#cs
UDF cfx.au3
serial functions using kernel32.dll
V1.0
Uwe Lahni 2008
V2.0
Andrew Calcutt 05/16/2009 - Started converting to UDF
V2.1
Mikko Keski-Heroja 02/23/2011 - UDF is now compatible with Opt("MustDeclareVars",1) and Date.au3. Global variable $dll is renamed to $commDll.
V2.2
Veronesi 04/26/2011 - Changed some cosmetics and documentation / Add Function to set RTS and to get DCD Status
#ce
#include-once
Global $commDll
Global $hSerialPort
Global $dcb_Struct
Global $commtimeout
Global $commtimeout_Struct
Global $commState
;====================================================================================
; Function Name: _OpenCOMPort($CommPort, $CommBaud, $CommBits, $CommParity, $CommStop, $SetRTS)
; Описание: Открытие последовательного порта
; Параметры: $CommPort
; $CommBits - 4-8
; $CommParity - 0=none, 1=odd, 2=even, 3=mark, 4=space
; $CommStop - 0 => 1 Stop bit / 1 => 1.5 Stop bits / 2 => 2 Stop bits
; $SetRTS - 0 = RTS => 0 / 1 = RTS => 1 / 2 = RTS handshake / 3 = RTS toggle
; Returns: В случае успеха возвращает идентификатор серийного порта
; В случае неудачи возвращает - 1 и устанавливает @error в 1
; Note:
;====================================================================================
Func _OpenCOMPort($CommPort, $CommBaud = '9600', $CommBits = '8', $CommParity = '0', $CommStop = '0', $SetRTS = 0)
#cs
CommCtrl => fBitfields => http://msdn.microsoft.com/en-us/library/aa363214(v=vs.85).aspx
http://www.hpcc.ecs.soton.ac.uk/software/Win32API.Txt
' The fourteen actual DCB bit-sized data fields within the four bytes of fBitFields can be manipulated by bitwise logical And/Or operations.
' FieldName Bit # Description
' ----------------- ----- ------------------------------
' fBinary 1 binary mode, no EOF check
' fParity 2 enable parity checking
' fOutxCtsFlow 3 CTS output flow control
' fOutxDsrFlow 4 DSR output flow control
' fDtrControl 5 DTR flow control type (2 bits)
' fDsrSensitivity 7 DSR sensitivity
' fTXContinueOnXoff 8 XOFF continues Tx
' fOutX 9 XON/XOFF out flow control
' fInX 10 XON/XOFF in flow control
' fErrorChar 11 enable error replacement
' fNull 12 enable null stripping
' fRtsControl 13 RTS flow control (2 bits)
' fAbortOnError 15 abort reads/writes on error
' fDummy2 16 reserved
#ce
Local Const $RTS_CONTROL_DISABLE = 0x0000
Local Const $RTS_CONTROL_ENABLE = 0x1000
Local Const $RTS_CONTROL_HANDSHAKE = 0x2000
Local Const $RTS_CONTROL_TOGGLE = 0x3000
Local $CommCtrl
$commDll = DllOpen("kernel32.dll")
Local $dcbs = "long DCBlength;long BaudRate; long fBitFields;short wReserved;" & _
"short XonLim;short XoffLim;byte Bytesize;byte parity;byte StopBits;byte XonChar; byte XoffChar;" & _
"Byte ErrorChar;Byte EofChar;Byte EvtChar;short wReserved1"
Local $commtimeouts = "long ReadIntervalTimeout;long ReadTotalTimeoutMultiplier;" & _
"long ReadTotalTimeoutConstant;long WriteTotalTimeoutMultiplier;long WriteTotalTimeoutConstant"
Local Const $GENERIC_READ_WRITE = 0xC0000000
Local Const $OPEN_EXISTING = 3
Local Const $FILE_ATTRIBUTE_NORMAL = 0x80
$dcb_Struct = DllStructCreate($dcbs)
If @error Then Return SetError(1, 1, -1)
$commtimeout_Struct = DllStructCreate($commtimeouts)
If @error Then Return SetError(1, 1, -1)
$hSerialPort = DllCall($commDll, "hwnd", "CreateFile", "str", "COM" & $CommPort, _
"int", $GENERIC_READ_WRITE, _
"int", 0, _
"ptr", 0, _
"int", $OPEN_EXISTING, _
"int", $FILE_ATTRIBUTE_NORMAL, _
"int", 0)
If @error Then Return SetError(1, 1, -1)
If Number($hSerialPort[0]) < 1 Then Return SetError(1, 1, -1)
$commState = DllCall($commDll, "long", "GetCommState", "hwnd", $hSerialPort[0], "ptr", DllStructGetPtr($dcb_Struct))
$CommCtrl = BitAND($CommCtrl, 0xFFFCFFF) ; RTS-Bits loschen
Switch $SetRTS
Case 0
Case 1
$CommCtrl = BitOR($CommCtrl, $RTS_CONTROL_ENABLE)
Case 2
$CommCtrl = BitOR($CommCtrl, $RTS_CONTROL_HANDSHAKE)
Case 3
$CommCtrl = BitOR($CommCtrl, $RTS_CONTROL_TOGGLE)
Case Else
Return SetError(1, 1, -1)
EndSwitch
If @error Then Return SetError(1, 1, -1)
DllStructSetData($dcb_Struct, "DCBLength", DllStructGetSize($dcb_Struct))
If @error Then Return SetError(1, 1, -1)
DllStructSetData($dcb_Struct, "BaudRate", $CommBaud)
If @error Then Return SetError(1, 1, -1)
DllStructSetData($dcb_Struct, "Bytesize", $CommBits)
If @error Then Return SetError(1, 1, -1)
DllStructSetData($dcb_Struct, "fBitfields", Number($CommCtrl))
If @error Then Return SetError(1, 1, -1)
DllStructSetData($dcb_Struct, "Parity", $CommParity)
If @error Then Return SetError(1, 1, -1)
DllStructSetData($dcb_Struct, "StopBits", '0x' & $CommStop)
If @error Then Return SetError(1, 1, -1)
DllStructSetData($dcb_Struct, "XonLim", 2048)
If @error Then Return SetError(1, 1, -1)
DllStructSetData($dcb_Struct, "XoffLim", 512)
If @error Then Return SetError(1, 1, -1)
$commState = DllCall($commDll, "short", "SetCommState", "hwnd", $hSerialPort[0], "ptr", DllStructGetPtr($dcb_Struct))
If @error Then Return SetError(1, 1, -1)
If $commState[0] = 0 Then Return SetError(1, 1, -1)
DllStructSetData($commtimeout_Struct, "ReadIntervalTimeout", -1)
$commtimeout = DllCall($commDll, "long", "SetCommTimeouts", "hwnd", $hSerialPort[0], "ptr", DllStructGetPtr($commtimeout_Struct))
If @error Then Return SetError(1, 1, -1)
Return Number($hSerialPort[0])
EndFunc ;==>_OpenCOMPort
;====================================================================================
; Function Name: _CloseCOMPort($CommSerialPort)
; Description: Closes serial port
; Parameters: $CommSerialPort - value returned by _OpenComm
; Returns: on success, returns 1
; on failure returns -1 and sets @error to 1
; Note:
;====================================================================================
Func _CloseCOMPort($CommSerialPort)
Local $closeerr = DllCall($commDll, "int", "CloseHandle", "hwnd", $CommSerialPort)
DllClose($commDll)
If @error Then Return SetError(1, 1, -1)
Return ($closeerr[0])
EndFunc ;==>_CloseCOMPort
;====================================================================================
; Function Name: _SendSerialString($CommSerialPort, $sSensString)
; Description: Send a String
; Parameters: $CommSerialPort - value returned by _OpenComm
; $sSendString - String to send
; Returns: on success, returns 1
; on failure returns -1 and sets @error to 1
; Note:
;====================================================================================
Func _SendSerialString($CommSerialPort, $sSendString)
Local $lptr0 = DllStructCreate("long_ptr")
DllCall($commDll, "int", "WriteFile", "hwnd", $CommSerialPort, _
"str", $sSendString, _
"int", StringLen($sSendString), _
"long_ptr", DllStructGetPtr($lptr0), _
"ptr", 0)
If @error Then Return SetError(1, 1, -1)
EndFunc ;==>_SendSerialString
;====================================================================================
; Function Name: _ReceiveStringWait($CommSerialPort, $MinBufferSize, $MaxWaitTime)
; Description: Recieves data
; Parameters: $CommSerialPort - value returned by _OpenComm
; $MinBufferSize - Buffer size to wait for
; $MaxWaitTime - Maximum time to wait before failing
; Returns: on success, returns String
; on failure returns -1 and sets @error to 1
; Note:
;====================================================================================
Func _ReceiveStringWait($CommSerialPort, $MinBufferSize, $MaxWaitTime)
Local $rxbuf
Local $jetza = TimerInit()
Local $lptr0 = DllStructCreate("long_ptr")
Local $rxr, $rxl, $to
Do
$rxr = DllCall($commDll, "int", "ReadFile", "hwnd", $CommSerialPort, _
"str", " ", _
"int", 1, _
"long_ptr", DllStructGetPtr($lptr0), _
"ptr", 0)
If @error Then Return SetError(1, 1, -1)
$rxl = DllStructGetData($lptr0, 1)
If $rxl >= 1 Then
$rxbuf &= $rxr[2]
EndIf
$to = TimerDiff($jetza)
Until StringLen($rxbuf) >= $MinBufferSize Or $to > $MaxWaitTime
Return ($rxbuf)
EndFunc ;==>_ReceiveStringWait
;====================================================================================
; Function Name: _SetCOMRTS($commPort, $RTS)
; Description: Sets RTS flow control
; Parameters: $CommPort - value returned by _OpenComm
; $RTS : 0 = disable, 1 = enable
; Returns: on success, returns 1
; on failure returns -1 and sets @error to 1
; Note:
;====================================================================================
Func _SetCOMRTS($CommPort, $SetRTS)
;http://msdn.microsoft.com/en-us/library/aa363254(v=vs.85).aspx
Local $EscapeComm, $RTS
If Number($CommPort) < 1 Then Return SetError(1, 1, -1)
Switch $SetRTS
Case 0
$RTS = 4
Case 1
$RTS = 3
Case Else
Return SetError(1, 1, -1)
EndSwitch
$EscapeComm = DllCall($CommDll, "BOOL", "EscapeCommFunction", "HWND", $CommPort, "DWORD", $RTS)
If @error Or ($EscapeComm[0] = 0) Then Return SetError(1, 1, -1)
Return True
EndFunc ;==>_SetCOMRTS
;====================================================================================
; Function Name: _GetCOMDCD($commPort)
; Description: Gets DCD status (Set from RTS in 0-Modem Cable)
; Parameters: $CommPort - value returned by _OpenComm
; Returns: on success, returns value
; on failure returns -1 and sets @error to 1
; Note:
;====================================================================================
Func _GetCOMDCD($CommPort)
; http://msdn.microsoft.com/en-us/library/aa363258(v=vs.85).aspx
Local $CommCtrl, $lpModemStat
If Number($CommPort) < 1 Then Return SetError(1, 1, -1)
$lpModemStat = DllStructCreate("DWORD")
$CommState = DllCall($CommDll, "BOOL", "GetCommModemStatus", "HWND", $CommPort, "Ptr", DllStructGetPtr($lpModemStat))
If @error Or ($CommState[0] = 0) Then Return SetError(1, 1, -1)
$CommCtrl = DllStructGetData($lpModemStat, 1)
If BitAND($CommCtrl, 0x80) Then Return 1 ; Isolate DCD (RLSD)
Return 0
EndFunc ;==>_GetCOMDCD
;====================================================================================
; Function Name: _GetCOMCTS($commPort)
; Description: Gets CTS status
; Parameters: $CommPort - value returned by _OpenComm
; Returns: on success, returns value
; on failure returns -1 and sets @error to 1
; Note:
;====================================================================================
Func _GetCOMCTS($CommPort)
; http://msdn.microsoft.com/en-us/library/aa363258(v=vs.85).aspx
Local $CommCtrl, $lpModemStat
If Number($CommPort) < 1 Then Return SetError(1, 1, -1)
$lpModemStat = DllStructCreate("DWORD")
$CommState = DllCall($CommDll, "BOOL", "GetCommModemStatus", "HWND", $CommPort, "Ptr", DllStructGetPtr($lpModemStat))
If @error Or ($CommState[0] = 0) Then Return SetError(1, 1, -1)
$CommCtrl = DllStructGetData($lpModemStat, 1)
If BitAND($CommCtrl, 0x10) Then Return 1 ; Isolate CTS
Return 0
EndFunc ;==>_GetCOMCTS