COM-Port by Vertex
BlitzPlus Forums/BlitzPlus Programming/COM-Port by Vertex
| ||
| I need to control an instrument through the com port. If I first set the com port to 9600,N,8,1 with Hyperterminal Vertex's code from the code archives works with the instrument. The problem seems to be that code below (a boiled down version of Vertex's original) doesn't actually change the Com port settings. Any suggestions to fix or a alternative to change the com port settings from Blitzplus? driverHandle = apiCreateFile("COM1", $80000000 Or $40000000 , 0, 0, 3, 0, 0) If driverHandle = -1 Then Stop apiSetupComm(driverHandle, 1024, 1024) dcb = CreateBank(28) PokeInt dcb, 00, 28 ; sizeof(DCB) PokeInt dcb, 04, 9600 ; baud rate ;val = 1 ; ;Binary Mode (skip Eof check) ;val = val Or 2 ;Enable parity checking ;val = val Or 48 ; DTR Flow control on ;PokeByte dcb, 08, val PokeByte dcb, 08, 0 ;no parity PokeByte dcb, 09, 0 ;16 RTS_CONTROL=48 PokeByte dcb, 18, 8 ; number of bits/byte, 4-8 PokeByte dcb, 19, 0 ; 0-4=no, odd, even, mark, space PokeByte dcb, 20, 1 ; 0,1,2 = 1, 1.5, 2 apiSetCommState(driverHandle, dcb) apiSetCommMask(driverHandle, EV_TXEMPTY) ; Get the Comm state For i=0 To 27 PokeByte dcb,i,0 Next PokeInt dcb, 0, 28 ; sizeof(DCB) ;Get the Comm state apiGetCommState(driverHandle,dcb) mx$= "handle = "+driverhandle +Chr$(13) mx$=mx$+ "Baudrate " +PeekInt(dcb,4) +Chr$(13) mx$=mx$+ "Databits " +PeekByte(dcb,18) +Chr$(13) mx$=mx$+ "Parity " +PeekByte(dcb,19) +Chr$(13) mx$=mx$+ "Stopbits " +PeekByte(dcb,20) +Chr$(13) Notify mx$ apiCloseHandle(driverHandle) |
| ||
| If you read furthur down the archive entry, you will see that Vertex's code isn't all correct. "What is going on? The offsets for the DCB at offset 8 are bits not DWORDS." Function openComport(comport, baudRate)
Local dcbBaudRate, driverHandle, dcb
If comport > 255 Or comport < 0 Then
Return INVALID_HANDLE_VALUE
EndIf
Select baudRate
Case 110
dcbBaudRate = CBR_110
Case 300
dcbBaudRate = CBR_300
Case 600
dcbBaudRate = CBR_600
Case 1200
dcbBaudRate = CBR_1200
Case 2400
dcbBaudRate = CBR_2400
Case 4800
dcbBaudRate = CBR_4800
Case 9600
dcbBaudRate = CBR_9600
Case 14400
dcbBaudRate = CBR_14400
Case 19200
dcbBaudRate = CBR_19200
Case 38400
dcbBaudRate = CBR_38400
Case 56000
dcbBaudRate = CBR_56000
Case 57600
dcbBaudRate = CBR_57600
Case 115200
dcbBaudRate = CBR_115200
Default
Return INVALID_HANDLE_VALUE
End Select
driverHandle = apiCreateFile("COM"+comport, GENERIC_READ Or GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0)
If driverHandle = INVALID_HANDLE_VALUE Then
Return INVALID_HANDLE_VALUE
Else
apiSetupComm(driverHandle, 1024, 1024)
dcb = CreateBank(28)
PokeInt dcb, 00, 28 ; sizeof(DCB)
PokeInt dcb, 04, dcbBaudRate ; current baud rate
val = 1 ; Binary Mode (skip Eof check)
If parityEnable = True Then val = val Or 2 ; Enable parity checking
If protocol = DTR_CONTROL Then val = val Or 48 ; DTR Flow control on
PokeByte dcb, 08, val
val = 0
If protocol = RTS_CONTROL Then val = val Or 48
PokeByte dcb, 09, val
PokeByte dcb, 18, dataBits ; number of bits/byte, 4-8
PokeByte dcb, 19, parityBit ; 0-4=no, odd, even, mark, space
PokeByte dcb, 20, stopBits ; 0,1,2 = 1, 1.5, 2
apiSetCommState(driverHandle, dcb)
apiSetCommMask(driverHandle, EV_TXEMPTY)
EndIf
FreeBank dcb
Return driverHandle
End Function
After looking some more, it appears that you are already doing so. Any suggestions to fix or a alternative to change the com port settings from Blitzplus? The com settings DO change because I've used Vertexes code. I'm not sure what your code to return the com settings actually returns. |
| ||
| I have noticed that apiSetCommState returns 0 in my code but I haven't been able figure out why. If Not apiSetCommState(driverHandle, dcb) Then Notify "error setcomm state" |
| ||
Here is the exact code I am using that works:Function openComport(comport, baudRate)
Local dcbBaudRate, driverHandle, dcb
If comport > 255 Or comport < 0 Then
Return False
EndIf
Select baudRate
Case 110
dcbBaudRate = CBR_110
Case 300
dcbBaudRate = CBR_300
Case 600
dcbBaudRate = CBR_600
Case 1200
dcbBaudRate = CBR_1200
Case 2400
dcbBaudRate = CBR_2400
Case 4800
dcbBaudRate = CBR_4800
Case 9600
dcbBaudRate = CBR_9600
Case 14400
dcbBaudRate = CBR_14400
Case 19200
dcbBaudRate = CBR_19200
Case 38400
dcbBaudRate = CBR_38400
Case 56000
dcbBaudRate = CBR_56000
Case 57600
dcbBaudRate = CBR_57600
Case 115200
dcbBaudRate = CBR_115200
Default
Return False
End Select
driverHandle = apiCreateFile("COM"+comport, GENERIC_READ Or GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0)
If driverHandle = INVALID_HANDLE_VALUE Then
Return INVALID_HANDLE_VALUE
Else
apiSetupComm(driverHandle, 1024, 1024)
; dcb = CreateBank(80)
; PokeInt dcb, 00, 80 ; sizeof(DCB)
; PokeInt dcb, 04, dcbBaudRate ; current baud rate
; PokeInt dcb, 08, 1 ; binary mode, no EOF check
; If parityEnable = True Then
; PokeInt dcb, 12, 1 ; enable parity checking
; Else
; PokeInt dcb, 12, 0 ; disable parity checking
; EndIf
; If protocol = 0 Then
; PokeInt dcb, 24, DTR_CONTROL_ENABLE ; DTR flow control type
; Else
; PokeInt dcb, 24, DTR_CONTROL_DISABLE ; DTR flow control type
; EndIf
; PokeInt dcb, 28, False ; DSR sensitivity
; If protocol = 1 Then
; PokeInt dcb, 52, RTS_CONTROL_ENABLE ; RTS flow control
; Else
; PokeInt dcb, 52, RTS_CONTROL_DISABLE ; RTS flow control
; EndIf
; PokeInt dcb, 60, 17 ; reserved
; PokeByte dcb, 70, dataBits ; number of bits/byte, 4-8
; PokeByte dcb, 71, parityBit ; 0-4=no, odd, even, mark, space
; PokeByte dcb, 72, stopBits ; 0,1,2 = 1, 1.5, 2
dcb = CreateBank(28)
PokeInt dcb, 00, 28 ; sizeof(DCB)
PokeInt dcb, 04, dcbBaudRate ; current baud rate
val = 1 ; Binary Mode (skip Eof check)
If parityEnable = True Then val = val Or 2 ; Enable parity checking
If protocol = DTR_CONTROL Then val = val Or 48 ; DTR Flow control on
PokeByte dcb, 08, val
val = 0
If protocol = RTS_CONTROL Then val = val Or 48
PokeByte dcb, 09, val
PokeByte dcb, 18, dataBits ; number of bits/byte, 4-8
PokeByte dcb, 19, parityBit ; 0-4=no, odd, even, mark, space
PokeByte dcb, 20, stopBits ; 0,1,2 = 1, 1.5, 2
apiSetCommState(driverHandle, dcb)
apiSetCommMask(driverHandle, EV_TXEMPTY)
EndIf
FreeBank dcb
Return driverHandle
End Function
Function closeComport(driverHandle)
If driverHandle = INVALID_HANDLE_VALUE Or driverHandle = 0 Then
Return False
Else
Return apiCloseHandle(driverHandle)
EndIf
End Function
Function writeComport(driverHandle, numBytes, buffer)
Local state, temp
If driverHandle = INVALID_HANDLE_VALUE Or driverHandle = 0 Then
Return False
EndIf
apiEscapeCommFunction(driverHandle, SETRTS)
temp = CreateBank(4)
state = apiWriteFile(driverHandle, buffer, numBytes, temp, 0)
apiEscapeCommFunction(driverHandle, CLRRTS)
FreeBank temp
Return state
End Functionopen, close, and write all work for me. I also have this bit of code for reading, but I am not using it, so I don't know if it works: Function readComport(driverHandle, bytesRead, bufferSize, buffer, tOut)
Local comErrors, comStat
If driverHandle = INVALID_HANDLE_VALUE Or driverHandle = 0 Then
Return False
EndIf
PokeInt timeouts, 00, 0
PokeInt timeouts, 04, 0
PokeInt timeouts, 08, tOut
PokeInt timeouts, 12, 0
apiSetCommTimeouts(driverHandle, timeouts)
comErrors = CreateBank(4)
comStat = CreateBank(10)
apiClearCommError(driverHandle, comErrors, comStat)
apiReadFile(driverHandle, buffer, bufferSize, bytesRead, 0)
FreeBank comErrors
FreeBank comStat
Return True
End Function |
| ||
And, of course I am using these declarations in a COM-Port.decls file:.lib "Kernel32.dll" apiCreateFile%(lpFileName$, dwDesiredAccess, dwShareMode, lpSecurrityAttributes, dwCreationDistribution, dwFlagsAndAttributes, hTemplateFile) : "CreateFileA" apiSetupComm%(hFile, dwInQueue, dwOutQueue) : "SetupComm" apiGetCommState%(hFile, lpDCB*) : "GetCommState" apiSetCommState%(hFile, lpCDB*) : "SetCommState" apiSetCommMask%(hFile, dwEvtMask) : "SetCommMask" apiCloseHandle%(hObject) : "CloseHandle" apiEscapeCommFunction%(hFile, dwFunc) : "EscapeCommFunction" apiWriteFile%(hFile, lpBuffer*, nNumberOfBytesToWrite, lpNumberOfBytesWritten*, lpOverlapped) : "WriteFile" apiSetCommTimeouts%(hFile, lpCommTimeouts*) : "SetCommTimeouts" apiClearCommError%(hFile, lpErrors*, lpStat*) : "ClearCommError" apiReadFile%(hFile, lpBuffer*, nNumberOfBytesToRead, lpNumberOfBytesRead*, lpOverlapped) : "ReadFile" |
| ||
| Thanks Wolran, I tried your code, apiSetCommStatestill returns 0 but gets a drivehandle, Getcommstate indicates the settings don't change. I would try apiBuildCommDCB but I would need to construct a pointer to a string. I there a way to do this in BlitzPlus? |
| ||
| The problem is that SetCommState dosn't accept 9600,N,8,1 as valid comm settings, however 9600,N,8,0 works instead. |
| ||
| Very strange. I wonder why. |