COM Objekt für RS232 Kommunikation

  • Hallo zusammen

    Ich bin nun schon seit geraumer Zeit auf der Suche nach einem COM Objekt für RS232 Kommunikation welches ich mit AutoIt ansteuern kann.
    Klar, ich kenne diesen Thread. Dies funktioniert auch einwandfrei (32bit), ist aber leider mit externer und mir unbekannter DLL!
    Auch die Threads mit der MSCOMM32.ocx kenne ich. (z.B. hier). Dies funktioniert auch - teilweise. Dort kommt es auf den Computer drauf an und welche Komponenten / Entwicklungsumgebungen sonst noch installiert sind.
    Auch die NETComm.ocxThreads kenne ich, welche aber augenscheinlich wieder auf der MSCOMM32.ocx basieren.

    Was ich suche ist eine Lösung ohne externe (fremde) DLL welche zuerst noch ins System gebracht und registriert werden muss.

    M$ kann seit vielen Jahren auch aus der DOS-Box auf die serielle Schnittstelle schreiben. Da sollte es doch möglich sein, ein COM Objekt dafür zu finden. Von mir aus kann .NET eine Voraussetzung dafür sein.
    Es sollte einfach im System vorhanden sein und zuverlässig sowohl mit 32Bit als auch mit 64bit kompillierten AutoIt Scripten funktionieren.

    Ich muss "bloss" die serielle Schnittstelle konfigurieren können, Strings senden und empfangen, sowie das RTS setzen und das DCD Abfragen.

    Es wäre toll, wenn jemand eine Lösung findet. Mit dem OLEViewer 2.0 habe ich schon erfolglos gesucht.

    Danke!
    Veronesi

    3 Mal editiert, zuletzt von veronesi (27. April 2011 um 08:13)

  • Krass was für eine Frage stell dir vor es gibt auch heutzutage geräte die man über RS232 Steuern bzw eine neue software aufspielen kann.

    Aber was is den so schlimm an der DLL?
    Weil so ganz ohne fällt mir auch nix ein

  • Ganz ohne externe DLL wäre mir am liebsten.
    1. Weil ich den DLL Inhalt nicht kenne und meine Auftraggeber sehr kritisch gegenüber fremden DLLs eingestellt sind
    2. Die bestehenden DLLs meistens (immer?) 32bit sind. Meine Auftraggeber möchten das ganze Programm als 64Bit kompiliert haben => und nein: das hat keinen bestimmten Grund...

    Es muss nicht ein COM Objekt sein. Sollte halt etwas mit internen Windows DLLs sein, da die Auftraggeber diese als "vertrauenswürdig" eingestuft haben!

    Wie geht es denn????? (Irgendwas mit Filewrite in einer DLL, aber wie kann ich dann Ports definieren, senden, empfangen, RTS setzten, DCD abfragen?)
    Lg Veronesi

  • Hallo Funkey,
    vielen Dank. Das sieht in der Tat sehr vielversprechend aus. Bloss kann ich damit kein RTS setzen und DCD abfragen.
    Dies ist für mich leider zwingend.
    Könnte man solche Funktionen noch einbauen?

  • Leider habe ich mit dieser UDF so meine Probleme.
    Ich habe ein serielles Programm (gekauft), mit welchem ich erfolgreich strings von COM3 nach COM4 und zurück senden kann.
    Nun möchte ich im ersten Schritt den COM3 von dieser UDF steuern. Also schliesse ich den COM3 mit dem externen Programm, damit er nicht mehr belegt ist und sende von diesen kurzen Script unten.
    Jedoch kommt nie irgendetwas an.

    Spoiler anzeigen
    [autoit]

    #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.
    #ce
    #include-once
    Global $commDll
    Global $hSerialPort
    Global $dcb_Struct
    Global $commtimeout
    Global $commtimeout_Struct
    Global $commState
    Global $commState_Struct
    ;Global $rxbuf
    Global Const $STX=chr(2)
    Global Const $ETX=chr(3)
    Global Const $EOT=chr(4)
    Global Const $ENQ=chr(5)
    Global Const $ACK=chr(6)
    Const $NAK=chr(15)
    Const $DLE=chr(16)

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

    $Return = _OpenComm(3, 9600)
    If $Return = -1 Then MsgBox(0,"Fehler", "Der COM-Port konnte nicht geöffnet werden!")

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

    _Tx(3, "Hallo")

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

    Sleep(2000)

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

    _CloseComm(3)

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

    ;====================================================================================
    ; Function Name: _OpenComm($CommPort, $CommBaud, $CommBits, $CommParity, $CommStop, $CommCtrl)
    ; Description: Opens serial port
    ; Parameters: $CommPort
    ; $CommBits - 4-8
    ; $CommParity - 0=none, 1=odd, 2=even, 3=mark, 4=space
    ; $CommStop - 0,1,5,2
    ; $CommCtrl = 0011
    ; Returns: on success, returns serial port id?
    ; on failure returns -1 and sets @error to 1
    ; Note:
    ;====================================================================================
    Func _OpenComm($CommPort, $CommBaud = '4800', $CommBits = '8', $CommParity = '0', $CommStop = '0', $CommCtrl = '0011', $DEBUG = '0')
    $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"

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

    local $commtimeouts="long ReadIntervalTimeout;long ReadTotalTimeoutMultiplier;" & _
    "long ReadTotalTimeoutConstant;long WriteTotalTimeoutMultiplier;long WriteTotalTimeoutConstant"

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

    local const $GENERIC_READ_WRITE=0xC0000000
    local const $OPEN_EXISTING=3
    local const $FILE_ATTRIBUTE_NORMAL =0x80
    local const $NOPARITY=0
    local const $ONESTOPBIT=0

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

    $dcb_Struct=DllStructCreate($dcbs)
    if @error Then errpr()

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

    $commtimeout_Struct=DllStructCreate($commtimeouts)
    if @error Then errpr()

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

    $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 errpr()
    If number($hserialport[0])<1 Then
    If $DEBUG = 1 Then consolewrite("Open Error" & @CRLF)
    return (-1)
    EndIf
    $commState=dllcall($commDll,"long","GetCommState","hwnd",$hSerialPort[0],"ptr",DllStructGetPtr($dcb_Struct))
    if @error Then errpr()
    DllStructSetData( $dcb_Struct,"DCBLength",DllStructGetSize($dcb_Struct))
    if @error Then errpr()
    DllStructSetData( $dcb_Struct,"BaudRate",$CommBaud)
    if @error Then errpr()
    DllStructSetData( $dcb_Struct,"Bytesize",$CommBits)
    if @error Then errpr()
    DllStructSetData( $dcb_Struct,"fBitfields",number('0x' & $CommCtrl))
    if @error Then errpr()
    DllStructSetData( $dcb_Struct,"Parity",$CommParity)
    if @error Then errpr()
    DllStructSetData( $dcb_Struct,"StopBits",'0x' & $CommStop)
    if @error Then errpr()
    DllStructSetData( $dcb_Struct,"XonLim",2048)
    if @error Then errpr()
    DllStructSetData( $dcb_Struct,"XoffLim",512)
    if @error Then errpr()
    $commState=dllcall($commDll,"short","SetCommState","hwnd",$hSerialPort[0],"ptr",DllStructGetPtr($dcb_Struct))
    if @error Then errpr()
    If $DEBUG = 1 Then consolewrite("CommState: "& $commstate[0] & @CRLF)
    if $commstate[0]=0 Then
    If $DEBUG = 1 Then consolewrite("SetCommState Error" & @CRLF)
    return (-1)
    EndIf
    DllStructSetData( $commtimeout_Struct,"ReadIntervalTimeout",-1)
    $commtimeout=dllcall($commDll,"long","SetCommTimeouts","hwnd",$hSerialPort[0],"ptr",DllStructGetPtr($commtimeout_Struct))
    if @error Then errpr()
    return number($hSerialPort[0])
    EndFunc

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

    ;====================================================================================
    ; Function Name: _CloseComm($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 _CloseComm($CommSerialPort, $DEBUG = 0)
    local $closeerr=DllCall($commDll, "int", "CloseHandle", "hwnd", $CommSerialPort)
    if @error Then
    errpr()
    Exit
    EndIf
    If $DEBUG = 1 Then ConsoleWrite("Close " & $closeerr[0] & @crlf)
    return($closeerr[0])
    EndFunc

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

    Func _tx($CommSerialPort, $t, $DEBUG = 0)
    if $DEBUG=1 then FileWriteLine("debug.txt","Send " &c2s($t))
    local $lptr0=dllstructcreate("long_ptr")
    local $tbuf=$t
    local $txr=dllcall($commDll,"int","WriteFile","hwnd",$CommSerialPort, _
    "str",$tbuf, _
    "int",stringlen($tbuf), _
    "long_ptr", DllStructGetPtr($lptr0), _
    "ptr", 0)
    if @error Then errpr()
    EndFunc

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

    ;====================================================================================
    ; Function Name: _rxwait($CommSerialPort, $MinBufferSize, $MaxWaitTime, $DEBUG = 0)
    ; Description: Recieves data
    ; Parameters: $CommSerialPort - value returned by _OpenComm
    ; $MinBufferSize - Buffer size to wait for
    ; $MaxWaitTime - Maximum time to wait before failing
    ; $DEBUG - Show debug messages
    ; Returns: on success, returns 1
    ; on failure returns -1 and sets @error to 1
    ; Note:
    ;====================================================================================
    Func _rxwait($CommSerialPort, $MinBufferSize, $MaxWaitTime, $DEBUG = 0)
    if $DEBUG=1 then ConsoleWrite("Wait " & $MinBufferSize & " " & $MaxWaitTime & @CRLF)
    Local $rxbuf
    local $jetza=TimerInit()
    local $lptr0=dllstructcreate("long_ptr")

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

    local $rxr, $rxl, $to
    Do
    $rxr=dllcall($commDll,"int","ReadFile","hwnd",$CommSerialPort, _
    "str"," ", _
    "int",1, _
    "long_ptr", DllStructGetPtr($lptr0), _
    "ptr", 0)
    if @error Then errpr()
    $rxl=DllStructGetData($lptr0,1)
    if $DEBUG=1 then ConsoleWrite("R0:" & $rxr[0] & " |R1:" & $rxr[1] & " |R2:" & $rxr[2] & " |rxl:" & $rxl & " |R4:" & $rxr[4] & @CRLF)
    if $rxl>=1 then
    $rxbuf&=$rxr[2]
    EndIf
    $to=TimerDiff($jetza)
    Until stringlen($rxbuf) >= $MinBufferSize OR $to > $MaxWaitTime
    Return($rxbuf)
    EndFunc

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

    Func _rx($rxbuf, $n=0, $DEBUG = 0)
    local $r
    if StringLen($rxbuf)<$n then
    $rxbuf=""
    Return("")
    EndIf
    If $n=0 Then
    $r=$rxbuf
    $rxbuf=""
    Return($r)
    EndIf
    If $n<0 then
    $rxbuf=""
    Return("")
    EndIf
    $r=Stringleft($rxbuf,$n)
    local $rl=Stringlen($rxbuf)
    $rxbuf=StringRight($rxbuf,$rl-$n)
    if $DEBUG=1 then FileWriteLine("debug.txt","Read " & c2s($r))
    return($r)
    EndFunc

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

    Func c2s($t)
    local $tc
    local $ts=""
    For $ii= 1 To StringLen($t)
    $tc=StringMid($t,$ii,1)
    if Asc($tc)<32 Then
    $ts&="<" & asc($tc) & ">"
    Else
    $ts&=$tc
    EndIf
    Next
    return $ts
    EndFunc

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

    func errpr()
    consolewrite ("Error " & @error & @CRLF)
    EndFunc

    [/autoit]

    Das ist übrigens die aktuellste UDF in dem genannten Link!

  • Ok. Ich bin gerade auf den wohl ältesten Fehler reingefallen:
    Beim _TX muss natürlich nicht die Portnummer rein, sondern der Rückgabewert der _OpenComm Funktion!

    Nun funktioniert das Senden und auch das Empfangen. Doch wie kann ich damit RTS setzen und zurücksetzen??

  • Also, ich habe nun die UDF etwas umformatiert, damit sie auch etwas besser aussieht, vollständig dokumentiert ist und keine überflüssigen Einträge (Funktionen / Variablen) mehr enthält.
    Senden und empfangen funktioniert tadellos, sowohl mit realen, als auch mit USB-zu-Serial Adaptern.

    Einzig folgendes: Wie kann ich das RTS setzen / rücksetzen und auf der anderen Seite den DCD Status abfragen?
    Hier die UDF:

    Spoiler anzeigen
    [autoit]

    #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
    #ce
    #include-once
    Global $commDll
    Global $hSerialPort
    Global $dcb_Struct
    Global $commtimeout
    Global $commtimeout_Struct
    Global $commState
    ;~ Global $commState_Struct
    ;~ Global Const $STX = Chr(2)
    ;~ Global Const $ETX = Chr(3)
    ;~ Global Const $EOT = Chr(4)
    ;~ Global Const $ENQ = Chr(5)
    ;~ Global Const $ACK = Chr(6)
    ;~ Const $NAK = Chr(15)
    ;~ Const $DLE = Chr(16)

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

    Local $SendPort = _OpenCOMPort(3, 9600, 8, 0, 0)
    If $SendPort = -1 Then MsgBox(0, "Fehler", "Der sendende COM-Port konnte nicht geöffnet werden!")
    $ReceivePort = _OpenCOMPort(4, 9600, 8, 0, 0)
    If $ReceivePort = -1 Then MsgBox(0, "Fehler", "Der empfangende COM-Port konnte nicht geöffnet werden!")

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

    _SendSerialString($SendPort, "This is a Teststring")
    MsgBox(0, "Empfangen", _ReceiveStringWait($ReceivePort, 20, 50))

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

    _CloseCOMPort($SendPort)
    _CloseCOMPort($ReceivePort)

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

    ;====================================================================================
    ; Function Name: _OpenCOMPort($CommPort, $CommBaud, $CommBits, $CommParity, $CommStop, $CommCtrl)
    ; Description: Opens serial port
    ; Parameters: $CommPort
    ; $CommBits - 4-8
    ; $CommParity - 0=none, 1=odd, 2=even, 3=mark, 4=space
    ; $CommStop - 0,1,5,2
    ; $CommCtrl = 0011
    ; Returns: on success, returns serial port id?
    ; on failure returns -1 and sets @error to 1
    ; Note:
    ;====================================================================================
    Func _OpenCOMPort($CommPort, $CommBaud = '9600', $CommBits = '8', $CommParity = '0', $CommStop = '0', $CommCtrl = '0011')
    $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"

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

    Local $commtimeouts = "long ReadIntervalTimeout;long ReadTotalTimeoutMultiplier;" & _
    "long ReadTotalTimeoutConstant;long WriteTotalTimeoutMultiplier;long WriteTotalTimeoutConstant"

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

    Local Const $GENERIC_READ_WRITE = 0xC0000000
    Local Const $OPEN_EXISTING = 3
    Local Const $FILE_ATTRIBUTE_NORMAL = 0x80
    ;~ Local Const $NOPARITY = 0
    ;~ Local Const $ONESTOPBIT = 0

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

    $dcb_Struct = DllStructCreate($dcbs)
    If @error Then Return SetError(1, 1, -1)

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

    $commtimeout_Struct = DllStructCreate($commtimeouts)
    If @error Then Return SetError(1, 1, -1)

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

    $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))
    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('0x' & $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)

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

    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

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

    ;====================================================================================
    ; 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)
    If @error Then Return SetError(1, 1, -1)
    Return ($closeerr[0])
    EndFunc ;==>_CloseCOMPort

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

    ;====================================================================================
    ; 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

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

    ;====================================================================================
    ; 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 1
    ; 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")

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

    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

    [/autoit]
  • Du wirst es nicht glauben, aber genau das habe ich auch gedacht! Und diese Seite habe ich auch schon gesucht, aber noch nicht gefunden!
    Danke!
    Ich werde es mal versuchen zu ändern!

  • Hallo veronesi,
    endlich hab ich mal was gefunden dass mir evtl auch weiter hilft.

    Ich habe hier eine RS232 8 Fach Relaiskarte von Conrad, und will diese über AutoIt ansteuern

    Vieleicht hast du lust mir dabei ein bisschen unter die Arme zu greifen!

    Gruß Rene

  • Hallo Rene,
    im Moment bin ich leider ziemlich im Stress sorry. Aber Mit dieser UDF sollte das Ansteuern der seriellen (!) Schnittstelle kein Problem mehr sein.
    Einfach die Handshake Leitungen (RTS....) können (noch) nicht gesetzt und abgefragt werden.

    Die Befehle sind in der UDF Dokumentiert. Bei Fragen fragen ;)

  • Mit diesen Änderungen ist es nun möglich (beim öffnen des Ports) den RTS Status zu setzen.
    Leider ist es mir nicht gelungen

    • Eine eigene Funktion zu schreiben, mit welcher einfach RTS gesetzt und rückgesetzt werden kann. (Unabhängig der Port öffnen Funktion! Natürlich muss der Port dazu offen sein!)

    • Eine Funktion zu schreiben welche das DCD Bit abfragt und zurück gibt.


    Da ich momentan leider keine Zeit mehr für dies habe, wäre ich froh, wenn mir jemand ein paar Tipps dafür geben könnte, damit ich die UDF noch ganz fertig machen kann.

    Spoiler anzeigen
    [autoit]

    #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
    #ce
    #include-once
    Global $commDll
    Global $hSerialPort
    Global $dcb_Struct
    Global $commtimeout
    Global $commtimeout_Struct
    Global $commState
    ;~ Global $commState_Struct
    ;~ Global Const $STX = Chr(2)
    ;~ Global Const $ETX = Chr(3)
    ;~ Global Const $EOT = Chr(4)
    ;~ Global Const $ENQ = Chr(5)
    ;~ Global Const $ACK = Chr(6)
    ;~ Const $NAK = Chr(15)
    ;~ Const $DLE = Chr(16)

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

    Local $SendPort = _OpenCOMPort(3, 9600, 8, 0, 0, 1)
    If $SendPort = -1 Then MsgBox(0, "Fehler", "Der sendende COM-Port konnte nicht geöffnet werden!")
    ;~ $ReceivePort = _OpenCOMPort(4, 9600, 8, 0, 0)
    ;~ If $ReceivePort = -1 Then MsgBox(0, "Fehler", "Der empfangende COM-Port konnte nicht geöffnet werden!")

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

    _SendSerialString($SendPort, "This is a Teststring")
    ;~ MsgBox(0, "Empfangen", _ReceiveStringWait($ReceivePort, 20, 50))
    Sleep(2000)

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

    _CloseCOMPort($SendPort)
    ;~ _CloseCOMPort($ReceivePort)

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

    ;====================================================================================
    ; Function Name: _OpenCOMPort($CommPort, $CommBaud, $CommBits, $CommParity, $CommStop, $SetRTS)
    ; Description: Opens serial port
    ; Parameters: $CommPort
    ; $CommBits - 4-8
    ; $CommParity - 0=none, 1=odd, 2=even, 3=mark, 4=space
    ; $CommStop - 0,1,5,2
    ; $SetRTS - 1 = Set it / 0 = Don't set it
    ; Returns: on success, returns serial port id?
    ; on failure returns -1 and sets @error to 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/…4(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 $CommCtrl = 0x1
    If $SetRTS = 1 Then $CommCtrl = BitOR($CommCtrl, 0x1001)
    $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"

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

    Local $commtimeouts = "long ReadIntervalTimeout;long ReadTotalTimeoutMultiplier;" & _
    "long ReadTotalTimeoutConstant;long WriteTotalTimeoutMultiplier;long WriteTotalTimeoutConstant"

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

    Local Const $GENERIC_READ_WRITE = 0xC0000000
    Local Const $OPEN_EXISTING = 3
    Local Const $FILE_ATTRIBUTE_NORMAL = 0x80
    ;~ Local Const $NOPARITY = 0
    ;~ Local Const $ONESTOPBIT = 0

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

    $dcb_Struct = DllStructCreate($dcbs)
    If @error Then Return SetError(1, 1, -1)

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

    $commtimeout_Struct = DllStructCreate($commtimeouts)
    If @error Then Return SetError(1, 1, -1)

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

    $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))
    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)

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

    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

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

    ;====================================================================================
    ; 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

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

    ;====================================================================================
    ; 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

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

    ;====================================================================================
    ; 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 1
    ; 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")

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

    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

    [/autoit]

    Vielen Dank!
    Veronesi

  • ich habe es mit der udf probiert, bekomme aber nicht einen schaltvorgang zu stande
    soll eigentlich ganz eifach sein, nach angabe von conrad
    es soll ein kommandorahmen folgender maßen gesendet werden
    er besteht aus 4 Byte
    Byte1= Befehl
    Byte2= Adr der Karte
    Byte3= Daten(0-255)
    Byte4= Cecksumme
    Byte4= Byte1 XOR Byte2 XOR Byte3

    aber ich bekomme es nicht hin

    als erstes muss ich den init string senden
    1,1,1,1
    danach den jeweiligen befehl

    3,0,1,2 für Relais 1 AN
    3,0,3,0 für Relais 2 AN

  • Hast Du es mal mit so etwas versucht:

    [autoit]

    #include "Func_Serial.au3"

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

    ;Alle Konstanten müssen angepasst werden!
    ;Gemäss Spezifikationen der Karte!
    Global Const $ComPort = 3
    Global Const $Baudrate = 9600
    Global Const $Bits = 8
    Global Const $Parity = 0
    Global Const $Stop = 0
    Global Const $Rts = 0

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

    Global Const $Byte1 = 0x01
    Global Const $Byte2 = 0x02
    Global Const $Byte3 = 0xFF
    Global Const $Byte4 = BitXOR($Byte1, $Byte2, $Byte3)

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

    Local $SendPort = _OpenCOMPort($ComPort, $Baudrate, $Bits, $Parity, $Stop, $Rts)
    If $SendPort = -1 Then MsgBox(0, "Fehler", "Der sendende COM-Port konnte nicht geöffnet werden!")

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

    _SendSerialString($SendPort, String($Byte1 & $Byte2 & $Byte3 & $Byte4))
    Sleep(100)
    _CloseCOMPort($SendPort)

    [/autoit]

    Dazu natürlich diese UDF:

    Spoiler anzeigen
    [autoit]

    #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
    #ce
    #include-once
    Global $commDll
    Global $hSerialPort
    Global $dcb_Struct
    Global $commtimeout
    Global $commtimeout_Struct
    Global $commState
    ;~ Global $commState_Struct
    ;~ Global Const $STX = Chr(2)
    ;~ Global Const $ETX = Chr(3)
    ;~ Global Const $EOT = Chr(4)
    ;~ Global Const $ENQ = Chr(5)
    ;~ Global Const $ACK = Chr(6)
    ;~ Const $NAK = Chr(15)
    ;~ Const $DLE = Chr(16)

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

    ;====================================================================================
    ; Function Name: _OpenCOMPort($CommPort, $CommBaud, $CommBits, $CommParity, $CommStop, $SetRTS)
    ; Description: Opens serial port
    ; Parameters: $CommPort
    ; $CommBits - 4-8
    ; $CommParity - 0=none, 1=odd, 2=even, 3=mark, 4=space
    ; $CommStop - 0,1,5,2
    ; $SetRTS - 1 = Set it / 0 = Don't set it
    ; Returns: on success, returns serial port id?
    ; on failure returns -1 and sets @error to 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/…4(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 $CommCtrl = 0x1
    If $SetRTS = 1 Then $CommCtrl = BitOR($CommCtrl, 0x1001)
    $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"

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

    Local $commtimeouts = "long ReadIntervalTimeout;long ReadTotalTimeoutMultiplier;" & _
    "long ReadTotalTimeoutConstant;long WriteTotalTimeoutMultiplier;long WriteTotalTimeoutConstant"

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

    Local Const $GENERIC_READ_WRITE = 0xC0000000
    Local Const $OPEN_EXISTING = 3
    Local Const $FILE_ATTRIBUTE_NORMAL = 0x80
    ;~ Local Const $NOPARITY = 0
    ;~ Local Const $ONESTOPBIT = 0

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

    $dcb_Struct = DllStructCreate($dcbs)
    If @error Then Return SetError(1, 1, -1)

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

    $commtimeout_Struct = DllStructCreate($commtimeouts)
    If @error Then Return SetError(1, 1, -1)

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

    $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))
    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)

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

    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

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

    ;====================================================================================
    ; 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

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

    ;====================================================================================
    ; 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

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

    ;====================================================================================
    ; 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 1
    ; 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")

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

    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

    [/autoit]

  • Es geht schon "ganz ohne", aber eben nicht nativ über COM ...


    Gruß
    Greenhorn

    Doch arbeite auf assamblerebene mit dem Treiber :D

    Okey sag nochmal kurz was jetz noch das Problem ist?