Что нового

Как открыть и закрыть COM порт.

A

at

Гость
Версия AutoIt: 3.3.6.1

Час Добрый Всем!

Описание: При нажатии на $Button1, на СОМ порту (на одном из его выводов) должна появится логическая единица ( +5 или 12 вольт ). При повторном нажатии на $Button1, СОМ порт закрывается ( на выходах логический 0 ).

Не смог найти ничего по COM портам, ни на форуме, ни в справке. Подскажите, кто знает хотя бы направление, где искать по этой теме.
 

WSWR

AutoIT Гуру
Сообщения
941
Репутация
363
Не оно? :whistle:
http://autoit-script.ru/index.php/topic,6963.msg48108.html
http://www.autoitscript.com/forum/topic/128546-serial-port-com-port-udf/
 
Автор
A

at

Гость
Чем больше вникаю в суть, тем больше становиться не понятно, можно ли вообще реализовать эту задачу с помощью Autoit? Еще сильно смущает факт отсутствия тем связанных с COM портами на форуме. То, что находится поиском, в основном не раскрытые до конца вопросы.
 

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
Когда я работал с COM портом, то использовал
Код:
activex MSCOMM32.OCX

Для работы с ним, создавал объект
Код:
ObjCreate("MSCOMMLib.MsComm.1")

и использовал готовые методы, свойства. Плюс есть поддержка событий.
Так что можно написать приложение не опрашивающее порт постоянно, а слушающее приходящие события.
 
Автор
A

at

Гость
Насколько я понял из прочитанного, MSCOMM32.OCX не бесплатна. Может есть еще варианты?
 

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
Есть аналог - NETComm.ocx, похоже на полный клон MSCOMM32.OCX, с кое какими отличиями, точно не помню.
 

C2H5OH

AutoIT Гуру
Сообщения
1,473
Репутация
333
Где же у него кнопка???

http://images.yandex.ua/yandsearch?text=com-%D0%BF%D0%BE%D1%80%D1%82&noreask=1&img_url=www.adslclub.ru%2Fupload%2Fimg%2F2010-08%2F30-21265636147.jpg&pos=14&rpt=simage&lr=143
 
Автор
A

at

Гость
Поправил первый пост.


Добавлено:
Сообщение автоматически объединено:

Есть аналог - NETComm.ocx, похоже на полный клон MSCOMM32.OCX, с кое какими отличиями, точно не помню.
<a href="http://autoit-script.ru/index.php?action=downloads;sa=downfile&id=275" />NetCommOCX.zip</a>

Интересные факты: http://www.autoitscript.com/forum/topic/37349-question-about-netcommocx/
Цитата: "Если вы используете NETComm.ocx, вы не должны устанавливать и использовать VS 6 (или VB6). Это решает вопрос лицензирования, которая имеет MSCOMM32.OCX".

Как я понял из этой ветки, использование MSCOMM32.OCX без VS 6 (или VB6) не нарушает ее лицензионное соглашение. С трудом конечно вериться, вникать в текст лицензии MSCOMM32.OCX сейчас нет особого желания. Может кто знает и может подтвердить.


Добавлено:
Сообщение автоматически объединено:

Вот здесь: http://www.autoit.de/index.php?page=Thread&threadID=26832&pageNo=1 нашел вроде рабочий код:
Код:
#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

Помогите прикрутить к нему $Button1.
 
Верх