Как получить данные с com-порта?

Обсуждение программ nnCron и nnCron LITE

Re: Как получить данные с com-порта?

Postby Ilya » Tue, 22 Sep 2009, 23:26

Halfer wrote:.. хотя бывают случаи, когда считанный ШК передаётся только частично. связано это, полагаю, с тайм-аутом ожидания :-( если бы все ШК имели длину 13 симовлов + 2 символа префикс и суффикс (стандарт EAN-13), то можно было бы проверять длину строки. Но бывают такие ШК, у которых не 13 символов, а меньше, например EAN-8, или UC - у них длин ШК другая и проверить корректность считывания такого ШК, наверное, не представляется возможным.

Возможно всё! :)
Попробуй прочитать не 15 байт, а допустим 20...30 и выведи полученные данные в лог
Code: Select all
Buf1 20 DUMP
.
Если верить логике и форумам, то в дампе ты должен увидеть 0x0D.
Тогда всё будет просто.
Ilya
 
Posts: 445
Joined: Mon, 07 Aug 2006, 09:51
Location: Санкт-Петербург

Re: Как получить данные с com-порта?

Postby Halfer » Wed, 23 Sep 2009, 04:36

Вообще, я подключил код, расположенный на первой странице, как плагин COM_read_write.spf, изменив в нём только название слова main. Вчера всё работало, потом заметил, что код несколько модернизировался и я обновил его. Запустил крон, он ругнулся на обновлённый плагин, типа не могу загрузить, сказал его название и в конце дописал циферку 75 через двоеточие. Не могу понять, что там такого поменяли? Старого кода нет :-(

З.Ы. упс, прошу прощения, затупил, кусочек от старого кода остался всёже :-)
Halfer
 
Posts: 395
Joined: Wed, 09 May 2007, 13:23

Re: Как получить данные с com-порта?

Postby Halfer » Wed, 23 Sep 2009, 05:25

Ilya wrote:Попробуй прочитать не 15 байт, а допустим 20...30 и выведи полученные данные в лог
Code: Select all
Buf1 20 DUMP

это куда писать? просто в конце слова дописать и вывести в лог? Я пробовал вывести в сообщение, нифига не получилось.
Halfer
 
Posts: 395
Joined: Wed, 09 May 2007, 13:23

Re: Как получить данные с com-порта?

Postby Halfer » Wed, 23 Sep 2009, 05:55

И вообще, после обновления я не могу понять логики работы кода. Зацикливание слова COM_read ничего не даст. Если сканер данные не передал, то происходит выход из слова и, далее, задача прерывается. А мне нужно постоянно слушать порт, даже если там нет нифига. Верните старый код, я хоть понимал, что там происходит, в обновлённом нифига не понятно сталою.
Halfer
 
Posts: 395
Joined: Wed, 09 May 2007, 13:23

Re: Как получить данные с com-порта?

Postby Wyz » Wed, 23 Sep 2009, 06:16

Halfer wrote:Вообще, я подключил код, расположенный на первой странице, как плагин COM_read_write.spf, изменив в нём только название слова main.

В его первых строчках рекомендован более другой способ применения ;-)
Когда из-за моих ошибок порт оказывался недоступен при последующих вызовах (хэндл-то не закрывается), я вместо перезапуска основного процесса решил запускать так.

Не могу понять, что там такого поменяли?

Хе-хе! >:-> Бэкапь работающие решения!
Было:
Code: Select all
DUP Buf1 + 0 SWAP C! Buf1 ASCIIZ> MsgBox DROP

Стало:
Code: Select all
( DUP ) Buf1 + 0 SWAP C! Buf1 ASCIIZ> MsgBox ( DROP )


это куда писать? просто в конце слова дописать и вывести в лог? Я пробовал вывести в сообщение, нифига не получилось.

После вызова COM_read или в конец этого слова. Выводит в nncron.out или на консоль.

Зацикливание слова COM_read ничего не даст. Если сканер данные не передал, то происходит выход из слова и, далее, задача прерывается. А мне нужно постоянно слушать порт, даже если там нет нифига.

Ну типа зацикливай не само слово, а его вызов. Когда что-нить прочитает, оно вернет не 0. А для понимания настрой логирование отдельным словом, в котором проверяй флаг - писать лог или нет.

Кстати, насчет потерь: попробуй скорость понизить (замени 115200 на 2400).
Wyz
 
Posts: 389
Joined: Tue, 11 Dec 2007, 01:42

Re: Как получить данные с com-порта?

Postby Ilya » Wed, 23 Sep 2009, 18:46

Halfer wrote:
Ilya wrote:Попробуй прочитать не 15 байт, а допустим 20...30 и выведи полученные данные в лог
Code: Select all
Buf1 20 DUMP

это куда писать? просто в конце слова дописать и вывести в лог? Я пробовал вывести в сообщение, нифига не получилось.
Ilya
 
Posts: 445
Joined: Mon, 07 Aug 2006, 09:51
Location: Санкт-Петербург

Re: Как получить данные с com-порта?

Postby Halfer » Thu, 24 Sep 2009, 06:30

Ilya wrote:Возможно всё! :)
Попробуй прочитать не 15 байт, а допустим 20...30 и выведи полученные данные в лог
Code: Select all
Buf1 20 DUMP
.
Если верить логике и форумам, то в дампе ты должен увидеть 0x0D.
Тогда всё будет просто.

Поставил 20 байт, считал ШК два раза, в nnCron.out написано:
Code: Select all
51D6D2   02 34 36 30  36 39 39 38  30 33 36 38  35 32 03 02 .4606998036852..
51D6E2   34 36 30 36  00 00 00 00  00 00 00 00  00 00 00 00 4606............
51D6D2   39 39 38 30  33 36 38 35  32 03 36 38  35 32 03 02 998036852.6852..
51D6E2   34 36 30 36  00 00 00 00  00 00 00 00  00 00 00 00 4606............
Halfer
 
Posts: 395
Joined: Wed, 09 May 2007, 13:23

Re: Как получить данные с com-порта?

Postby Ilya » Fri, 25 Sep 2009, 09:55

Halfer wrote:Поставил 20 байт, считал ШК два раза, в nnCron.out написано:
Code: Select all
51D6D2   02 34 36 30  36 39 39 38  30 33 36 38  35 32 03 02 .4606998036852..
51D6E2   34 36 30 36  00 00 00 00  00 00 00 00  00 00 00 00 4606............
51D6D2   39 39 38 30  33 36 38 35  32 03 36 38  35 32 03 02 998036852.6852..
51D6E2   34 36 30 36  00 00 00 00  00 00 00 00  00 00 00 00 4606............


Почитал я доку по твоему сканеру и вот что пришло на ум:
1) Поскольку много лет использую под SPF-ом либу winmodem.f, то и буду опираться на неё:
Code: Select all
\ winmodem.f -- interface with modem under Windows'95/98/etc.       06-jan-2003
\
\ <c> Aleksey Filutich, 2003     cactus@forth.org.ru

: DWORD CELL -- ;
: WORD1 2 -- ;

WINAPI: GetCommState        KERNEL32.DLL
WINAPI: SetCommState        KERNEL32.DLL
WINAPI: SetCommTimeouts     KERNEL32.DLL
WINAPI: GetCommTimeouts     KERNEL32.DLL
WINAPI: PurgeComm KERNEL32.DLL
WINAPI: EscapeCommFunction KERNEL32.DLL
WINAPI: GetCommModemStatus KERNEL32.DLL
WINAPI: ClearCommError KERNEL32.DLL
WINAPI: GetCommMask KERNEL32.DLL
WINAPI: SetCommMask KERNEL32.DLL
WINAPI: WaitCommEvent KERNEL32.DLL
WINAPI: SetCommBreak KERNEL32.DLL
WINAPI: ClearCommBreak  KERNEL32.DLL
WINAPI: CommConfigDialogA  KERNEL32.DLL
WINAPI: GetCommProperties  KERNEL32.DLL
WINAPI: BuildCommDCBA  KERNEL32.DLL
WINAPI: TransmitCommChar KERNEL32.DLL

10 1024 * CONSTANT rcvBufSize   \ Размер буфера приёма

0 VALUE esc-buf
0 VALUE rcv-buf      \ Указатель на буфер приёма
0 VALUE com-handle   \ Хэндл открытого COM порта
0 VALUE cbr            \ Кол-во принятых байт
0 VALUE cbs            \ Кол-во передаваемых байт
0 VALUE st
0 VALUE sz
0 VALUE fltmGet
0 VALUE spid
VARIABLE SIG
VARIABLE SIGerr
VARIABLE com_event      \ Код события COM порта
VARIABLE com_error      \ Код события COM порта

VARIABLE ComWasRead
VARIABLE ComReadBuffer

\ VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
\ Структура COMMTIMEOUTS
\ VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
0
4 -- ReadIntervalTimeout            \ Maximum time between read chars
4 -- ReadTotalTimeoutMultiplier     \ Multiplier of characters
4 -- ReadTotalTimeoutConstant       \ Constant in milliseconds
4 -- WriteTotalTimeoutMultiplier    \ Multiplier of characters
4 -- WriteTotalTimeoutConstant      \ Constant in milliseconds
CONSTANT /COMMTIMEOUTS

\ VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
\ Структура DCB
\ VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
0
4 -- DCBlength                   \ sizeof/DCB/ == 28 bytes
4 -- BaudRate                    \ Baudrate at which running
4 -- fBitField                   \ bit fields
\ -- fBinary             1           \ Binary Mode /skip EOF check/
\ -- fParity             1           \ Enable parity checking
\ -- fOutxCtsFlow        1           \ CTS handshaking on output
\ -- fOutxDsrFlow        1           \ DSR handshaking on output
\ -- fDtrControl         2           \ DTR Flow control
\ -- fDsrSensitivity     1           \ DSR Sensitivity
\ -- fTXContinueOnXoff   1           \ Continue TX when Xoff sent
\ -- fOutX               1           \ Enable output X-ON/X-OFF
\ -- fInX                1           \ Enable input X-ON/X-OFF
\ -- fErrorChar          1           \ Enable Err Replacement
\ -- fNull               1           \ Enable Null stripping
\ -- fRtsControl         2           \ Rts Flow control
\ -- fAbortOnError       1           \ Abort all reads and writes on Error
\ -- fDummy2            17           \ Reserved
2 -- wReserved                   \ Not currently used
2 -- XonLim                      \ Transmit X-ON threshold
2 -- XoffLim                     \ Transmit X-OFF threshold
1 -- ByteSize                    \ Number of bits/byte, 4-8
1 -- Parity                      \ 0-4=None,Odd,Even,Mark,Space
1 -- StopBits                    \ 0,1,2 = 1, 1.5, 2
1 -- XonChar                     \ Tx and Rx X-ON character
1 -- XoffChar                    \ Tx and Rx X-OFF character
1 -- ErrorChar                   \ Error replacement char
1 -- EofChar                     \ End of Input character
1 -- EvtChar                     \ Received Event character
2 -- wReserved1                  \ Fill for now
CONSTANT /DCB

\ VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
\ Структура OVERLAPPED
\ VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
0
CELL -- Internal
CELL -- InternalHigh
CELL -- Offset
CELL -- OffsetHigh
CELL -- hEvent
CONSTANT OVELAPPED
\ HERE DUP >R OVELAPPED DUP ALLOT ERASE VALUE overlap
CREATE overlap OVELAPPED ALLOT

\ VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
\ Структура LPCOMSTAT
\ VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
   0
   CELL -- fBinState
    DWORD fCtsHold   \ : 1;   // Tx waiting for CTS signal
    DWORD fDsrHold   \ : 1;   // Tx waiting for DSR signal
    DWORD fRlsdHold  \ : 1;  // Tx waiting for RLSD signal
    DWORD fXoffHold  \ : 1;  // Tx waiting, XOFF char rec'd
    DWORD fXoffSent  \ : 1;  // Tx waiting, XOFF char sent
    DWORD fEof      \ : 1;       // EOF character sent
    DWORD fTxim     \ : 1;      // character waiting for Tx
   25 CELLS -- fReserved \ : 25; // reserved
   DWORD cbInQue \ ;        // bytes in input buffer
   DWORD cbOutQue \ ;       // bytes in output buffer
   CONSTANT LPCOMSTAT_SIZE
CREATE LPCOMSTAT LPCOMSTAT_SIZE CELLS ALLOT

REQUIRE {             ~ac\lib\locals.f


( baud   - 300, 600, .. 57600
  data   - 4 .. 8
  parity - 0-4 = None,Odd,Even,Mark,Space
  stop   - 0,1,2 = 1, 1.5, 2 stop bits
  handle - хэндл открытого порта
)

: SetModemParameters ( baud data parity stop mode handle -- ior )
   { baud data parity stop  handle \ dcb }
   /DCB ALLOCATE THROW -> dcb
   dcb handle GetCommState DROP
   \ 0x80000000 dcb fBitField !
   baud   dcb BaudRate !
   data   dcb ByteSize C!
   parity dcb Parity   C!
   stop   dcb StopBits C!
   \ mode   dcb fBitField !
   dcb handle SetCommState -1 = IF GetLastError ELSE 0 THEN
   dcb FREE THROW
;

: GetModemParameters ( handle -- baud data parity stop ior )
   { handle \ dcb baud data parity stop mode ior }
   /DCB ALLOCATE THROW -> dcb
   dcb handle GetCommState -1 = IF GetLastError ELSE 0 THEN -> ior
   dcb BaudRate @ -> baud
   dcb ByteSize C@ -> data
   dcb Parity   C@ -> parity
   dcb StopBits C@ -> stop
   dcb fBitField @ -> mode
   dcb FREE THROW
   baud data parity stop mode ior
;

: SetComPortParameters
{ adr handle \ dcb -- }
/DCB ALLOCATE THROW -> dcb
dcb handle GetCommState DROP
dcb adr BuildCommDCBA DROP
dcb handle SetCommState -1 = IF GetLastError ELSE 0 THEN
dcb FREE THROW
;

( set port timeout )

: SetTimeOut ( t handle -- ior )
   { t handle \ timeout ior }
   /COMMTIMEOUTS ALLOCATE THROW -> timeout
   0 timeout ReadIntervalTimeout !
   t timeout ReadTotalTimeoutMultiplier !
   1 timeout ReadTotalTimeoutConstant !
   t timeout WriteTotalTimeoutMultiplier !
   1 timeout WriteTotalTimeoutConstant !
   timeout handle SetCommTimeouts  -1 = IF GetLastError ELSE 0 THEN -> ior
   timeout FREE THROW
   ior
;

: CLEARCOMMERROR LPCOMSTAT com_error com-handle ClearCommError  DROP ;

: CommConfigDialog CommConfigDialogA

;

\EOF
REQUIRE STR@          \devel\~ac\lib\str.f
: TEST { \ handle }
   S" COM3" R/W OPEN-FILE THROW -> handle
   57600 8 0 0 handle SetModemParameters THROW
   100 handle SetTimeOut THROW
   handle GetModemParameters THROW . . . . CR
   " ATI5{CRLF}" STR@ handle WRITE-FILE THROW
   1500 PAUSE
HERE 200 handle READ-FILE CR HERE 100 DUMP

   handle CLOSE-FILE THROW
;

TEST

2) Исходные установки у сканера следующие: 9600,SPACE,2,7 , т.е.
Code: Select all
 S" COM3" R/W OPEN-FILE THROW -> handle
   9600 7 4 2 handle SetModemParameters THROW
   100 handle SetTimeOut THROW

3) Обрамление кадра данных: 0x02 - начало кадра, 0x03 - конец кадра, т.е.
Code: Select all
HERE DUP 15 handle READ-FILE THROW \ Читаем данные из сканера - на выходе указатель на буфер данных и кол-во полученных байт

4) Закрываем порт
Code: Select all
 handle CLOSE-FILE THROW

5) Если читаешь данные под nnCron-ом, то либо в задаче не забыть указать SingleInstance, либо запустить цикл чтения отдельным потоком.

Кста, а какое практическое применение данной задачи?
Ilya
 
Posts: 445
Joined: Mon, 07 Aug 2006, 09:51
Location: Санкт-Петербург

Re: Как получить данные с com-порта?

Postby AlikasS » Fri, 25 Sep 2009, 15:57

Ilya wrote:Кста, а какое практическое применение данной задачи?

конечное сгенерировать прогу.exe
которая при сканировании ШК через сканер
по коду ишет в базе (любой) др.инфу, ну и отображает ее для пользователя.
P.S. кстати интересует, насколько сгенерированные в кроне exe
попадают под действие лицензии?
(при условии изменении свойств конечного файла RESOURCES: ....)
User avatar
AlikasS
 
Posts: 1437
Joined: Wed, 28 Jun 2006, 05:39
Location: Khabarovsk

Re: Как получить данные с com-порта?

Postby Ilya » Fri, 25 Sep 2009, 18:51

AlikasS wrote:
Ilya wrote:Кста, а какое практическое применение данной задачи?

конечное сгенерировать прогу.exe
которая при сканировании ШК через сканер
по коду ишет в базе (любой) др.инфу, ну и отображает ее для пользователя.
P.S. кстати интересует, насколько сгенерированные в кроне exe
попадают под действие лицензии?
(при условии изменении свойств конечного файла RESOURCES: ....)


Откомпилить можно и на "голом" SPF-е (вся мощь nnCron-а для этого не потребна).
"...базе (любой) ..." - через ODBC !?
Мог бы помочь безвозмездно, но для этого бы потребовался во временное пользование сам сканер + образчик базы в Питере!
Ilya
 
Posts: 445
Joined: Mon, 07 Aug 2006, 09:51
Location: Санкт-Петербург

Re: Как получить данные с com-порта?

Postby Halfer » Tue, 29 Sep 2009, 04:34

Илья, покажи, плиз, примерчик задачи, которая читает данные ком-порта. Что-то я не могу разобраться :-(
Halfer
 
Posts: 395
Joined: Wed, 09 May 2007, 13:23

Re: Как получить данные с com-порта?

Postby Ilya » Tue, 29 Sep 2009, 07:33

Halfer wrote:Илья, покажи, плиз, примерчик задачи, которая читает данные ком-порта. Что-то я не могу разобраться :-(


Code: Select all
#( read-com-data
0 VALUE handle
NoActive
Action:
S" COM1" R/W OPEN-FILE THROW -> handle  \ Открыли порт
   9600 7 4 2 handle SetModemParameters THROW
   100 handle SetTimeOut THROW
HERE DUP 15 handle READ-FILE THROW \ Читаем данные из сканера - на выходе указатель на буфер данных и кол-во полученных байт
CR DUMP   \ Вывели данные в nncon.out
handle CLOSE-FILE THROW  \ Закрыли порт
Ilya
 
Posts: 445
Joined: Mon, 07 Aug 2006, 09:51
Location: Санкт-Петербург

Re: Как получить данные с com-порта?

Postby Halfer » Tue, 29 Sep 2009, 07:38

Ilya wrote:
Code: Select all
#( read-com-data
0 VALUE handle
NoActive
Action:
S" COM1" R/W OPEN-FILE THROW -> handle  \ Открыли порт
   9600 7 4 2 handle SetModemParameters THROW
   100 handle SetTimeOut THROW
HERE DUP 15 handle READ-FILE THROW \ Читаем данные из сканера - на выходе указатель на буфер данных и кол-во полученных байт
CR DUMP   \ Вывели данные в nncon.out
handle CLOSE-FILE THROW  \ Закрыли порт

на пятой строке синтаксическая ошибка в кронтабе. либу winmodem.f подключил как плагин, прально?
Halfer
 
Posts: 395
Joined: Wed, 09 May 2007, 13:23

Re: Как получить данные с com-порта?

Postby Ilya » Tue, 29 Sep 2009, 08:01

Halfer wrote:
Ilya wrote:
Code: Select all
#( read-com-data
0 VALUE handle
NoActive
Action:
S" COM1" R/W OPEN-FILE THROW -> handle  \ Открыли порт
   9600 7 4 2 handle SetModemParameters THROW
   100 handle SetTimeOut THROW
HERE DUP 15 handle READ-FILE THROW \ Читаем данные из сканера - на выходе указатель на буфер данных и кол-во полученных байт
CR DUMP   \ Вывели данные в nncon.out
handle CLOSE-FILE THROW  \ Закрыли порт

на пятой строке синтаксическая ошибка в кронтабе. либу winmodem.f подключил как плагин, прально?

Замени S" COM1" R/W OPEN-FILE THROW -> handle \ Открыли порт на S" COM1" R/W OPEN-FILE THROW TO handle \ Открыли порт
Ilya
 
Posts: 445
Joined: Mon, 07 Aug 2006, 09:51
Location: Санкт-Петербург

Re: Как получить данные с com-порта?

Postby Halfer » Tue, 29 Sep 2009, 08:41

В общем, подключил либу, зациклил задачу, при считывании ШК в дампе пишется, например:
Code: Select all
51EA32   00 00 00 78  00 00 78 00  00 00 78 00  7E 00 78 00 ...x..x...x.~.x.

51EA32   00 00 00 78  00 00 78 00  00 00 78 00  7E 00 78 00 ...x..x...x.~.x.

как это теперь вывести через сообщение? пробовал так
Code: Select all
HERE DUP 15 handle READ-FILE THROW MsgBox

выводится пустая строка.
Halfer
 
Posts: 395
Joined: Wed, 09 May 2007, 13:23

PreviousNext

Return to nnCron forum (Russian)

Who is online

Users browsing this forum: No registered users and 2 guests