Befehle an COM 1 senden

  • Hallo, bin ein bisschen überfragt...

    Ich habe ein Digitalmultimeter über rs232 an com1 (auch rs232) angeschlossen. Ich möchte nun die vom Multimeter gemessenen Daten auf meinen Computer übertragen.

    Der Hersteller hat in seinen Handbuch einige Befehle zur Kommunikation gelistet, diese kann man senden um verschiedene Reaktionen, Ausgaben oder Abläufe zu steuern.

    Wenn ich die Befehle über das Hyperterminal (von Windows) eingebe erhalte ich stets korrekte antworten vom Gerät (Multimeter)...-> Übertragung ist sichergestellt.

    Was ich noch hinzufügen möchte ist das der Befehl in ASCII gesendet werden muss.

    Im englischsprachigen Forum habe ich bereits einen script gefunden, dieser Funktioniert jedoch nicht einwandfrei (gar nicht)...-> das Gerät erkennt zwar das "etwas" ankommt gibt anschließend jedoch ständig ;Syntax - Fehler; aus.

    Mein Betriebssystem ist Windows ME,

    Verbindungsdaten: 9600 Bps, 0 Parität, 8 Bits (angeschlossen an COM1)

    Hier ist der Skript den ich bereits versucht habe...

    Über Hilfe in Form eines Skriptes das Befehle in ASCII sendet oder informationen über den Ablauf wie die Informationen weiter verarbeitet werden (vom Programm, Computer oder sonstigen Bestandteilen)

    Vielen Dank im vorraus

    ( der Befehl der im Bsp. Skript gesendet wird heißt "DISP:TEXT 'Test'" )

  • Hallo xslip,

    hast du diesen http://www.autoitscript.com/forum/index.php?showtopic=45842</a> Link probiert, hat sich vielversprechend gelesen, ansonsten die Methode die du verwendest schau mal in MSDN-Library nach, da du ja ein MS Objekt verwendest, kannst dir ja auch hier Visual Studio Express downloaden, MSDN ist meines Wissens nach dabei. Ich bin vor Jahren mal in die Verlegenheit gekommen mit Delphi die Com1 anzusprechen, hab es damals ähnlich gemacht MS-Komponente eingebunden und die Hife von VB benutzt um mit der Komponente klarzukommen.

    Edit1: ich nehme an, du hast die sieben Themen schon gelesen, die Suchfunktion (oben links) anbietet wenn mann serielle Schittstelle eingibt, dieser sieht gut aus, er sendet Befehle und wertet die Inputs graphisch aus.

    Edit2: das sieht auch ganz gut aus

    Spoiler anzeigen
    [autoit]

    $MsComm = ObjCreate("MSCOMMLib.MsComm.1")

    [/autoit] [autoit][/autoit] [autoit]

    $MsComm.CommPort = 2
    $MsComm.Settings = "9600,N,8,1"
    $MsComm.Handshaking = 0
    $MsComm.InBufferSize = 1024
    $MsComm.InputLen = 1

    [/autoit] [autoit][/autoit] [autoit]

    $MsComm.PortOpen = 1

    [/autoit] [autoit][/autoit] [autoit]

    While 1
    _MsgOut("RT" & @CR)
    MsgBox(0,"Testing",_MsgIn())
    Sleep(2000)
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    Func _MsgOut($str)
    $MsComm.OutBufferCount = 0
    $MsComm.InBufferCount = 0

    If $MsComm.PortOpen = True Then
    $MsComm.Output = $str
    EndIf
    $MsComm.InputLen = 0
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _MsgIn()
    $TIMEOUT = 1000
    $nTimeCtr = 0
    $sBuffer = ""
    Do
    $nTimeCtr += 1
    If $MsComm.InBufferCount > 0 Then
    $sBuffer = $sBuffer & $MsComm.Input
    EndIf
    Sleep(500)
    Until StringInStr($sBuffer,@CR) OR $nTimeCtr > $TIMEOUT

    If $nTimeCtr < $TIMEOUT Then
    $nI = StringInStr($sBuffer,@CR)
    Return StringLeft($sBuffer,$nI)
    Else
    Return "Error"
    EndIf
    EndFunc

    [/autoit]

    gefunden auf http://www.autoitscript.com/forum/index.php?showtopic=13890&view=findpost&p=95392

    mfg (Auto)Bert

    2 Mal editiert, zuletzt von AutoBert (29. April 2009 um 02:07)

  • Vielen Dank für die antwort, jetzt weiß ich zumindest die Richtung in der ich weiter auf Fehlersuche gehen kann ^^....

    Eine Frage tut sich mir jetzt aber noch auf.

    Der Skript bezieht sich ja auf die MSComm.dll, in einige Foren habe ich nun gelesen das man diese erst aktivieren muss ( um diese zu verwenden ). Der jetzige stand ist, dass ein Signal am Multimeter ankommt... dieses kann es jedoch nicht als Befehl interpretieren.

    An der Verbindung kann es jedoch nicht liegen da ich mit den Hyperterminal einwandfrei Befehle senden und empfangen kann...

    Daher denke ich man nicht MSComm voll nutzen kann oder das die Befehle die ich sende im falschen Format sind (den schließelich will das Multimeter seine Befehle im ASCII-Format [oder wandelt MSComm das schon um?])

    Vielen Dank nochmal es geht voran^^

  • Hallo xslip,

    wenn die dll registriert werden muss, kannst du das ja über eine Installation von VS Studio Express erledigen, dann dürftest du auch rechtlich auf der sicheren Seite sein, trotzdem die Eula von MS zu Visua-Studio genau lesen. Wenn es nur um die Registry geht, da gehts auch einfacher, regsvr32 DLLNAME in Konsole (Dos-Box) ausführen, dies dürfte aber nicht nötig sein, da nach meinem Erachten das Skript ohne die registrierte Komponente bereits in der 1. Zeile eine Fehlermedung ausgegeben hätte,

    mfg (Auto)Bert

  • hy hy !!

    schau dir mal des an ...

    Code
    $MsComm1 = ObjCreate("MSCOMMLib.MsComm.1")												; überprüfung ob sich objekt com generieren lässt
    if not IsObj($MsComm1) then																; wenn nicht dann 
    MsgBox(0,"Fehler"," Kann datei : mscomm32.ocx : nicht im system finden. Installation läuft")
    FileInstall("MSCOMM32.OCX", EnvGet("SystemRoot") & "\System32\MSCOMM32.OCX")			; installation der mscomm32.ocx
    Run(@ComSpec & " /c C:\WINDOWS\SYSTEM32\REGSVR32.EXE C:\WINDOWS\SYSTEM32\MSCOMM32.OCX")	; ausführung
    RegWrite("HKEY_CLASSES_ROOT\Licenses\DB4C0D00-400B-101B-A3C9-08002B2F49FB", "", "REG_SZ", "mgkgtgnnmnmninigthkgogggvmkhinjggnvm")	; registration
    RegWrite("HKEY_CLASSES_ROOT\Licenses\7BC20EDC-4A42-101B-A3C9-08002B2F49FB", "", "REG_SZ", "gifblihbhiiihbciocfbkifbqcfcdiebbiqh")	; registration
    $MsComm1 = ObjCreate("MSCOMMLib.MsComm.1")												; erneute überprüfung ob sich objekt com generieren lässt
    endif


    bye

  • vivus,

    schönes script, ich würde aber trotzdem nur dann deine Methode wählen, wenn ich mir sicher bin, dass die entsprechende DLL (OCX zählt auch dazu) zurecht auf dem Zielordnercomputer existiert, warum du allerdings 2 mal registrierst 1 mal über regsvr32 und dann nochmal mit regwrite, hat sich mir allerdings nicht erschlossen, da ein aufruf von regsvr32 eigentlich alles erledigen sollte,

    mfg (Auto)Bert

  • Hallo xslip,

    schau dir mal diesen Artikel http://support.microsoft.com/kb/823179/de an, eventuell baust du ja dein Skript dann entsprechend auf (VB-Code enthalten, ist aber leicht umzusetzen), probier doch zu Testzwecken einfach mal dies:

    Spoiler anzeigen

    $MsComm = ObjCreate("MSCOMMLib.MsComm.1")
    if not IsObj($MsComm1) then
    MsgBox(0,"Fehler","MSComm nicht eingebumden")
    exit
    EnfIf
    $MsComm.CommPort = 1
    $MsComm.Settings = "9600,N,8,1"
    $MsComm.Handshaking = 0
    $MsComm.InBufferSize = 1024
    $MsComm.InputLen = 0 ;<-----------
    $MsComm.PortOpen = 1
    ;While 1 <--------------
    ;_MsgOut("DISP:TEXT 'Test'" & @CR)
    MSComm1.Output = "DISP:TEXT 'Test'" & @CR)
    MsgBox(0,"Testing",_MsgIn())
    Sleep(2000)
    exit
    ;WEnd <-----------------
    exit
    Func _MsgOut($str)
    $MsComm.OutBufferCount = 0
    $MsComm.InBufferCount = 0

    If $MsComm.PortOpen = True Then
    $MsComm.Output = $str
    EndIf
    $MsComm.InputLen = 0
    EndFunc
    Func _MsgIn()
    $TIMEOUT = 1000
    $nTimeCtr = 0
    $sBuffer = ""
    Do
    $nTimeCtr += 1
    If $MsComm.InBufferCount > 0 Then
    $sBuffer = $sBuffer & $MsComm.Input
    EndIf
    Sleep(500)
    Until StringInStr($sBuffer,@CR) OR $nTimeCtr > $TIMEOUT

    If $nTimeCtr < $TIMEOUT Then
    $nI = StringInStr($sBuffer,@CR)
    Return StringLeft($sBuffer,$nI)
    Else
    Return "Error"
    EndIf
    EndFunc

    [autoit][/autoit]

    aus,

    mfg (Auto)Bert

  • hab hier die elegantere Lösung

    commg.dll

    lässt sich mit

    Spoiler anzeigen
    [autoit]

    ;Opt("mustdeclarevars",1) testing only
    #cs
    UDF for commg.dll
    V1.0 Replaces mgcomm.au3
    #ce
    Const $sUDFVersion = 'CommMG.au3 V2.1 '
    #cs
    Version 2.1.1 Added missing declarations which caused problems in scripts using Opt("MustDeclareVars",1) - thanks to Hannes
    Version 2.1 Thanks to jps1x2 for the read/send bte array incentive and testing.
    Version 2.0.2 beta changed readbytearray so returns no of bytes read
    Version 2.0.1 beta
    added _CommSendByteArray and _CommReadByteArray
    Version 2.0 - added _CommSwitch. Can now use up to 4 ports.
    added option for flow control = NONE to _CommSetPort

    AutoIt Version: 3.2.3++
    Language: English

    Description: Functions for serial comms using commg.dll
    Works with COM ports, USB to Serial converters, Serial to RS424 etc

    Functions available:
    _CommGetVersion
    _CommListPorts
    _CommSetPort
    _CommPortConnection
    _CommClearOutputBuffer
    _CommClearInputBuffer
    _CommGetInputcount
    _CommGetOutputcount
    _CommSendString
    _CommGetString
    _CommGetLine
    _CommReadByte
    _CommReadChar
    _CommSendByte
    _CommSendBreak; not tested!!!!!!!!!!
    _CommCloseport
    _CommSwitch
    _CommSendByteArray
    _CommReadByteArray

    Author: Martin Gibson
    #ce
    #include-once

    [/autoit] [autoit][/autoit] [autoit]

    Global $fPortOpen = False
    Global $hDll

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ;
    ; Function Name: _CommListPorts($iReturnType=1)
    ; Description: Gets the list of available ports seperated by '|' or as an array
    ;
    ; Parameters: $iReturnType - integer:if $iReturnType = 1 then return a string with the list of COM ports seperated by '|'
    ; if $iReturnType <> 1 then return an array of strings, with element [0] holding the number of COM ports
    ; Returns; on success - a string eg 'COM1|COM8', or array eg ['2','COM1','COM2']
    ; on failure - an empty string and @error set to 1 if dll could not list any ports
    ; @error set to 2 id dll not open and couldn't be opened

    [/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    Func _CommListPorts($iReturnType = 1)
    Local $vDllAns, $lpres
    If Not $fPortOpen Then
    $hDll = DllOpen('commg.dll')
    If $hDll = -1 Then
    SetError(2)
    ;$sErr = 'Failed to open commg.dll'
    Return 0;failed
    EndIf
    $fPortOpen = True
    EndIf
    If $fPortOpen Then
    $vDllAns = DllCall($hDll, 'str', 'ListPorts')
    If @error = 1 Then
    SetError(1)
    Return ''
    Else

    ;ConsoleWrite($vDllAns[0] & @CRLF)
    If $iReturnType = 1 Then
    Return $vDllAns[0]
    Else
    Return StringSplit($vDllAns[0], '|')
    EndIf


    EndIf
    Else
    SetError(1)
    Return ''
    EndIf

    [/autoit] [autoit][/autoit] [autoit]


    EndFunc ;==>_CommListPorts

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ;
    ; Function Name: _Commgetversion($iType = 1)
    ; Description: Gets the version of the dll if $iType = 1
    ; Or the version of this UDF if $iType = 2
    ; Parameters: $iType - integer: = 1 to reurn the commg.dll version
    ; = 2 to return the UDF version
    ; Returns; on success - a string eg 'V1.3'
    ; on failure - an empty string and @error set to 1

    [/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _CommGetVersion($iType = 1)
    Local $vDllAns
    If $iType = 2 Then Return $sUDFVersion

    If $fPortOpen Then
    $vDllAns = DllCall($hDll, 'str', 'Version')

    If @error = 1 Then
    SetError(1)
    ConsoleWrite('error in get version' & @CRLF)
    Return ''
    Else
    ;ConsoleWrite('length of version is ' & stringlen($vDllAns[0]) & @CRLF)
    Return $vDllAns[0]

    EndIf
    Else
    $vDllAns = DllCall('commg.dll', 'str', 'Version')
    If @error = 1 Then
    SetError(1)
    ConsoleWrite('error in get version' & @CRLF)
    Return ''
    Else
    ;ConsoleWrite('length of version is ' & stringlen($vDllAns[0]) & @CRLF)
    Return $vDllAns[0]
    EndIf
    EndIf

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    EndFunc ;==>_CommGetVersion

    [/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ;
    ; Function Name: _CommSwitch($channel)
    ;switches functions to operate on channel 1, 2, 3 or 4
    ;if $channel > 4 then switches to 1
    ;returns on succes the channel switched to ie 1 or 2
    ; on failure -1
    ;Remarks on start up of script channel 1 is selected, so if you only need one COM port
    ; you don't need to use _CommSwitch
    ; each channel needs to be set up with _CommSetPort
    ; The same COM port cannot be used on more than one channel.
    ; The channel number is not related to the COM port number, so channel 1 can
    ; be set to use COM2 and channel 4 can be set to use COM1 or any available port.
    ;======================================================================================
    Func _CommSwitch($channel)
    Local $vDllAns

    [/autoit] [autoit][/autoit] [autoit]

    $vDllAns = DllCall($hDll, 'int', 'switch', 'int', $channel)
    If @error <> 0 Then
    SetError(1)
    Return -1
    Else
    Return $vDllAns[0]
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    EndFunc ;==>_CommSwitch

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;===========================================================================================================
    ;
    ; Function Name: _CommSetport($iPort,ByRef $sErr,$iBaud=9600,$iBits=8,$vDllAnsar=0,$iStop=1,$iFlow=0)
    ; Description: Initialises the port and sets the parameters
    ; Parameters: $iPort - integer = the port or COM number to set. Allowed values are 1 or higher.
    ; NB WIndows refers To COM10 Or higher`as \\.\com10 but only use the number 10, 11 etc
    ; $sErr - string: the string to hold an error message if func fails.
    ; $iBaud - integer: the baud rate required. allowed values are one of
    ; 50, 75, 110, 150, 600, 1200, 1800, 2000, 2400, 3600, 4800, 7200, 9600, 10400,
    ; 14400, 15625, 19200, 28800, 38400, 56000, 57600, 115200, 128000, 256000
    ; $iBits - integer: number of bits in code to be transmitted
    ; $iParity - integer: 0=None,1=Odd,2=Even,3=Mark,4=Space
    ; $iStop - integer: number of stop bits, 1=1 stop bit 2 = 2 stop bits, 15 = 1.5 stop bits
    ; $iFlow - integer: 0 sets hardware flow control,
    ; 1 sets XON XOFF control,
    ; 2 sets NONE i.e. no flow control.
    ; Returns; on success - returns 1 and sets $sErr to ''
    ; on failure - returns 0 and with the error message in $sErr, and sets @error as follows
    ; @error meaning error with
    ; 1 dll call failed
    ; 2 dll was not open and could not be opened
    ; -1 $iBaud
    ; -2 $iStop
    ; -4 $iBits
    ; -8 $iPort = 0 not allowed
    ; -16 $iPort not found
    ; -32 $iPort access denied (in use?)
    ; -64 unknown error
    ;Remarks You cannot set the same COM port on more than one channel
    ;===========================================================================================================

    [/autoit] [autoit][/autoit] [autoit]

    Func _CommSetPort($iPort, ByRef $sErr, $iBaud = 9600, $iBits = 8, $iPar = 0, $iStop = 1, $iFlow = 0)
    Local $vDllAns
    Local $sMGBuffer = ''
    $sErr = ''
    If Not $fPortOpen Then
    $hDll = DllOpen('commg.dll')
    If $hDll = -1 Then
    SetError(2)
    $sErr = 'Failed to open commg.dll'
    Return 0;failed
    EndIf
    $fPortOpen = True
    EndIf
    ConsoleWrite('port = ' & $iPort & ', baud = ' & $iBaud & ', bits = ' & $iBits & ', par = ' & $iPar & ', stop = ' & $iStop & ', flow = ' & $iFlow & @CRLF)

    $vDllAns = DllCall($hDll, 'int', 'SetPort', 'int', $iPort, 'int', $iBaud, 'int', $iBits, 'int', $iPar, 'int', $iStop, 'int', $iFlow)
    If @error <> 0 Then
    $sErr = 'dll SetPort call failed'
    SetError(1)
    Return 0
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    If $vDllAns[0] < 0 Then
    SetError($vDllAns[0])
    Switch $vDllAns[0]
    Case - 1
    $sErr = 'undefined baud rate'
    Case - 2
    $sErr = 'undefined stop bit number'
    Case - 4
    $sErr = 'undefined data size'
    Case - 8
    $sErr = 'port 0 not allowed'
    Case - 16
    $sErr = 'port does not exist'
    Case - 32
    $sErr = 'access denied, maybe port already in use'
    Case - 64
    $sErr = 'unknown error accessing port'
    EndSwitch
    Return 0
    Else
    Return 1
    EndIf

    EndFunc ;==>_CommSetPort

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;===================================================================================
    ;
    ; Function Name: _CommPortConnection()
    ; Description: Gets the port connected to the selected channel - see _CommSwitch
    ; Parameters: None
    ; Returns; on success - a string eg 'COM5'
    ; on failure - an empty string and @error set to the rerror set by DllCall
    ; Remarks - Can be used to verify the port is connected

    [/autoit] [autoit][/autoit] [autoit]

    ;====================================================================================

    [/autoit] [autoit][/autoit] [autoit]

    Func _CommPortConnection()
    Local $vDllAns
    $vDllAns = DllCall($hDll, 'str', 'Connection');reply is port eg COM8

    [/autoit] [autoit][/autoit] [autoit]

    If @error <> 0 Then
    SetError(@error)
    Return ''
    Else
    Return $vDllAns[0]
    EndIf


    EndFunc ;==>_CommPortConnection

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;=====================================================================================
    ;
    ; Function Name: _CommSendString($sMGString,$iWaitComplete=0)
    ; Description: Sends a string to the connected port on the currently selected channel
    ; Parameters: $sMGString: the string to send sent without any extra CR or LF added.
    ; $iWaitComplete- integer:0 = do not wait till string sent
    ; 1 = wait till sent
    ; Returns: always 1
    ; on success- @error set to 0
    ; on failure - @error set to the error returned from DllCall
    ;======================================================================================

    [/autoit] [autoit][/autoit] [autoit]

    Func _CommSendString($sMGString, $iWaitComplete = 0)
    ;sends $sMGString on the currently open port
    ;returns 1 if ok, returns 0 if port not open/active
    Local $vDllAns
    $vDllAns = DllCall($hDll, 'int', 'SendString', 'str', $sMGString, 'int', $iWaitComplete)
    If @error <> 0 Then
    SetError(@error)
    Return ''
    Else
    Return $vDllAns[0]
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    EndFunc ;==>_CommSendString

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;================================================================================
    ;
    ; Function Name: _CommGetstring()
    ; Description: Get whatever characters are available received by the port for the selected channel
    ; Parameters: none
    ; Returns: on success the string and @error is 0
    ; if input buffer empty then empty string returned
    ; on failure an empty string and @error set to the error set by DllCall
    ; Notes: Use GetLIne to get a whole line treminated by @CR or a defined character.
    ;=================================================================================

    [/autoit] [autoit][/autoit] [autoit]

    Func _Commgetstring()
    ;get a string NB could be part of a line depending on what is in buffer
    Local $vDllAns
    ;$sStr1 = ''
    ;$vDllAns = DllCall($hDll,'str','GetByte')
    $vDllAns = DllCall($hDll, 'str', 'GetString')

    If @error <> 0 Then
    SetError(1)
    ConsoleWrite('error in _commgetstring' & @CRLF)
    Return ''
    EndIf
    Return $vDllAns[0]
    EndFunc ;==>_Commgetstring

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;====================================================================================
    ;
    ; Function Name: _CommGetLine($EndChar = @CR,$maxlen = 10000, $maxtime = 10000)
    ; Description: Get a string ending in $lineEnd
    ; Parameters: $lineEnd the character to indicate the end of the string to return.
    ; The $lineEnd character is included in the return string.
    ; $MaxLen - integer: the maximum length of a string before
    ; returning even if $linEnd not received
    ; If $maxlen is 0 then there is no number of characters
    ; $maxtime - integer:the maximum time in mS to wait for the $EndChar before
    ; returning even if $linEnd not received.
    ; If $maxtime is 0 then there is no max time to wait
    ;
    ; Returns: on success the string and @error is 0
    ; If $maxlen characters received without the $lineEnd character, then these
    ; characters are returned and @error is set To -1.
    ; If $maxtime passes without receiving the $lineEnd character, then the characters
    ; received so far are returned and @error is set To -2.
    ; on failure areturns any characters reeived and sets @error to 1
    ;======================================================================================
    Func _CommGetLine($sEndChar = @CR, $maxlen = 0, $maxtime = 0)
    Local $vDllAns, $sLineRet, $sStr1, $waited, $sNextChar, $iSaveErr

    [/autoit] [autoit][/autoit] [autoit]

    $sStr1 = ''; $sMGBuffer
    $waited = TimerInit()

    While 1;stringinstr($sStr1,$EndChar) = 0
    If TimerDiff($waited) > $maxtime And $maxtime > 0 Then
    SetError(-2)
    Return $sStr1
    EndIf


    If StringLen($sStr1) >= $maxlen And $maxlen > 0 Then
    SetError(-1)
    Return $sStr1
    EndIf
    ;$ic = _CommGetInputCount()
    $sNextChar = _CommReadChar()
    $iSaveErr = @error
    If $iSaveErr = 0 And $sNextChar <> '' Then

    $sStr1 = $sStr1 & $sNextChar
    ;ConsoleWrite($sStr1 & @CRLF)
    If $sNextChar = $sEndChar Then ExitLoop

    EndIf

    If $iSaveErr <> 0 Then
    SetError(1)
    Return $sStr1
    EndIf

    WEnd

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Return $sStr1
    EndFunc ;==>_CommGetLine

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;============================================================================
    ;
    ; Function Name: _CommGetInputCount()
    ; Description: Get the number of characters available to be read from the port.
    ; Parameters: none
    ; Returns: on success a string conversion of the number of characters.(eg '0', '26')
    ; on failure returns an empty string and sets @error to 1
    ;===============================================================================

    [/autoit] [autoit][/autoit] [autoit]

    Func _CommGetInputCount()
    Local $vDllAns
    $vDllAns = DllCall($hDll, 'str', 'GetInputCount')

    If @error <> 0 Then
    SetError(1)
    Return 0
    Else
    Return $vDllAns[0]

    EndIf

    [/autoit] [autoit][/autoit] [autoit]


    EndFunc ;==>_CommGetInputCount

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;============================================================================
    ;
    ; Function Name: _CommGetOutputCount()
    ; Description: Get the number of characters waiting to be sent from the port.
    ; Parameters: none
    ; Returns: on success a string conversion of the number of characters.(eg '0', '26')
    ; on failure returns an empty string and sets @error to 1
    ;===============================================================================
    Func _CommGetOutputCount()
    Local $vDllAns

    [/autoit] [autoit][/autoit] [autoit]

    $vDllAns = DllCall($hDll, 'str', 'GetOutputCount')

    If @error <> 0 Then
    SetError(1)
    Return ''
    Else
    Return $vDllAns[0]
    EndIf

    [/autoit] [autoit][/autoit] [autoit]


    EndFunc ;==>_CommGetOutputCount

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;================================================================================================
    ;
    ; Function Name: _CommReadByte($wait = 0)

    [/autoit] [autoit][/autoit] [autoit]

    ; Description: Reads the byte as a string
    ; Parameters: $wait:integer if 0 then if no data to read then return -1 and set @error to 1
    ; if <> 0 then does not return untill a byte has been read
    ; Returns: on success a string conversion of the value of the byte read.(eg '0', '20')
    ; on failure returns empty string and sets @error to 1 if no data to read and $wait is 0
    ; Returns empty string and sets @error to 2 ifDllCall failed
    ;
    ;;NB could hang if nothing rec'd when wait is <> 0
    ;==================================================================================================
    Func _CommReadByte($wait = 0)
    Local $iCount, $vDllAns
    If Not $wait Then
    $iCount = _CommGetInputCount()
    If $iCount = 0 Then
    SetError(1)
    Return ''
    EndIf
    EndIf

    $vDllAns = DllCall($hDll, 'str', 'GetByte')

    If @error <> 0 Then
    SetError(2)
    Return ''
    EndIf
    ;ConsoleWrite('byte read was ' & $vDllAns[0] & @CRLF)
    Return $vDllAns[0]

    EndFunc ;==>_CommReadByte

    [/autoit] [autoit][/autoit] [autoit]

    ;============================================================================
    ;
    ; Function Name: _CommReadChar($wait = 0)

    [/autoit] [autoit][/autoit] [autoit]

    ; Description: Reads the next Character as a string
    ; Parameters: $wait:integer if 0 then if no data to read then return -1 and set @error to 1
    ; if <> 0 then does not return untill a byte has been read
    ; Returns: on success a string of 1 character
    ; on failure returns empty string and sets @error to 1
    ;
    ;
    ;;NB could hang if nothing rec'd when wait is <> 0
    ;===============================================================================

    [/autoit] [autoit][/autoit] [autoit]

    Func _CommReadChar($wait = 0)
    Local $sChar, $iErr

    [/autoit] [autoit][/autoit] [autoit]

    $sChar = _CommReadByte($wait)
    $iErr = @error
    If $iErr > 2 Then
    SetError(1)
    Return ''
    EndIf
    If $iErr == 0 Then Return Chr(Execute($sChar))
    EndFunc ;==>_CommReadChar

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;============================================================================
    ; Function Name: SendByte($byte,$iWaitComplete=0)

    [/autoit] [autoit][/autoit] [autoit]

    ; Description: Sends the byte value of $byte. $byte must be in range 0 to 255
    ; Parameters: $byte the byte to send.
    ; $iWaitComplete - integer: if 0 then functions returns without
    ; waiting for byte to be sent
    ; If <> 0 then waits till byte sent.
    ; Returns: on success returns 1
    ; on failure returns -1 and sets @error to 1
    ;
    ;;NB could hang if byte cannot be sent and $iWaitComplete <> 0
    ;===============================================================================
    Func _CommSendByte($byte, $iWaitComplete = 0)
    Local $vDllAns

    [/autoit] [autoit][/autoit] [autoit]

    $vDllAns = DllCall($hDll, 'int', 'SendByte', 'int', $byte, 'int', $iWaitComplete)
    If @error <> 0 Then
    SetError(1)
    Return -1
    Else
    Return $vDllAns[0]
    EndIf

    EndFunc ;==>_CommSendByte

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ; Function Name: _CommSendByteArray($pAddr,$iNum,$iWait)

    [/autoit] [autoit][/autoit] [autoit]

    ; Description: Sends the bytes from address $pAddress
    ; Parameters: $iNum the number of bytes to send.
    ; $iWaitComplete - integer: if 0 then functions returns without
    ; waiting for bytes to be sent
    ; if <> 0 then waits untill all bytes are sent.
    ; Returns: on success returns 1
    ; on failure returns -1 and sets @error to 1
    ;
    ;;NB could hang if byte cannot be sent and $iWaitComplete <> 0
    ; could lose data if you send more bytes than the size of the outbuffer.
    ; the output buffer size is 2048
    ;===============================================================================
    Func _CommSendByteArray($pAddr, $iNum, $iWait)
    Local $vDllAns = DllCall($hDll, 'int', 'SendByteArray', 'ptr', $pAddr, 'int', $iNum, 'int', $iWait)
    If @error <> 0 Or $vDllAns[0] = -1 Then
    SetError(1)
    Return -1
    Else
    Return $vDllAns[0]
    EndIf

    EndFunc ;==>_CommSendByteArray

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;====================================================================================
    ; Function Name: _CommReadByteArray($pAddr,$iNum,$iWait)
    ;
    ; Description: Reads bytes and writes them to memory starting at address $pAddress
    ; Parameters: $iNum the number of bytes to read.
    ; $iWaitComplete - integer: if 0 and then the functions returns
    ; with the available bytes up to $iNum.
    ; if 1 then waits untill the $iNum bytes received.
    ; Returns: on success returns the Number of bytes read.
    ; on failure returns -1 and sets @error to 1
    ;
    ;;NB could hang if bytes are not received and $iWaitComplete <> 0
    ; the input buffer size is 4096
    ;====================================================================================
    Func _CommReadByteArray($pAddr, $iNum, $iWait)
    Local $vDllAns = DllCall($hDll, 'int', 'ReadByteArray', 'ptr', $pAddr, 'int', $iNum, 'int', $iWait)
    If @error <> 0 Or $vDllAns[0] = -1 Then
    SetError(1)
    Return -1
    Else
    Return $vDllAns[0]
    EndIf


    EndFunc ;==>_CommReadByteArray

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ; Function Name: ClearOutputBuffer()

    [/autoit] [autoit][/autoit] [autoit]

    ; Description: Clears any characters in the out put queue5
    ; Parameters: none
    ; Returns: on success returns 1
    ; on failure returns -1 and sets @error to 1
    ;
    ;===============================================================================
    Func _CommClearOutputBuffer()

    Local $vDllAns = DllCall($hDll, 'int', 'ClearOutputBuffer')

    EndFunc ;==>_CommClearOutputBuffer

    [/autoit] [autoit][/autoit] [autoit]

    Func _CommClearInputBuffer()
    Local $sMGBuffer = ''
    Local $vDllAns = DllCall($hDll, 'int', 'ClearInputBuffer')
    If @error <> 0 Then
    Return -1
    Else
    Return 1
    EndIf

    EndFunc ;==>_CommClearInputBuffer

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ; Function Name: ClosePort()

    [/autoit] [autoit][/autoit] [autoit]

    ; Description: closes the port

    [/autoit] [autoit][/autoit] [autoit]

    ; Parameters: none

    [/autoit] [autoit][/autoit] [autoit]

    ; Returns: no return value
    ;===============================================================================
    Func _CommClosePort()
    ;_CommClearOutputBuffer()
    ;_CommClearInputBuffer()
    DllCall($hDll, 'int', 'CloseDown')
    DllClose($hDll)
    $fPortOpen = False
    EndFunc ;==>_CommClosePort

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;================================================================================================
    ; Function Name: SendBreak($iDowTime,$iUpTime)
    ; NB Simulates the break signal used by some equipment to indicate the start of a sequence
    ; Not tested so might Not work. Any feedback welcome - PM martin on Autoit forum

    [/autoit] [autoit][/autoit] [autoit]

    ; Description: sets the TX line low for $iDowTime, then sets it high for $iUpTime

    [/autoit] [autoit][/autoit] [autoit]

    ; Parameters: $iDowTime - integer: the number of ms to hold the TX line down
    ; $iUpTime - integer: the number of ms to hold the line up for before returning
    ; if $iDowTime or $iUpTime is zero then does nothing and returns
    ; Returns: on success returns 1
    ; on failure returns 0 and sets @error to
    ; = 1 if one of params is zero
    ; = 2 1 unable to use the DLL file,
    ; = 3 unknown "return type" from dll
    ; = 4 "function" not found in the DLL file.

    [/autoit] [autoit][/autoit] [autoit]

    ; Notes : Not tested!
    ;================================================================================================
    Func _CommSendBreak($iDowTime, $iUpTime);requires commg.dll v2.0 or later
    Local $vDllAns
    If $iDowTime = 0 Or $iUpTime = 0 Then
    SetError(1)
    Return 0
    EndIf

    If Not $fPortOpen Then
    SetError(1)
    Return 0
    EndIf
    $vDllAns = DllCall($hDll, 'int', 'SendBreak', 'int', $iDowTime, 'int', $iUpTime)
    If @error <> 0 Then
    SetError(@error + 1)
    Return 0
    Else
    ;ConsoleWrite('done setbreak' & @CRLF)
    Return 1;success
    EndIf

    EndFunc ;==>_CommSendBreak

    [/autoit]

    wunder bar bearbeiten ... ;)

    somit kann man auf die MSCOMMLib.MsComm verzichten ..

    bye

    Edit BugFix:
    Die Benutzung des Spoilers ist nicht nur möglich, sondern ausdrücklich erwünscht. (Tags gesetzt)

    Einmal editiert, zuletzt von BugFix (24. Juni 2010 um 12:02)

  • Der thread ist über ein Jahr als-->Leichenschänder :D

    und bitte so lange Quelltexte Spoilern

    ;) besser spät als nie ... und wir wollen ja alle, dass die suche in AutoIt weiter so gut funktioniert, damit nicht immer die gleichen fragen beantwortet werden müssen ..

    globales wachsen des kollektiven Wissens ;)

    PS: hab gedacht, wenn ich auf "AutoIt-Quellcode gehe, dass er automatisch gespoilert wird .. tüt mich sorryyy !!


    .. hier aber noch n paar beispiele ..

    Spoiler anzeigen

    ;Example program showing how to use some of the commMg3.au3 UDF functions
    ;this example is a very simple terminal
    ;Version 2 26th July 2006
    ;changes-
    ;change flow control checkbox to combo and add NONE
    ;correct error in call to _CommSetPort - stop bits were missing which meant th eflow control was used for stop bits

    #include <GUIConstants.au3>
    #include 'CommMG.au3';or if you save the commMg.dll in the @scripdir use #include @SciptDir & '\commmg.dll'
    #include <GuiEdit.au3>
    #include <GuiComboBox.au3>
    #include <windowsconstants.au3>
    #include <buttonconstants.au3>

    Opt("WINTITLEMATCHMODE", 3)
    OnAutoItExitRegister("alldone")
    HotKeySet("{ESC}", "alldone")

    $result = '';used for any returned error message setting port
    Const $settitle = "COMMG Example - set Port", $maintitle = "COMMG Example"
    $setflow = 2;default to no flow control
    Dim $FlowType[3] = ["XOnXoff", "Hardware (RTS, CTS)", "NONE"]
    #Region main program

    #Region ### START Koda GUI section ### Form=d:\my documents\miscdelphi\commg\ExampleComm.kxf
    $Form2 = GUICreate("COMMG Example", 473, 349, 339, 333, BitOR($WS_MAXIMIZEBOX, $WS_MINIMIZEBOX, $WS_SIZEBOX, $WS_THICKFRAME, $WS_SYSMENU, $WS_CAPTION, $WS_OVERLAPPEDWINDOW, $WS_TILEDWINDOW, $WS_POPUP, $WS_POPUPWINDOW, $WS_GROUP, $WS_TABSTOP, $WS_BORDER, $WS_CLIPSIBLINGS))
    $Edit1 = GUICtrlCreateEdit("", 10, 25, 449, 223, BitOR($ES_AUTOVSCROLL, $ES_AUTOHSCROLL, $ES_READONLY, $ES_WANTRETURN, $WS_HSCROLL, $WS_VSCROLL))
    $BtnSend = GUICtrlCreateButton("Send", 380, 273, 53, 30, $BS_FLAT)
    $Input1 = GUICtrlCreateInput("", 18, 279, 361, 21)
    $Checkbox1 = GUICtrlCreateCheckbox("Add LF to incomming CR", 273, 4, 145, 17)
    GUICtrlSetState(-1, $GUI_CHECKED)
    GUICtrlSetResizing(-1, $GUI_DOCKAUTO)
    $Label11 = GUICtrlCreateLabel("Text to send", 24, 261, 63, 17)
    $BtnSetPort = GUICtrlCreateButton("Set Port", 16, 312, 73, 30, $BS_FLAT)
    $Label21 = GUICtrlCreateLabel("Received text", 34, 6, 70, 17)
    $Label31 = GUICtrlCreateLabel("commg.dll version unknown", 272, 328, 135, 17)
    GUICtrlSetColor(-1, 0x008080)
    GUISetState(@SW_SHOW)
    #EndRegion ### END Koda GUI section ###
    WinSetTitle($Form2, "", $maintitle & " UDF = " & _CommGetVersion(1))

    While setport(0) = -1
    If MsgBox(4, 'Port not set', 'Do you want to quite the program?') = 6 Then Exit
    WEnd


    #cs
    _CommSwitch(2)
    MsgBox(0,'set com11 res = ',_CommSetport(11,$result,9600,8,'none',1,1))
    MsgBox(0,'set port 11 gives',$result)
    _CommSendString("It's Monday" & @CR)
    _CommSwitch(1)
    AdlibEnable("port11",500)
    #ce


    ;GUISwitch($Form2)
    ConsoleWrite("stage 1" & @CRLF)
    GUICtrlSetData($Label31, 'using ' & _CommGetVersion(1))
    ConsoleWrite("stage 2" & @CRLF)
    Events()

    GUICtrlSetState($Edit1, $GUI_FOCUS)

    While 1

    ;gets characters received returning when one of these conditions is met:
    ;receive @CR, received 20 characters or 200ms has elapsed
    $instr = _CommGetString()

    If $instr <> '' Then;if we got something

    If GUICtrlRead($Checkbox1) = $GUI_CHECKED Then $instr = StringReplace($instr,@CR,@CRLF)
    GUICtrlSetData($Edit1, $instr,1)

    EndIf

    WEnd

    Alldone()


    Func port11()
    ;MsgBox(0,'now set to channel',_CommSwitch(2))
    _commSwitch(2)
    $s2 = "1 2 3 4";_CommGetString()
    ConsoleWrite("comm1 gets " & $s2 & @CRLF)
    _CommSendString($s2)
    _CommSwitch(1)

    EndFunc ;==>port11

    #EndRegion main program
    Func Events()
    Opt("GUIOnEventMode", 1)
    GUISetOnEvent($GUI_EVENT_CLOSE, "justgo")
    GUICtrlSetOnEvent($BtnSend, "SendEvent")
    GUICtrlSetOnEvent($BtnSetPort, "SetPortEvent")
    EndFunc ;==>Events

    Func SetPortEvent()
    setport();needed because a parameter is optional for setport so we can't use "setport" for the event
    GUICtrlSetState($Edit1, $GUI_FOCUS)
    EndFunc ;==>SetPortEvent

    Func justgo()
    Exit
    EndFunc ;==>justgo

    Func SendEvent();send the text in the inputand append CR
    _CommSendstring(GUICtrlRead($Input1) & @CR)
    GUICtrlSetData($Input1, '');clear the input
    ;GUICtrlSetState($edit1,$GUI_FOCUS);sets the caret back in the terminal screen
    EndFunc ;==>SendEvent


    Func AllDone()
    ;MsgBox(0,'will close ports','')
    _Commcloseport()
    ;MsgBox(0,'port closed','')
    Exit
    EndFunc ;==>AllDone


    ; Function SetPort($mode=1)
    ; Creates a form for the port settings
    ;Parameter $mode sets the return value depending on whether the port was set
    ;Returns 0 if $mode <> 1
    ; -1 If` the port not set and $mode is 1
    Func SetPort($mode = 1);if $mode = 1 then returns -1 if settings not made

    Opt("GUIOnEventMode", 0);keep events for $Form2, use GuiGetMsg for $Form3

    #Region ### START Koda GUI section ### Form=d:\my documents\miscdelphi\commg\examplecommsetport.kxf
    $Form3 = GUICreate("COMMG Example - set Port", 422, 279, 329, 268, BitOR($WS_MINIMIZEBOX, $WS_CAPTION, $WS_POPUP, $WS_GROUP, $WS_BORDER, $WS_CLIPSIBLINGS, $DS_MODALFRAME), BitOR($WS_EX_TOPMOST, $WS_EX_WINDOWEDGE))
    $Group1 = GUICtrlCreateGroup("Set COM Port", 18, 8, 288, 252)
    $CmboPortsAvailable = GUICtrlCreateCombo("", 127, 28, 145, 25)
    $CmBoBaud = GUICtrlCreateCombo("9600", 127, 66, 145, 25, BitOR($CBS_DROPDOWN, $CBS_AUTOHSCROLL, $CBS_SORT, $WS_VSCROLL))
    GUICtrlSetData(-1, "10400|110|115200|1200|128000|14400|150|15625|1800|19200|2000|2400|256000|28800|3600|38400|4800|50|56000|57600|600|7200|75")
    $CmBoStop = GUICtrlCreateCombo("1", 127, 141, 145, 25)
    GUICtrlSetData(-1, "1|2|1.5")
    $CmBoParity = GUICtrlCreateCombo("none", 127, 178, 145, 25)
    GUICtrlSetData(-1, "odd|even|none")
    $Label2 = GUICtrlCreateLabel("Port", 94, 32, 23, 17)
    $Label3 = GUICtrlCreateLabel("baud", 89, 70, 28, 17)
    $Label4 = GUICtrlCreateLabel("No. Stop bits", 52, 145, 65, 17)
    $Label5 = GUICtrlCreateLabel("parity", 88, 182, 29, 17)
    $CmboDataBits = GUICtrlCreateCombo("8", 127, 103, 145, 25)
    GUICtrlSetData(-1, "7|8")
    $Label7 = GUICtrlCreateLabel("No. of Data Bits", 38, 107, 79, 17)
    $ComboFlow = GUICtrlCreateCombo("NONE", 127, 216, 145, 25)
    GUICtrlSetData(-1, "NONE|XOnXOff|Hardware (RTS, CTS)")
    $Label1 = GUICtrlCreateLabel("flow control", 59, 220, 58, 17)
    GUICtrlCreateGroup("", -99, -99, 1, 1)
    $BtnApply = GUICtrlCreateButton("Apply", 315, 95, 75, 35, $BS_FLAT)
    GUICtrlSetFont(-1, 12, 400, 0, "MS Sans Serif")
    $BtnCancel = GUICtrlCreateButton("Cancel", 316, 147, 76, 35, $BS_FLAT)
    GUICtrlSetFont(-1, 12, 400, 0, "MS Sans Serif")
    GUISetState(@SW_SHOW)
    #EndRegion ### END Koda GUI section ###


    WinSetTitle($Form3, "", $settitle);ensure a change to Koda design doesn't stop script working
    $mainxy = WinGetPos($Form2)
    WinMove($Form3, "", $mainxy[0] + 20, $mainxy[1] + 20)
    ;$set = _CommSetport(1,$result,9600,8,0,1,0)
    ;help
    ;send /rcv
    ;
    $portlist = _CommListPorts(0);find the available COM ports and write them into the ports combo
    If @error = 1 Then
    MsgBox(0, 'trouble getting portlist', 'Program will terminate!')
    Exit
    EndIf


    For $pl = 1 To $portlist[0]
    GUICtrlSetData($CmboPortsAvailable, $portlist[$pl]);_CommListPorts())
    Next
    GUICtrlSetData($CmboPortsAvailable, $portlist[1]);show the first port found
    GUICtrlSetData($ComboFlow, $FlowType[$setflow])
    _GUICtrlComboBox_SetMinVisible($CmBoBaud, 10);restrict the length of the drop-down list

    $retval = 0

    While 1
    $msg = GUIGetMsg()
    If $msg = $BtnCancel Then
    If Not $mode Then $retval = -1
    ExitLoop
    EndIf


    If $msg = $BtnApply Then
    Local $sportSetError
    $comboflowsel = GUICtrlRead($ComboFlow)
    For $n = 0 To 2
    If $comboflowsel = $FlowType[$n] Then
    $setflow = $n
    ConsoleWrite("flow = " & $setflow & @CRLF)
    ExitLoop
    EndIf

    Next
    $setport = StringReplace(GUICtrlRead($CmboPortsAvailable), 'COM', '')
    _CommSetPort($setport, $sportSetError, GUICtrlRead($CmBoBaud), GUICtrlRead($CmboDataBits), GUICtrlRead($CmBoParity), GUICtrlRead($CmBoStop), $setflow)
    if $sportSetError = '' Then
    MsgBox(262144, 'Connected ','to COM' & $setport)
    Else
    MsgBox(262144, 'Setport error = ', $sportSetError)
    EndIf
    $mode = 1;
    ExitLoop
    EndIf

    ;stop user switching back to $form2
    If WinActive($maintitle) Then
    ConsoleWrite('main is active' & @CRLF)
    If WinActivate($settitle) = 0 Then MsgBox(0, 'not found', $settitle)
    EndIf


    WEnd
    GUIDelete($Form3)
    WinActivate($maintitle)
    Events()
    Return $retval


    EndFunc ;==>SetPort