Here is cattlerustlers serial plugin I used for quite a while for reading barcodes from a serial scanner. Then I found someone who (long time ago) wrote a pure DBP method of reading/writing serial port. I adapted that which seems to be more reliable for me. (I had problems with the dll when performing the first read from the serial port, but after that it works fine.)
You'll need to modify the dbp code for your own use because I'm only using it to read barcodes. Hopefully one or the other will be useful.
#constant _KERNEL32 1
#constant _FALSE 0
#constant _TRUE 1
#constant _TAB chr$(9)
load dll "\windows\system32\kernel32.dll", _KERNEL32
global hPort as dword
global SERIAL_CHUNK$ as string =""
global SCAN_BARCODE$ as string =""
hPort=Open_ComPort("COM1")
repeat
Check_SerialPort(hPort)
if SCAN_BARCODE$<>"" then print SCAN_BARCODE$
until returnkey()
result=call dll(_KERNEL32,"CloseHandle",hPort)
if result=0 then Msg("Error: Could not close com port handle",0)
wait key
end
function Open_ComPort(comport$)
local dcb_buf as dword
local tim_buf as dword
`GENERIC_READ=0x80000000 GENERIC_WRITE=0x40000000
`See http://msdn.microsoft.com/en-us/library/aa363858%28v=VS.85%29.aspx for parameter explanations
com_handle=call dll(_KERNEL32,"CreateFileA",comport$,0x80000000,0,0,3,0x80,0)
if com_handle=-1 then Msg("Error: Could not retrieve handle for COM port. (Port in use?)",0) : ExitFunction -1 `Exit with fail condition
`Build comm port parameters and apply them. See: http://msdn.microsoft.com/en-us/library/aa363143%28v=VS.85%29.aspx
dcb_buf=alloc zeroed(80) `Allocate memory to create DCB structure (com port parameters)
result=call dll(_KERNEL32,"BuildCommDCBA","baud=9600 parity=M data=8 stop=1 xon=off dtr=off rts=off",dcb_buf) `Build structure with selected options
if result=0 then Msg("Error: Could not build DCB.",0)
result=call dll(_KERNEL32,"SetCommState",com_handle,dcb_buf) `Apply new comm parameters
if result=0 then Msg("Error: Could not set Com port state",0)
free dcb_buf `Free dcb buffer memory back to system
`Set com port timeouts. See: http://msdn.microsoft.com/en-us/library/aa363190%28v=VS.85%29.aspx
tim_buf=alloc zeroed(20) `Allocate memory to create Timeout structure & fill standard values
poke dword tim_buf+0,4294967295 `ReadIntervalTimeout (Set to maxdword so returns immediately)
poke dword tim_buf+4,0 `ReadTotalTimeoutMultiplier (Set to 0 - return immediate)
poke dword tim_buf+8,0 `ReadTotalTimeOutConstant (Set to 0 - return immediate)
poke dword tim_buf+12,0 `WriteTotalTimeoutMultiplier
poke dword tim_buf+16,1000 `WriteTotalTimeoutConstant
result=call dll(_KERNEL32,"SetCommTimeouts",com_handle,tim_buf) `Apply new settings from timeouts structure
if result=0 then Msg("Error: Could not set Com Timeouts.",0)
free tim_buf `Free buffer memory back to system
endfunction com_handle
function Check_SerialPort(hFile as dword)
local char_buf as dword
SCAN_BARCODE$="" `Always blank global barcode string each loop
char_buf=alloc zeroed(4+255) `dword for returned num of characters read, 255 bytes max space for character data
result=call dll(_KERNEL32,"ReadFile",hfile,char_buf+4,255,char_buf,0) `Call readfile to get up to 255 characters from serial port
if result=0 then Msg("Error: Could not read from com port.",0)
if peek dword(char_buf)>0 `If returned some characters
SERIAL_CHUNK$=SERIAL_CHUNK$+peek string(char_buf+4,peek dword(char_buf)) `then add them to the serial chunk data
SERIAL_CHUNK$=trimleft$(SERIAL_CHUNK$,_TAB) `If 1st character is TAB then remove it (redundant)
tbpos=instr(SERIAL_CHUNK$,_TAB) `TAB character signals end of barcode transmission
if tbpos>0
SCAN_BARCODE$=left$(SERIAL_CHUNK$,tbpos-1) `Get all characters up to the tab stopmark
SERIAL_CHUNK$=remove$(SERIAL_CHUNK$,1,tbpos) `Keep any remainder of chunk after tabstop - start of next barcode
if len(SCAN_BARCODE$)=12 then SCAN_BARCODE$="0"+SCAN_BARCODE$ `If got a 12 digit (UPC) barcode and finished reading from serial then add leading 0 (EAN13)
endif
endif
free char_buf `Free serial character buffer
EndFunction
function Msg(err$,x)
`placeholder function for logging/error msgs
print err$ : wait key : end
endfunction