• Hi @ all !

    Ich hab hier ein kleines Paket Zusammengeschnürt um Via AutoIt das Modbus Protokoll zu verwenden. Und somit unzählige Hardware Anzusprechen.

    Enthalten sind:

    meine UDF

    Spoiler anzeigen
    [autoit]


    #include-Once
    ; #INDEX# =======================================================================================================================
    ; Title .........: libmodbus
    ; AutoIt Version : 3.2.10++
    ; Language ......: English/German
    ; Description ...: Functions for Handling the http://libmodbus.org/ dll
    ; the "_nativ" Funktions Handels the ModbusTCP ONLY VIA AutoIT !! -> you need no modbus.dll for those Funktions
    ; Author(s) .....: vivus ( Marc Neininger ), funkey,
    ; The libmodbus documentation was written by Stéphane Raimbault <[email='stephane.raimbault@gmail.com'][/email]>
    ; ===============================================================================================================================

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

    ; #CURRENT# =====================================================================================================================
    ;>"_native" ( dll not needed )
    ;_native_ModbusTCP_ReadImputRegister($mainsocket, $iStart, $iNum, $sType)
    ;_native_ModbusTCP_ReadCoils($mainsocket, $iStartAddress, $iNumOfCoils)
    ;_native_ModbusTCP_WriteCoils($mainsocket, $Port_adress , $Hi_Lo)
    ;_native_ModbusTCP_WriteSingleRegister($mainsocket, $iStartAddress, $iNumOfCoils)

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

    ;----------------------------------------------------
    ;>"_Madbus" ( libmodbus.dll from libmodbus.org needed )
    ;_Modbus_SetDllPath($sFullPath)
    ;_Modbus_DllOpen()
    ;_Modbus_New_TCP($sIP, $iPort = 502)
    ;_Modbus_Connect($tModbus)
    ;_Modbus_Close($tModbus)
    ;_Modbus_Free($tModbus)
    ;_Modbus_StrError($iError)
    ;_Modbus_Read_Registers($tModbus, $iAddr, $iNum)
    ;_Modbus_Read_Input_Registers($tModbus, $iAddr, $iNum)
    ;_Modbus_Read_Input_Bits($tModbus, $iAddr, $iNum = 1)
    ;_Modbus_Read_Bits($tModbus, $iAddr, $iNum = 1 ) ( offiziell Read Coil )
    ;_Modbus_Write_Bit($tModbus, $iAddr, $status )
    ;_Modbus_Write_Register($tModbus, $iAddr, $Value)
    ;_Modbus_Write_Bits($tModbus, $iAddr, $iNum) ( write many bits / Multible Coil )
    ;_Modbus_Set_Debug($tModbus, $boolean)
    ; ===============================================================================================================================

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

    ; #INTERNAL_USE_ONLY# ===========================================================================================================
    ;>"_native" ( dll not needed )
    ;__Convert_To_Binary($iNumber)
    ;__WinAPI_Int64ToDouble($iInt64)
    ;__ModbusTCP_Recv($mainsocket, $maxlen = 256, $flag = 0)
    ;__ModbusTCP_Send($mainsocket, $data)
    ;----------------------------------------------------
    ;
    ; ===============================================================================================================================

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

    #include <Array.au3>
    #include <WinAPI.au3>

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

    Const $_sUDFVersion = 'V1.0'
    ;Global $_mgdebug = False

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

    ;###################################################################################################################################
    ;###################################################################################################################################
    ;###################################################################################################################################
    ;###################################################################################################################################
    ;###################################################################################################################################
    ;>"_nativ" ( dll not needed )
    Global $_native_ModbusTCP_Debug_Send = 0 ; if = 1 you can see the modbus send-Protokoll on CMD-line ( only _native )
    Global $_native_ModbusTCP_Debug_Recv = 0 ; if = 1 you can see the modbus recv-Protokoll on CMD-line ( only _native )
    Global $__TID=0 ; ONLY INTERNAL USE !! contains the transmission ID of the last _native_Modbus CALL !!

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

    ; #Simple-Sample# for >"_nativ" ModbusTCP( dll not needed ) ========================================================================
    #cs

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

    Func _example_nativ()
    MsgBox(0, "_example_native()", "Example modbusTCP only via Autoit")
    TCPStartup()

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

    $_native_ModbusTCP_Debug_Send = 1
    $_native_ModbusTCP_Debug_Recv = 1

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

    Global $iSock = TCPConnect("172.18.65.159", 502)

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

    If $iSock = -1 Then
    ConsoleWrite("Fehler Verbindungsaufbau" & @LF)
    Exit
    EndIf

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

    $repeat = 5

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

    While $repeat >= 1

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

    ConsoleWrite("write" & @CRLF)
    $retval = _native_ModbusTCP_WriteCoils($iSock, 1, 1) ;
    ConsoleWrite("$retval =" & $retval & @CRLF)

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

    Sleep(100)
    ConsoleWrite("clear" & @CRLF)
    $retval = _native_ModbusTCP_WriteCoils($iSock, 1, 0)
    ConsoleWrite("$retval =" & $retval & @CRLF)

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

    ; oder
    $retval = _native_ModbusTCP_WriteSingleRegister($iSock, 0, 0)
    ConsoleWrite("$retval =" & $retval & @CRLF)

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

    $aTest = _native_ModbusTCP_ReadImputRegister($iSock, 0, 4, "float") ;Functioncode 4, Register 1, Länge 4 Resiter lesen, als float zurückgeben
    ConsoleWrite("float = " & $aTest[0] & @CRLF)
    $aTest = _native_ModbusTCP_ReadImputRegister($iSock, 0, 1, "word") ;Functioncode 4, Register 1, Länge 4 Resiter lesen, als float zurückgeben
    ConsoleWrite("word = " & $aTest[0] & @CRLF)
    _ArrayDisplay($aTest)

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

    Global $iRet = _native_ModbusTCP_ReadCoils($iSock, 0, 8);16)
    ConsoleWrite("Bits = " & $iRet & @CRLF)

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

    $repeat = $repeat - 1

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

    WEnd

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

    TCPCloseSocket($iSock)
    TCPShutdown()

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

    EndFunc ;==>_example_nativ
    #ce
    ; ===============================================================================================================================

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

    Func _native_ModbusTCP_ReadImputRegister($mainsocket, $iStart, $iNum, $sType)

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

    $__TID += 1

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

    Local $iBytesToSend = 6
    Local $FC = "04"

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

    __ModbusTCP_Send($mainsocket, "0x" & Hex($__TID, 4) & "0000" & Hex($iBytesToSend, 4) & "01" & Hex($FC, 2) & Hex($iStart, 4) & Hex($iNum, 4))
    If @error Then Return SetError(1, 0, 0)

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

    Local $sRecv

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

    Do
    $sRecv = __ModbusTCP_Recv($mainsocket, 512)

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

    Until @error Or $sRecv <> ""
    If @error Then Return SetError(2, 0, 0)

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

    If Int(String(BinaryMid($sRecv, 1, 2))) <> $__TID Then Return SetError(3, 0, 0)

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

    ;ConsoleWrite("$sRecv"&$sRecv&@CRLF)

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

    Local $iSize = 4 ; default

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

    Switch $sType
    Case "word"
    $iSize = 2
    Case "float"
    $iSize = 4
    Case "double"
    $iSize = 8
    EndSwitch

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

    Local $aRet[$iNum / ($iSize / 2)], $iTemp

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

    For $i = 0 To UBound($aRet) - 1
    $iTemp = BinaryMid($sRecv, 10 + $i * $iSize, $iSize)
    Switch $sType
    Case "word"
    $aRet[$i] = Int(String($iTemp))
    Case "float"
    $aRet[$i] = _WinAPI_IntToFloat(Int(String($iTemp)))
    Case "double"
    $aRet[$i] = __WinAPI_Int64ToDouble(Int(String($iTemp)))
    EndSwitch
    Next
    Return $aRet
    EndFunc ;==>_ModbusTCP_ReadValues

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

    Func _native_ModbusTCP_ReadCoils($mainsocket, $iStartAddress, $iNumOfCoils)

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

    $__TID += 1

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

    Local $iBytesToSend = 6, $iFunctionCode = "02"

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

    If $iNumOfCoils < 1 Then Return SetError(1, 0, 0)

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

    __ModbusTCP_Send($mainsocket, "0x" & Hex($__TID, 4) & "0000" & Hex($iBytesToSend, 4) & "01" & $iFunctionCode & Hex($iStartAddress, 4) & Hex($iNumOfCoils, 4))
    If @error Then Return SetError(2, 0, 0)

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

    Local $sRecv

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

    Do
    $sRecv = __ModbusTCP_Recv($mainsocket, 512)
    Until @error Or $sRecv <> ""
    If @error Then Return SetError(3, 0, 0)

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

    If Int(String(BinaryMid($sRecv, 1, 2))) <> $__TID Then Return SetError(4, 0, 0)

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

    Local $iAnzahlBytes = Int(String(BinaryMid($sRecv, 9, 1)))

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

    ;ConsoleWrite("Anzahl der erhaltenen Daten: " & $iAnzahlBytes & " Byte(s), max " & $iAnzahlBytes * 8 & " Bits." & @CRLF)

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

    Return __Convert_To_Binary(Int(String(BinaryMid($sRecv, 10, $iAnzahlBytes))))
    EndFunc ;==>_ModbusTCP_ReadCoils

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

    ;--------------------------------------------------------------------------------------------------------------------------------------------------------------

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

    Func _native_ModbusTCP_WriteCoils($mainsocket, $Port_adress , $Hi_Lo)

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

    $__TID += 1

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

    Local $iBytesToSend = 6, $iFunctionCode = "05"

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

    If $Port_adress < 1 Then Return SetError(1, 0, 0)

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

    If $Hi_Lo = 1 then
    __ModbusTCP_Send($mainsocket, "0x" & Hex($__TID, 4) & "0000" & Hex($iBytesToSend, 4) & "01" & $iFunctionCode & Hex($Port_adress-1, 4) & "FF00"); 65280 = FF00

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

    ElseIf $Hi_Lo = 0 then
    __ModbusTCP_Send($mainsocket, "0x" & Hex($__TID, 4) & "0000" & Hex($iBytesToSend, 4) & "01" & $iFunctionCode & Hex($Port_adress-1, 4) & "0000")

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

    Else
    ;If $iNumOfCoils < 1 Then Return SetError(1, 0, 0)
    Return SetError(1, 0, 0)
    ;_ModbusTCP_Send($mainsocket, "0x" & Hex($__TID, 4) & "0000" & Hex($iBytesToSend, 4) & "01" & $iFunctionCode & Hex($iStartAddress, 4) & Hex($iNumOfCoils, 4))

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

    EndIf
    If @error Then Return SetError(2, 0, 0)

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

    Local $sRecv

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

    Do
    $sRecv = __ModbusTCP_Recv($mainsocket, 512)
    Until @error Or $sRecv <> ""
    If @error Then Return SetError(3, 0, 0)

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

    If Int(String(BinaryMid($sRecv, 1, 2))) <> $__TID Then Return SetError(4, 0, 0)

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

    ;Local $iAnzahlBytes = Int(String(BinaryMid($sRecv, 9, 1)))

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

    ;ConsoleWrite("Anzahl der erhaltenen Daten: " & $iAnzahlBytes & " Byte(s), max " & $iAnzahlBytes * 8 & " Bits." & @CRLF)

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

    Return 1 ;_Convert_To_Binary(Int(String(BinaryMid($sRecv, 10, $iAnzahlBytes))))

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

    EndFunc ;==>_ModbusTCP_ReadCoils

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

    ;--------------------------------------------------------------------------------------------------------------------------------------------------

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

    Func _native_ModbusTCP_WriteSingleRegister($mainsocket, $iStartAddress, $iNumOfCoils)

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

    $__TID += 1

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

    Local $iBytesToSend = 6, $iFunctionCode = "06"

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

    If $iNumOfCoils < 0 Then
    Return SetError(1, 0, 0)
    EndIf

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

    __ModbusTCP_Send($mainsocket, "0x" & Hex($__TID, 4) & "0000" & Hex($iBytesToSend, 4) & "01" & $iFunctionCode & Hex($iStartAddress, 4) & Hex($iNumOfCoils, 4))
    If @error Then Return SetError(2, 0, 0)

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

    Local $sRecv

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

    Do
    $sRecv = __ModbusTCP_Recv($mainsocket, 512)
    Until @error Or $sRecv <> ""
    If @error Then Return SetError(3, 0, 0)

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

    If Int(String(BinaryMid($sRecv, 1, 2))) <> $__TID Then Return SetError(4, 0, 0)

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

    ;Local $iAnzahlBytes = Int(String(BinaryMid($sRecv, 9, 1)))

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

    ;ConsoleWrite("Anzahl der erhaltenen Daten: " & $iAnzahlBytes & " Byte(s), max " & $iAnzahlBytes * 8 & " Bits." & @CRLF)

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

    Return 1;_Convert_To_Binary(Int(String(BinaryMid($sRecv, 10, $iAnzahlBytes))))
    EndFunc ;==>_ModbusTCP_ReadCoils

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

    Func __ModbusTCP_Send($mainsocket, $data)
    If $_native_ModbusTCP_Debug_Send Then ConsoleWrite("_native_ModbusTCP_Send(" & $mainsocket & ", """ & $data & """)" & @CRLF)
    Local $Send = TCPSend($mainsocket, $data)
    Return SetError(@error, 0, $Send)
    EndFunc ;==>_ModbusTCP_Send

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

    Func __ModbusTCP_Recv($mainsocket, $maxlen = 256, $flag = 0)
    Local $sRecv = TCPRecv($mainsocket, $maxlen, $flag)
    Local $error = @error
    If $sRecv <> "" And $_native_ModbusTCP_Debug_Recv Then ConsoleWrite("_native_ModbusTCP_Recv: " & $sRecv & @CRLF)
    Return SetError($error, 0, $sRecv)
    EndFunc ;==>_ModbusTCP_Recv

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

    ; #FUNCTION# ====================================================================================================================
    ; Name...........: __WinAPI_Int64ToDouble
    ; Description ...: Returns a 8 byte integer as a double value
    ; Syntax.........: __WinAPI_IntToFloat($iInt64)
    ; Parameters ....: $iInt64 - 8 byte Integer value (64 bit)
    ; Return values .: Success - 8 byte integer value as a double
    ; Author ........: funkey
    ; Modified.......:
    ; Remarks .......:
    ; Related .......:
    ; Link ..........:
    ; Example .......: Yes
    ; ===============================================================================================================================
    Func __WinAPI_Int64ToDouble($iInt64)
    Local $__TIDnt64 = DllStructCreate("INT64")
    Local $tDouble = DllStructCreate("double", DllStructGetPtr($__TIDnt64))
    DllStructSetData($__TIDnt64, 1, $iInt64)
    Return DllStructGetData($tDouble, 1)
    EndFunc ;==>_WinAPI_Int64ToDouble

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

    Func __Convert_To_Binary($iNumber)
    Local $sBinString = ""
    Do
    $sBinString = BitAND($iNumber, 1) & $sBinString
    $iNumber = BitShift($iNumber, 1)
    Until $iNumber <= 0
    If $iNumber < 0 Then SetError(1, 0, 0)
    Return $sBinString
    EndFunc ;==>_Convert_To_Binary

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

    ; END -> ;>"_nativ" ( dll not needed )

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

    ;###################################################################################################################################
    ;###################################################################################################################################
    ;###################################################################################################################################
    ;###################################################################################################################################
    ;###################################################################################################################################
    ;>"_Madbus" ( libmodbus.dll from libmodbus.org needed )

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

    Global $hDLL_Modbus = 0
    Global $__DLLNAME = 'libModbus.dll'

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

    ; #Simple-Sample# for libmodbus.dll ================================================================================================
    #cs
    Func _example_libDll()
    MsgBox(0, "_example_libDll()", "Example with the libmodbus.dll")

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

    _Modbus_DllOpen()

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

    Global $tModbus = _Modbus_New_TCP("172.18.65.159")
    If _Modbus_Connect($tModbus) = -1 Then
    ConsoleWrite("! Fehler: Es konnte keine Verbindung aufgebaut werden." & @CRLF)
    _Modbus_Free($tModbus)
    Exit
    EndIf
    Global $aVal

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

    $aVal = _Modbus_Set_Debug($tModbus, 1)

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

    ;Global $aVal = _Modbus_Read_Registers($tModbus, 0, 1)
    ;Global $aVal = _Modbus_Read_Input_Registers($tModbus, 0, 1)
    ;Global $aVal = _Modbus_Read_Input_Bits($tModbus, 5)
    ;Global $aVal = _Modbus_Read_Bits($tModbus, 5)
    ;Global $aVal = _Modbus_Write_Bit($tModbus, 0, 1 )
    ;Global $aVal = _Modbus_Write_Register($tModbus, 0, 8 )

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

    $repeat = 5

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

    While $repeat >= 1

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

    $aVal = _Modbus_Write_Register($tModbus, 0, 1)
    ;_ArrayDisplay($aVal)
    ;MsgBox(0,"",$aVal)

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

    Sleep(100)
    $aVal = _Modbus_Write_Register($tModbus, 0, 0)
    ;_ArrayDisplay($aVal)
    ;MsgBox(0,"",$aVal)

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

    $aVal = _Modbus_Read_Registers($tModbus, 0, 1)
    _ArrayDisplay($aVal)
    ;MsgBox(0,"",$aVal)

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

    $repeat = $repeat - 1

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

    WEnd

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

    _Modbus_Close($tModbus)
    _Modbus_Free($tModbus)

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

    EndFunc ;==>_example_libDll
    #ce
    ; ===============================================================================================================================

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

    ;===============================================================================
    ; Function Name: _Modbus_SetDllPath($sFullPath)
    ; Description: Sets full path to th extdll so that it can be in any location.
    ; Parameters: $sFullPath - Full path to the libmodbus.dll e.g. "C:\libmodbus\libmodbus.dll"
    ; Returns; on success 1
    ; on error -1 if full path does not exist
    ;===============================================================================
    Func _Modbus_SetDllPath($sFullPath)
    If Not FileExists($sFullPath) Then Return -1

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

    $__DLLNAME = $sFullPath
    Return 1

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

    EndFunc ;==>_CommSetDllPath

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

    ;===============================================================================
    ; Function Name: _Modbus_DllOpen()
    ; Description: Start the Connection to the libmodbus dll
    ; Parameters:
    ; Returns; on success 1
    ; on error -1
    ;===============================================================================
    Func _Modbus_DllOpen()
    $hDLL_Modbus = DllOpen($__DLLNAME)
    If $hDLL_Modbus = -1 Then
    SetError(1)
    $sErr = 'Failed to open DLL'
    Return 0;failed
    EndIf

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

    return 1
    EndFunc

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

    ; #FUNCTION# ====================================================================================================================
    ; Name...........: _Modbus_New_TCP
    ; Description ...: The modbus_new_tcp() function shall allocate and initialize a modbus_t structure to communicate with a Modbus TCP/IPv4 server.
    ; Syntax.........: _Modbus_New_TCP($sIP, $iPort = 502)
    ; Parameters ....: The ip argument specifies the IP address of the server to which the client wants etablish a connection.
    ; The port argument is the TCP port to use. Set the port to MODBUS_TCP_DEFAULT_PORT to use the default one (502). It’s convenient to use a port number greater than or equal to 1024 because it’s not necessary to have administrator privileges.
    ; Return values .: The modbus_new_tcp() function shall return a pointer to a modbus_t structure if successful. Otherwise it shall return NULL and set errno to one of the values defined below.
    ; Failure EINVAL An invalid IP address was given.
    ; C-Syntax.......: modbus_t *modbus_new_tcp(const char *ip, int port);
    ; ===============================================================================================================================
    Func _Modbus_New_TCP($sIP, $iPort = 502)
    Local $aRet = DllCall($hDLL_Modbus, "ptr:cdecl", "modbus_new_tcp", "str", $sIP, "int", $iPort)
    Return $aRet[0]
    EndFunc ;==>_Modbus_New_TCP

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

    ; #FUNCTION# ====================================================================================================================
    ; Name...........: _Modbus_Connect
    ; Description ...: The modbus_connect() function shall etablish a connection to a Modbus server, a network or a bus using the context information of libmodbus context given in argument.
    ; Syntax.........: _Modbus_Connect($tModbus)
    ; Parameters ....: The $tModbus handle
    ; Return values .: The modbus_connect() function shall return 0 if successful. Otherwise it shall return -1 and set errno to one of the values defined by the system calls of the underlying platform.
    ; C-Syntax.......: int modbus_connect(modbus_t *ctx);
    ; ===============================================================================================================================
    Func _Modbus_Connect($tModbus)
    Local $aRet = DllCall($hDLL_Modbus, "int:cdecl", "modbus_connect", "ptr", $tModbus)
    Return $aRet[0]
    EndFunc ;==>_Modbus_Connect

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

    ; #FUNCTION# ====================================================================================================================
    ; Name...........: _Modbus_Close
    ; Description ...: The modbus_close() function shall close the connection established with the backend set in the context.
    ; Syntax.........: _Modbus_Close($tModbus)
    ; Parameters ....: The $tModbus handle
    ; Return values .: There is no return value.
    ; C-Syntax.......: void modbus_close(modbus_t *ctx);
    ; ===============================================================================================================================
    Func _Modbus_Close($tModbus)
    DllCall($hDLL_Modbus, "none:cdecl", "modbus_close", "ptr", $tModbus)
    EndFunc ;==>_Modbus_Close

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

    ; #FUNCTION# ====================================================================================================================
    ; Name...........: _Modbus_Free
    ; Description ...: The modbus_free() function shall free an allocated modbus_t structure.
    ; Syntax.........: _Modbus_Free($tModbus)
    ; Parameters ....: The $tModbus handle
    ; Return values .: There is no return value.
    ; C-Syntax.......: void modbus_free(modbus_t *ctx);
    ; ===============================================================================================================================
    Func _Modbus_Free($tModbus)
    DllCall($hDLL_Modbus, "none:cdecl", "modbus_free", "ptr", $tModbus)
    EndFunc ;==>_Modbus_Free

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

    ; #FUNCTION# ====================================================================================================================
    ; Name...........: _Modbus_StrError
    ; Description ...: The modbus_strerror() function shall return a pointer to an error message string corresponding to the error number specified by the errnum argument. As libmodbus defines additional error numbers over and above those defined by the
    ; operating system, applications should use modbus_strerror() in preference to the standard strerror() function.
    ; Syntax.........: _Modbus_StrError($iError)
    ; Parameters ....: the Error number
    ; Return values .: The modbus_strerror() function shall return a pointer to an error message string.
    ; C-Syntax.......: const char *modbus_strerror(*int errnum);
    ; ===============================================================================================================================
    Func _Modbus_StrError($iError)
    Local $aRet = DllCall($hDLL_Modbus, "str:cdecl", "modbus_strerror", "int", $iError)
    Return $aRet[0]
    EndFunc ;==>_Modbus_StrError

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

    ; #FUNCTION# ====================================================================================================================
    ; Name...........: _Modbus_Read_Registers
    ; Description ...: The modbus_read_registers() function shall read the content of the nb holding registers to the address addr of the remote device. The result of reading is stored in dest array as word values (16 bits).
    ; You must take care to allocate enough memory to store the results in dest (at least nb * sizeof(uint16_t)).
    ; The function uses the Modbus function code 0x03 (read holding registers).
    ; Syntax.........: _Modbus_Read_Registers($tModbus, $iAddr, $iNum)
    ; Parameters ....: nb holding registers
    ; addr of the remote device
    ; Return values .: The modbus_read_registers() function shall return the number of read registers if successful. Otherwise it shall return -1 and set errno.
    ; C-Syntax.......: int modbus_read_registers(modbus_t *ctx, int addr, int nb, uint16_t *dest);
    ; ===============================================================================================================================
    Func _Modbus_Read_Registers($tModbus, $iAddr, $iNum)
    Local $tBuffer = DllStructCreate("WORD[" & $iNum & "]")
    Local $aRet = DllCall($hDLL_Modbus, "int:cdecl", "modbus_read_registers", "ptr", $tModbus, "int", $iAddr, "int", $iNum, "struct*", $tBuffer)

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

    Local $aRes[$iNum]
    For $i = 0 To $iNum - 1
    $aRes[$i] = DllStructGetData($tBuffer, 1, $i + 1)
    Next
    Return $aRes
    EndFunc ;==>_Modbus_Read_Registers

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

    ; #FUNCTION# ====================================================================================================================
    ; Name...........: _Modbus_Read_Input_Registers
    ; Description ...: The modbus_read_input_registers() function shall read the content of the nb input registers to address addr of the remote device. The result of the reading is stored in dest array as word values (16 bits).
    ; You must take care to allocate enough memory to store the results in dest (at least nb * sizeof(uint16_t)).
    ; The function uses the Modbus function code 0x04 (read input registers). The holding registers and input registers have different historical meaning, but nowadays it’s more common to use holding registers only.
    ; Syntax.........: _Modbus_Read_Input_Registers($tModbus, $iAddr, $iNum)
    ; Parameters ....: nb holding registers
    ; addr of the remote device
    ; Return values .: The modbus_read_input_registers() function shall return the number of read input registers if successful. Otherwise it shall return -1 and set errno.
    ; C-Syntax.......: int modbus_read_input_registers(modbus_t *ctx, int addr, int nb, uint16_t *dest);
    ; ===============================================================================================================================
    Func _Modbus_Read_Input_Registers($tModbus, $iAddr, $iNum)
    Local $tBuffer = DllStructCreate("WORD[" & $iNum & "]")
    Local $aRet = DllCall($hDLL_Modbus, "int:cdecl", "modbus_read_input_registers", "ptr", $tModbus, "int", $iAddr, "int", $iNum, "struct*", $tBuffer)

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

    Local $aRes[$iNum]
    For $i = 0 To $iNum - 1
    $aRes[$i] = DllStructGetData($tBuffer, 1, $i + 1)
    Next
    Return $aRes
    EndFunc ;==>_Modbus_Read_Input_Registers

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

    ; #FUNCTION# ====================================================================================================================
    ; Name...........: _Modbus_Read_Input_Bits
    ; Description ...: The modbus_read_input_bits() function shall read the content of the nb input bits to the address addr of the remote device. The result of reading is stored in dest array as unsigned bytes (8 bits) set to TRUE or FALSE.
    ; You must take care to allocate enough memory to store the results in dest (at least nb * sizeof(uint8_t)).
    ; The function uses the Modbus function code 0x02 (read input status).
    ; Syntax.........: _Modbus_Read_Input_Bits($tModbus, $iAddr, $iNum)
    ; Parameters ....: nb holding registers
    ; addr of the remote device
    ; Return values .: The modbus_read_input_status() function shall return the number of read input status if successful. Otherwise it shall return -1 and set errno.
    ; C-Syntax.......: int modbus_read_input_bits(modbus_t *ctx, int addr, int nb, uint8_t *dest);
    ; ===============================================================================================================================
    Func _Modbus_Read_Input_Bits($tModbus, $iAddr, $iNum = 1)
    Local $tBuffer = DllStructCreate("WORD[" & $iNum & "]")
    Local $aRet = DllCall($hDLL_Modbus, "int:cdecl", "modbus_read_input_bits", "ptr", $tModbus, "int", $iAddr, "int", $iNum, "struct*", $tBuffer)

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

    Local $aRes[$iNum]
    For $i = 0 To $iNum - 1
    $aRes[$i] = DllStructGetData($tBuffer, 1, $i + 1)
    Next

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

    If $iNum = 1 Then
    Return $aRes[0]
    Else
    Return $aRes
    EndIf
    EndFunc ;==>_Modbus_Read_Input_Bits

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

    ; #FUNCTION# ====================================================================================================================
    ; Name...........: _Modbus_Read_Bits ( offiziell Read Coil )
    ; Description ...: The modbus_read_bits() function shall read the status of the nb bits (coils) to the address addr of the remote device. The result of reading is stored in dest array as unsigned bytes (8 bits) set to TRUE or FALSE.
    ; You must take care to allocate enough memory to store the results in dest (at least nb * sizeof(uint8_t)).
    ; The function uses the Modbus function code 0x01 (read coil status).
    ; Syntax.........: _Modbus_Read_Bits($tModbus, $iAddr, $iNum = 1 )
    ; Parameters ....: nb holding registers
    ; addr of the remote device
    ; Return values .: The modbus_read_bits() function shall return the number of read bits if successful. Otherwise it shall return -1 and set errno.
    ; C-Syntax.......: int modbus_read_bits(modbus_t *ctx, int addr, int nb, uint8_t *dest);
    ; ===============================================================================================================================
    Func _Modbus_Read_Bits($tModbus, $iAddr, $iNum = 1)
    Local $tBuffer = DllStructCreate("WORD[" & $iNum & "]")
    Local $aRet = DllCall($hDLL_Modbus, "int:cdecl", "modbus_read_bits", "ptr", $tModbus, "int", $iAddr, "int", $iNum, "struct*", $tBuffer)

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

    Local $aRes[$iNum]
    For $i = 0 To $iNum - 1
    $aRes[$i] = DllStructGetData($tBuffer, 1, $i + 1)
    Next

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

    If $iNum = 1 Then
    Return $aRes[0]
    Else
    Return $aRes
    EndIf
    EndFunc ;==>_Modbus_Read_Bits

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

    ; #FUNCTION# ====================================================================================================================
    ; Name...........: _Modbus_Write_Bit ( write a single bit )
    ; Description ...: The modbus_write_bit() function shall write the status of status at the address addr of the remote device. The value must be set to TRUE or FALSE.
    ; The function uses the Modbus function code 0x05 (force single coil).
    ; Syntax.........: _Modbus_Write_Bit($tModbus, $iAddr, $status )
    ; Parameters ....: addr of the remote device
    ; $status - True False
    ; Return values .: The modbus_write_bit() function shall return 1 if successful. Otherwise it shall return -1 and set errno.
    ; C-Syntax.......: int modbus_write_bit(modbus_t *ctx, int addr, int status);
    ; ===============================================================================================================================
    Func _Modbus_Write_Bit($tModbus, $iAddr, $status)
    ;Local $tBuffer = DllStructCreate("WORD[" & $iNum & "]")
    Local $aRet = DllCall($hDLL_Modbus, "int:cdecl", "modbus_write_bit", "ptr", $tModbus, "int", $iAddr, "int", $status);, "struct*", $tBuffer)

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

    If (UBound($aRet)) >= 4 Then
    If $aRet[3] = $status Then
    Return 1
    Else
    Return -1
    EndIf
    EndIf
    Return -1

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

    EndFunc ;==>_Modbus_Write_Bit

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

    ; #FUNCTION# ====================================================================================================================
    ; Name...........: _Modbus_Write_Register ( write a single register )
    ; Description ...: The modbus_write_register() function shall write the value of value holding registers at the address addr of the remote device.
    ; The function uses the Modbus function code 0x06 (preset single register).
    ; Syntax.........: _Modbus_Write_Register($tModbus, $iAddr, $Value)
    ; Parameters ....: addr of the remote device
    ; $status - True False
    ; Return values .: The modbus_write_register() function shall return 1 if successful. Otherwise it shall return -1 and set errno.
    ; C-Syntax.......: int modbus_write_register(modbus_t *ctx, int addr, int value);
    ; ===============================================================================================================================
    Func _Modbus_Write_Register($tModbus, $iAddr, $Value)

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

    Local $aRet = DllCall($hDLL_Modbus, "int:cdecl", "modbus_write_register", "ptr", $tModbus, "int", $iAddr, "int", $Value)

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

    If (UBound($aRet)) >= 4 Then
    If $aRet[3] = $Value Then
    Return 1
    Else
    Return -1
    EndIf
    EndIf

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

    Return -1

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

    EndFunc ;==>_Modbus_Write_Register

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

    ; #FUNCTION# ====================================================================================================================
    ; Name...........: _Modbus_Set_Debug ( set debug flag of the context)
    ; Description ...: The modbus_set_debug() function shall set the debug flag of the modbus_t context by using the argument boolean. When the boolean value is set to TRUE, many verbose messages are displayed on stdout and stderr. For example, this
    ; flag is useful to display the bytes of the Modbus messages.
    ; [00][14][00][00][00][06][12][03][00][6B][00][03]
    ; Waiting for a confirmation…
    ; <00><14><00><00><00><09><12><03><06><02><2B><00><00><00><00>
    ; Syntax.........: _Modbus_Set_Debug($tModbus, $boolean)
    ; Parameters ....: When the boolean value is set to TRUE many verbose messages are displayed on stdout and stderr
    ;
    ; Return values .: There is no return values.
    ; C-Syntax.......: void modbus_set_debug(modbus_t *ctx, int boolean);
    ; ===============================================================================================================================
    Func _Modbus_Set_Debug($tModbus, $boolean)

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

    Local $aRet = DllCall($hDLL_Modbus, "int:cdecl", "modbus_set_debug", "ptr", $tModbus, "int", $boolean)

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

    Return $aRet

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

    EndFunc ;==>_Modbus_Write_Register

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

    #cs
    ; #FUNCTION# ====================================================================================================================
    ; Name...........: _Modbus_Write_Bits ( write many bits / Multible Coil )
    ; Description ...: The modbus_write_bits() function shall write the status of the nb bits (coils) from src at the address addr of the remote device. The src array must contains bytes set to TRUE or FALSE.
    ; The function uses the Modbus function code 0x0F (force multiple coils).
    ; Syntax.........: _Modbus_Write_Bits($tModbus, $iAddr, $iNum)
    ; Parameters ....: addr of the remote device
    ; status of the nb bits (coils)
    ; src - quelle
    ; Return values .: The modbus_write_bits() function shall return the number of written bits if successful. Otherwise it shall return -1 and set errno.
    ; C-Syntax.......: int modbus_write_bits(modbus_t *ctx, int addr, int nb, const uint8_t *src);
    ; ===============================================================================================================================
    Func _Modbus_Write_Bits($tModbus, $iAddr, $iNum)
    Local $tBuffer = DllStructCreate("WORD[" & $iNum & "]")
    Local $aRet = DllCall($hDLL_Modbus, "int:cdecl", "modbus_read_registers", "ptr", $tModbus, "int", $iAddr, "int", $iNum, "struct*", $tBuffer)

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

    Local $aRes[$iNum]
    For $i = 0 To $iNum - 1
    $aRes[$i] = DllStructGetData($tBuffer, 1, $i + 1)
    Next
    Return $aRes
    EndFunc ;==>_Modbus_Read_Registers
    #ce

    [/autoit]

    das Simple_Sample

    Spoiler anzeigen
    [autoit]


    #cs ----------------------------------------------------------------------------

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

    AutoIt Version: 3.3.8.1
    Author: myName

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

    Script Function:
    Template AutoIt script.

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

    #ce ----------------------------------------------------------------------------

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

    #include <modbus.au3>

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

    HotKeySet("{ESC}", "Terminate")

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

    _example_nativ()
    _example_libDll()

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

    MsgBox(0, "EXIT", "End of Sample")

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

    Exit

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

    ;--------------------------------------------------------------------------------------

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

    Func _example_nativ()
    MsgBox(0, "_example_native()", "Example modbusTCP only via Autoit")
    TCPStartup()

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

    $_native_ModbusTCP_Debug_Send = 1
    $_native_ModbusTCP_Debug_Recv = 1

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

    Global $iSock = TCPConnect("172.18.65.159", 502)

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

    If $iSock = -1 Then
    ConsoleWrite("Fehler Verbindungsaufbau" & @LF)
    Exit
    EndIf

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

    $repeat = 5

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

    While $repeat >= 1

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

    ConsoleWrite("write" & @CRLF)
    $retval = _native_ModbusTCP_WriteCoils($iSock, 1, 1) ;
    ConsoleWrite("$retval =" & $retval & @CRLF)

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

    Sleep(100)
    ConsoleWrite("clear" & @CRLF)
    $retval = _native_ModbusTCP_WriteCoils($iSock, 1, 0)
    ConsoleWrite("$retval =" & $retval & @CRLF)

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

    ; oder
    $retval = _native_ModbusTCP_WriteSingleRegister($iSock, 0, 0)
    ConsoleWrite("$retval =" & $retval & @CRLF)

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

    $aTest = _native_ModbusTCP_ReadImputRegister($iSock, 0, 4, "float") ;Functioncode 4, Register 1, Länge 4 Resiter lesen, als float zurückgeben
    ConsoleWrite("float = " & $aTest[0] & @CRLF)
    $aTest = _native_ModbusTCP_ReadImputRegister($iSock, 0, 1, "word") ;Functioncode 4, Register 1, Länge 4 Resiter lesen, als float zurückgeben
    ConsoleWrite("word = " & $aTest[0] & @CRLF)
    _ArrayDisplay($aTest)

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

    Global $iRet = _native_ModbusTCP_ReadCoils($iSock, 0, 8);16)
    ConsoleWrite("Bits = " & $iRet & @CRLF)

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

    $repeat = $repeat - 1

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

    WEnd

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

    TCPCloseSocket($iSock)
    TCPShutdown()

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

    EndFunc ;==>_example_nativ

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

    ;--------------------------------------------------------------------------------------------------

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

    Func _example_libDll()
    MsgBox(0, "_example_libDll()", "Example with the libmodbus.dll")

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

    _Modbus_DllOpen()

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

    Global $tModbus = _Modbus_New_TCP("172.18.65.159")
    If _Modbus_Connect($tModbus) = -1 Then
    ConsoleWrite("! Fehler: Es konnte keine Verbindung aufgebaut werden." & @CRLF)
    _Modbus_Free($tModbus)
    Exit
    EndIf
    Global $aVal

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

    $aVal = _Modbus_Set_Debug($tModbus, 1)

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

    ;Global $aVal = _Modbus_Read_Registers($tModbus, 0, 1)
    ;Global $aVal = _Modbus_Read_Input_Registers($tModbus, 0, 1)
    ;Global $aVal = _Modbus_Read_Input_Bits($tModbus, 5)
    ;Global $aVal = _Modbus_Read_Bits($tModbus, 5)
    ;Global $aVal = _Modbus_Write_Bit($tModbus, 0, 1 )
    ;Global $aVal = _Modbus_Write_Register($tModbus, 0, 8 )

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

    $repeat = 5

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

    While $repeat >= 1

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

    $aVal = _Modbus_Write_Register($tModbus, 0, 1)
    ;_ArrayDisplay($aVal)
    ;MsgBox(0,"",$aVal)

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

    Sleep(100)
    $aVal = _Modbus_Write_Register($tModbus, 0, 0)
    ;_ArrayDisplay($aVal)
    ;MsgBox(0,"",$aVal)

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

    $aVal = _Modbus_Read_Registers($tModbus, 0, 1)
    _ArrayDisplay($aVal)
    ;MsgBox(0,"",$aVal)

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

    $repeat = $repeat - 1

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

    WEnd

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

    _Modbus_Close($tModbus)
    _Modbus_Free($tModbus)

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

    EndFunc ;==>_example_libDll

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

    Func Terminate()
    Exit 0
    EndFunc ;==>Terminate

    [/autoit]

    die einfache Visualisierung welche für die kleinste Konfiguration einer Wago 750-341 mit Di Modul 750-430 und Do Modul 750-530 läuft.

    Spoiler anzeigen
    [autoit]


    #include<modbus.au3>
    #include<DEC_HEX_BIN.au3>

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

    #include <ButtonConstants.au3>
    #include <EditConstants.au3>
    #include <GUIConstantsEx.au3>
    #include <StaticConstants.au3>
    #include <WindowsConstants.au3>
    #region ### START Koda GUI section ### Form=c:\users\marc.neininger\desktop\form1.kxf
    $Form1_1 = GUICreate("Wago Visualisierung", 461, 447, 263, 224)
    ;$Label1 = GUICtrlCreateLabel("Wago Visualisierung", 0, 0, 128, 20)
    $Group1 = GUICtrlCreateGroup("DI", 168, 24, 137, 409)
    $DIB_00 = GUICtrlCreateCheckbox("DIB_00", 176, 48, 97, 17)
    GUICtrlSetState(-1, $GUI_DISABLE)
    $DIB_01 = GUICtrlCreateCheckbox("DIB_01", 176, 72, 97, 17)
    GUICtrlSetState(-1, $GUI_DISABLE)
    $DIB_02 = GUICtrlCreateCheckbox("DIB_02", 176, 96, 97, 17)
    GUICtrlSetState(-1, $GUI_DISABLE)
    $DIB_03 = GUICtrlCreateCheckbox("DIB_03", 176, 120, 97, 17)
    GUICtrlSetState(-1, $GUI_DISABLE)
    $DIB_04 = GUICtrlCreateCheckbox("DIB_04", 176, 144, 97, 17)
    GUICtrlSetState(-1, $GUI_DISABLE)
    $DIB_05 = GUICtrlCreateCheckbox("DIB_05", 176, 168, 97, 17)
    GUICtrlSetState(-1, $GUI_DISABLE)
    $DIB_06 = GUICtrlCreateCheckbox("DIB_06", 176, 192, 97, 17)
    GUICtrlSetState(-1, $GUI_DISABLE)
    $DIB_07 = GUICtrlCreateCheckbox("DIB_07", 176, 216, 97, 17)
    GUICtrlSetState(-1, $GUI_DISABLE)
    $DIB_08 = GUICtrlCreateCheckbox("DIB_08", 176, 240, 97, 17)
    GUICtrlSetState(-1, $GUI_DISABLE)
    $DIB_09 = GUICtrlCreateCheckbox("DIB_09", 176, 264, 97, 17)
    GUICtrlSetState(-1, $GUI_DISABLE)
    $DIB_10 = GUICtrlCreateCheckbox("DIB_10", 176, 288, 97, 17)
    GUICtrlSetState(-1, $GUI_DISABLE)
    $DIB_11 = GUICtrlCreateCheckbox("DIB_11", 176, 312, 97, 17)
    GUICtrlSetState(-1, $GUI_DISABLE)
    $DIB_12 = GUICtrlCreateCheckbox("DIB_12", 176, 336, 97, 17)
    GUICtrlSetState(-1, $GUI_DISABLE)
    $DIB_13 = GUICtrlCreateCheckbox("DIB_13", 176, 360, 97, 17)
    GUICtrlSetState(-1, $GUI_DISABLE)
    $DIB_14 = GUICtrlCreateCheckbox("DIB_14", 176, 384, 97, 17)
    GUICtrlSetState(-1, $GUI_DISABLE)
    $DIB_15 = GUICtrlCreateCheckbox("DIB_15", 176, 408, 97, 17)
    GUICtrlSetState(-1, $GUI_DISABLE)
    GUICtrlCreateGroup("", -99, -99, 1, 1)
    $Group3 = GUICtrlCreateGroup("Settings", 8, 24, 153, 409)
    $Label2 = GUICtrlCreateLabel("IP-Wago", 24, 48, 57, 20)
    $Imp_IP = GUICtrlCreateInput("172.18.65.159", 24, 72, 121, 24)
    $connect = GUICtrlCreateButton("connect", 24, 360, 123, 25)
    $dissconnect = GUICtrlCreateButton("dissconnect", 24, 400, 123, 25)
    $Label3 = GUICtrlCreateLabel("DI-Adress", 24, 176, 64, 20)
    $DI_Adress = GUICtrlCreateInput("00", 24, 200, 121, 24)
    $Label4 = GUICtrlCreateLabel("DO-Adress", 24, 240, 71, 20)
    $DO_Adress = GUICtrlCreateInput("00", 24, 264, 121, 24)
    $Label5 = GUICtrlCreateLabel("Pool-Time", 24, 112, 67, 20)
    $Pool_time = GUICtrlCreateInput("50", 24, 136, 121, 24)
    $Group2 = GUICtrlCreateGroup("DO", 311, 25, 137, 409)
    $DOB_00 = GUICtrlCreateCheckbox("DOB_00", 319, 49, 97, 17)
    $DOB_01 = GUICtrlCreateCheckbox("DOB_01", 319, 73, 97, 17)
    $DOB_02 = GUICtrlCreateCheckbox("DOB_02", 319, 97, 97, 17)
    $DOB_03 = GUICtrlCreateCheckbox("DOB_03", 319, 121, 97, 17)
    $DOB_04 = GUICtrlCreateCheckbox("DOB_04", 319, 145, 97, 17)
    $DOB_05 = GUICtrlCreateCheckbox("DOB_05", 319, 169, 97, 17)
    $DOB_06 = GUICtrlCreateCheckbox("DOB_06", 319, 193, 97, 17)
    $DOB_07 = GUICtrlCreateCheckbox("DOB_07", 319, 217, 97, 17)
    $DOB_08 = GUICtrlCreateCheckbox("DOB_08", 319, 241, 97, 17)
    $DOB_09 = GUICtrlCreateCheckbox("DOB_09", 319, 265, 97, 17)
    $DOB_10 = GUICtrlCreateCheckbox("DOB_10", 319, 289, 97, 17)
    $DOB_11 = GUICtrlCreateCheckbox("DOB_11", 319, 313, 97, 17)
    $DOB_12 = GUICtrlCreateCheckbox("DOB_12", 319, 337, 97, 17)
    $DOB_13 = GUICtrlCreateCheckbox("DOB_13", 319, 361, 97, 17)
    $DOB_14 = GUICtrlCreateCheckbox("DOB_14", 319, 385, 97, 17)
    $DOB_15 = GUICtrlCreateCheckbox("DOB_15", 319, 409, 97, 17)
    GUICtrlCreateGroup("", -99, -99, 1, 1)
    _DO($GUI_DISABLE)
    GUISetState(@SW_SHOW)
    #endregion ### END Koda GUI section ###

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

    ;----------------------------------------------------------------
    _Modbus_DllOpen()

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

    ;$Gui_Name_String = "$DIB_00|$DIB_01|$DIB_02|$DIB_03|$DIB_04|$DIB_05|$DIB_06|$DIB_07|$DIB_08|$DIB_09|$DIB_10|$DIB_11|$DIB_12|$DIB_13|$DIB_14|$DIB_15|$DIB_16|$DIB_17"
    ;Global $GUI_DI_Handler = StringSplit($Gui_Name_String, "|")

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

    Dim $GUI_DI_Handler[18]
    $GUI_DI_Handler[0] = $DIB_00
    $GUI_DI_Handler[1] = $DIB_01
    $GUI_DI_Handler[2] = $DIB_02
    $GUI_DI_Handler[3] = $DIB_03
    $GUI_DI_Handler[4] = $DIB_04
    $GUI_DI_Handler[5] = $DIB_05
    $GUI_DI_Handler[6] = $DIB_06
    $GUI_DI_Handler[7] = $DIB_07
    $GUI_DI_Handler[8] = $DIB_08
    $GUI_DI_Handler[9] = $DIB_09
    $GUI_DI_Handler[10] = $DIB_10
    $GUI_DI_Handler[11] = $DIB_11
    $GUI_DI_Handler[12] = $DIB_12
    $GUI_DI_Handler[13] = $DIB_13
    $GUI_DI_Handler[14] = $DIB_14
    $GUI_DI_Handler[15] = $DIB_15
    $GUI_DI_Handler[16] = ""

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

    Global $Wago_Connected = False

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

    While 1

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

    $nMsg = GUIGetMsg()
    Switch $nMsg
    Case $GUI_EVENT_CLOSE
    Exit

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

    Case $connect
    GUICtrlSetState($connect, $GUI_DISABLE) ; the label is in disable state
    GUICtrlSetState($Imp_IP, $GUI_DISABLE) ; the label is in disable state
    $IP = GUICtrlRead($Imp_IP)

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

    Global $tModbus = _Modbus_New_TCP($IP)
    If _Modbus_Connect($tModbus) = -1 Then
    ConsoleWrite("! Fehler: Es konnte keine Verbindung aufgebaut werden." & @CRLF)
    _Modbus_Free($tModbus)
    GUICtrlSetState($connect, $GUI_ENABLE) ; the label is in disable state
    ;Exit
    EndIf
    Global $aVal

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

    $aVal = _Modbus_Set_Debug($tModbus, 1)
    $aVal = _Modbus_Write_Register($tModbus, 0, 0 )

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

    _DO($GUI_ENABLE)

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

    $Wago_Connected = True

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

    Case $dissconnect
    $Wago_Connected = False
    _DO($GUI_DISABLE)
    GUICtrlSetState($connect, $GUI_ENABLE) ; the label is in disable state
    GUICtrlSetState($Imp_IP, $GUI_ENABLE) ; the label is in disable state
    _Modbus_Close($tModbus)
    _Modbus_Free($tModbus)
    Case $DOB_00
    _DO_chance($DOB_00, 0)
    Case $DOB_01
    _DO_chance($DOB_01, 1)
    Case $DOB_02
    _DO_chance($DOB_02, 2)
    Case $DOB_03
    _DO_chance($DOB_03, 3)
    Case $DOB_04
    _DO_chance($DOB_04, 4)
    Case $DOB_05
    _DO_chance($DOB_05, 5)
    Case $DOB_06
    _DO_chance($DOB_06, 6)
    Case $DOB_07
    _DO_chance($DOB_07, 7)
    Case $DOB_08
    _DO_chance($DOB_08, 8)
    Case $DOB_09
    _DO_chance($DOB_09, 9)
    Case $DOB_10
    _DO_chance($DOB_10, 10)
    Case $DOB_11
    _DO_chance($DOB_11, 11)
    Case $DOB_12
    _DO_chance($DOB_12, 12)
    Case $DOB_13
    _DO_chance($DOB_13, 13)
    Case $DOB_14
    _DO_chance($DOB_14, 14)
    Case $DOB_15
    _DO_chance($DOB_15, 15)
    EndSwitch

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

    If $Wago_Connected Then
    $aVal = _Modbus_Read_Input_Registers($tModbus, GUICtrlRead($DI_Adress), 1)
    ; das Register als Binary
    $inBinary = _DecToBinary($aVal[0])
    _DI_Change($inBinary)

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

    EndIf

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

    Sleep( GUICtrlRead($Pool_time))
    WEnd

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

    Func _DI_Change($Binary)

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

    Dim $DIArray[17]
    ;die bits dem array übergeben
    For $i = 0 To BinaryLen($Binary) Step 1
    $DIArray[$i] = StringMid($Binary, StringLen($Binary) - $i, 1)
    Next

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

    ; mit 0en füllen
    For $i = 0 To (UBound($DIArray) - 1) Step 1
    If Not (($DIArray[$i] = "1") Or ($DIArray[$i] = "0")) Then
    $DIArray[$i] = 0
    EndIf

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

    Next

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

    ; den Gui State in das array übertragen
    For $i = 0 To (UBound($DIArray) - 1) Step 1
    If ($DIArray[$i] = "1") Then
    $DIArray[$i] = $GUI_CHECKED
    Else
    $DIArray[$i] = $GUI_UNCHECKED
    EndIf

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

    Next

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

    ;_ArrayDisplay($DIArray)
    ;_ArrayDisplay($GUI_DI_Handler)

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

    ; die GUI aktualisieren
    For $i = 0 To (UBound($DIArray) - 1) Step 1
    GUICtrlSetState($GUI_DI_Handler[$i], $DIArray[$i])
    Next

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

    EndFunc

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

    Func _DO_chance($Conrole_ID, $Bit)
    $Bit = $Bit + GUICtrlRead($DO_Adress)
    $state = GUICtrlRead($Conrole_ID)
    If $state = 1 Then
    _Modbus_Write_Bit($tModbus, $Bit, 1)
    Else
    _Modbus_Write_Bit($tModbus, $Bit, 0)
    EndIf

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

    EndFunc ;==>_DO_chance

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

    Func _DO($Status)
    GUICtrlSetState($DOB_00, $Status)
    GUICtrlSetState($DOB_01, $Status)
    GUICtrlSetState($DOB_02, $Status)
    GUICtrlSetState($DOB_03, $Status)
    GUICtrlSetState($DOB_04, $Status)
    GUICtrlSetState($DOB_05, $Status)
    GUICtrlSetState($DOB_06, $Status)
    GUICtrlSetState($DOB_07, $Status)
    GUICtrlSetState($DOB_08, $Status)
    GUICtrlSetState($DOB_09, $Status)
    GUICtrlSetState($DOB_10, $Status)
    GUICtrlSetState($DOB_11, $Status)
    GUICtrlSetState($DOB_12, $Status)
    GUICtrlSetState($DOB_13, $Status)
    GUICtrlSetState($DOB_14, $Status)
    GUICtrlSetState($DOB_15, $Status)

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

    EndFunc ;==>_DO

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

    Func _example_libDll()

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

    ;Global $aVal = _Modbus_Read_Registers($tModbus, 0, 1)
    ;Global $aVal = _Modbus_Read_Input_Registers($tModbus, 0, 1)
    ;Global $aVal = _Modbus_Read_Input_Bits($tModbus, 5)
    ;Global $aVal = _Modbus_Read_Bits($tModbus, 5)
    ;Global $aVal = _Modbus_Write_Bit($tModbus, 0, 1 )
    ;Global $aVal = _Modbus_Write_Register($tModbus, 0, 8 )

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

    EndFunc ;==>_example_libDll

    [/autoit]

    die Modbus.udf läuft entweder über die im Netz verfügbare libmodbus.dll von libmodbus.org

    Oder "Native" nur über den TCP-Stack von Autoit ( allerdings nur ein paar wichtige Grundfunktionen )

    Da die libmodbus noch viel Funktionen beinhaltet, die ich so noch nie verwendet habe, sind nicht alle umgesetzt.
    Diese Funktionen finden sich im "doc_offen" Ordner im Zip File.

    Fragen / Änderungen / Wünsche sind gerne gesehen.

    Viel Spaß damit !!

  • Ich hab deinen Thread gelesen im SPS-Forum und hab mich dann hierhin durchgeklickt ;)
    Hab mir dann mal dein Beispielskript angesehen.
    So wäre es ein wenig sinnvoller, wenn schon Array, dann richtig.

    Spoiler anzeigen
    [autoit]

    #include <modbus.au3>
    #include <DEC_HEX_BIN.au3>

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

    #include <ButtonConstants.au3>
    #include <EditConstants.au3>
    #include <GUIConstantsEx.au3>
    #include <StaticConstants.au3>
    #include <WindowsConstants.au3>

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

    Global $GUI_DI_Handler[16], $GUI_DO_Handler[16]
    Global $Wago_Connected = False

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

    $Form1_1 = GUICreate("Wago Visualisierung", 461, 447, 263, 224)
    ;$Label1 = GUICtrlCreateLabel("Wago Visualisierung", 0, 0, 128, 20)
    $Group1 = GUICtrlCreateGroup("DI", 168, 24, 137, 409)
    For $i = 0 To 15
    $GUI_DI_Handler[$i] = GUICtrlCreateCheckbox("DIB_" & StringFormat("%02u", $i), 176, 48 + ($i * 24), 97, 17)
    GUICtrlSetState(-1, $GUI_DISABLE)
    Next
    GUICtrlCreateGroup("", -99, -99, 1, 1)
    $Group3 = GUICtrlCreateGroup("Settings", 8, 24, 153, 409)
    $Label2 = GUICtrlCreateLabel("IP-Wago", 24, 48, 57, 20)
    $Imp_IP = GUICtrlCreateInput("172.18.65.159", 24, 72, 121, 24)
    $connect = GUICtrlCreateButton("connect", 24, 360, 123, 25)
    $dissconnect = GUICtrlCreateButton("dissconnect", 24, 400, 123, 25)
    $Label3 = GUICtrlCreateLabel("DI-Adress", 24, 176, 64, 20)
    $DI_Adress = GUICtrlCreateInput("00", 24, 200, 121, 24)
    $Label4 = GUICtrlCreateLabel("DO-Adress", 24, 240, 71, 20)
    $DO_Adress = GUICtrlCreateInput("00", 24, 264, 121, 24)
    $Label5 = GUICtrlCreateLabel("Pool-Time", 24, 112, 67, 20)
    $Pool_time = GUICtrlCreateInput("50", 24, 136, 121, 24)
    $Group2 = GUICtrlCreateGroup("DO", 311, 25, 137, 409)
    For $i = 0 To 15
    $GUI_DO_Handler[$i] = GUICtrlCreateCheckbox("DOB_" & StringFormat("%02u", $i), 319, 48 + ($i * 24), 97, 17)
    Next
    GUICtrlCreateGroup("", -99, -99, 1, 1)
    _DO($GUI_DISABLE)
    GUISetState()

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

    ;----------------------------------------------------------------
    _Modbus_DllOpen()

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

    ;$Gui_Name_String = "$DIB_00|$DIB_01|$DIB_02|$DIB_03|$DIB_04|$DIB_05|$DIB_06|$DIB_07|$DIB_08|$DIB_09|$DIB_10|$DIB_11|$DIB_12|$DIB_13|$DIB_14|$DIB_15|$DIB_16|$DIB_17"
    ;Global $GUI_DI_Handler = StringSplit($Gui_Name_String, "|")

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

    While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
    Case $GUI_EVENT_CLOSE
    Exit
    Case $connect
    GUICtrlSetState($connect, $GUI_DISABLE) ; the label is in disable state
    GUICtrlSetState($Imp_IP, $GUI_DISABLE) ; the label is in disable state
    $IP = GUICtrlRead($Imp_IP)

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

    Global $tModbus = _Modbus_New_TCP($IP)
    If _Modbus_Connect($tModbus) = -1 Then
    ConsoleWrite("! Fehler: Es konnte keine Verbindung aufgebaut werden." & @CRLF)
    _Modbus_Free($tModbus)
    GUICtrlSetState($connect, $GUI_ENABLE) ; the label is in disable state
    ;Exit
    EndIf
    Global $aVal

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

    $aVal = _Modbus_Set_Debug($tModbus, 1)
    $aVal = _Modbus_Write_Register($tModbus, 0, 0 )

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

    _DO($GUI_ENABLE)

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

    $Wago_Connected = True
    Case $dissconnect
    $Wago_Connected = False
    _DO($GUI_DISABLE)
    GUICtrlSetState($connect, $GUI_ENABLE) ; the label is in disable state
    GUICtrlSetState($Imp_IP, $GUI_ENABLE) ; the label is in disable state
    _Modbus_Close($tModbus)
    _Modbus_Free($tModbus)
    Case $GUI_DO_Handler[0] To $GUI_DO_Handler[15]
    _DO_Change($nMsg, $nMsg - $GUI_DO_Handler[0])
    EndSwitch

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

    If $Wago_Connected Then
    $aVal = _Modbus_Read_Input_Registers($tModbus, GUICtrlRead($DI_Adress), 1)
    ; das Register als Binary
    $inBinary = _DecToBinary($aVal[0])
    _DI_Change($inBinary)
    EndIf

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

    Sleep(GUICtrlRead($Pool_time))
    WEnd

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

    Func _DI_Change($Binary)
    Local $DIArray[17]
    ;die bits dem array übergeben
    For $i = 0 To BinaryLen($Binary)
    $DIArray[$i] = StringMid($Binary, StringLen($Binary) - $i, 1)
    Next

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

    ; mit 0en füllen
    For $i = 0 To UBound($DIArray) - 1
    If Not ($DIArray[$i] = "1" Or $DIArray[$i] = "0") Then $DIArray[$i] = "0"
    Next

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

    ; den Gui State in das array übertragen
    For $i = 0 To UBound($DIArray) - 1
    If $DIArray[$i] = "1" Then
    $DIArray[$i] = $GUI_CHECKED
    Else
    $DIArray[$i] = $GUI_UNCHECKED
    EndIf

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

    Next

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

    ;_ArrayDisplay($DIArray)
    ;_ArrayDisplay($GUI_DI_Handler)

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

    ; die GUI aktualisieren
    For $i = 0 To UBound($DIArray) - 1
    GUICtrlSetState($GUI_DI_Handler[$i], $DIArray[$i])
    Next
    EndFunc

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

    Func _DO_Change($Conrole_ID, $Bit)
    $Bit += Int(GUICtrlRead($DO_Adress))
    $state = GUICtrlRead($Conrole_ID)
    If $state = 1 Then
    _Modbus_Write_Bit($tModbus, $Bit, 1)
    Else
    _Modbus_Write_Bit($tModbus, $Bit, 0)
    EndIf
    EndFunc ;==>_DO_Change

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

    Func _DO($Status)
    For $i = 0 To 15
    GUICtrlSetState($GUI_DO_Handler[$i], $Status)
    Next
    EndFunc ;==>_DO

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

    Func _example_libDll()

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

    ;Global $aVal = _Modbus_Read_Registers($tModbus, 0, 1)
    ;Global $aVal = _Modbus_Read_Input_Registers($tModbus, 0, 1)
    ;Global $aVal = _Modbus_Read_Input_Bits($tModbus, 5)
    ;Global $aVal = _Modbus_Read_Bits($tModbus, 5)
    ;Global $aVal = _Modbus_Write_Bit($tModbus, 0, 1 )
    ;Global $aVal = _Modbus_Write_Register($tModbus, 0, 8 )

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

    EndFunc ;==>_example_libDll

    [/autoit]


    Und Checkboxen am besten immer mit BitAND und $GUI_CKECKED abfragen. Nicht nur einfach mit GuiCtrlRead.

    Ansonsten sehr schön und weiter so.

  • Ich hab deinen Thread gelesen im SPS-Forum und hab mich dann hierhin durchgeklickt ;)

    Und Checkboxen am besten immer mit BitAND und $GUI_CKECKED abfragen. Nicht nur einfach mit GuiCtrlRead.

    Ansonsten sehr schön und weiter so.


    Erläutere er es näher ! :D

    -

  • Eigentlich sagt es schon der Absatz in der Hilfe von GuiCtrlRead unter Bemerkungen.

    Code
    Bei Checkboxen und Radiobuttons können mehrere Statuse als $GUI_FOCUS und $GUI_CHECKED zurückgegeben werden. So ist z. B. BitAnd(GUICtrlRead($Item),$GUI_CHECKED) zu verwenden um zu sehen ob ein Control markiert ist.
  • 8) ich bekenne mich schuldig .. 8|

    war eher mit der Richtigkeit des UDF's beschäftigt, als mit der Visualisierung. :rolleyes:

    wenn ich das mit dem Schrittmotor implementiert habe ( in die UDF ) wird eine ansprechendere Visualisierung incl. deiner Verbesserungen folgen ..

    lust mit zu helfen ?

  • Ich kann gerne mithelfen. Bin auch gerade dabei ein Visu zu machen mit eigenen Buttons und Grafiken. Hab auch drangedacht die Funktion der Buttons so zu machen wie es auch ein Taster bzw. Schalter macht. Also beim Drücken eine 1 und beim Loslassen wieder 0. Die normalen Buttons reagieren ja nur beim loslassen.

    Willst du auch Serverfunktionen mitreinnehmen in die UDF?

  • Serverfunktionen ?

    Das Script / UDF ist doch der Server im Modbus .. oder meinst du jetzt was anderes ?

    d.h. du brauchst nur einen Feldbuskoppler ( ich habe hierzu den WAGO 750-341 verwendet ) und das Autoit "Programm".

    sonst keine Andere Software mehr. Du Steuerst mit der UDF direkt die IO's des Feldbuskopplers an.

    ..

  • Ich kann dazu auch meine SPS nehmen ;), muss ja nicht unbedingt von Wago sein. Über Modbus habe ich mit der auch schon kommuniziert. Mit Hilfe von AutoIt natürlich. Der Server ist dabei die SPS, oder wie in deinem Fall der Koppler. Das Script ist der Client. Aber um Sachen zu testen, wäre es mal schön den Server zu stellen und dann mit der SPS darauf zuzugreifen.

  • wäre dann der PC(die Software) nicht der client ? ... wenn du mit der SPS darauf zugreifen willst ?

    wäre natürlich auch ne geile Sache .. dann wäre das Thema mit dem Realtime auch gegessen ..

    für die Zeitkritischen sachen oder Sicherheitsrelevanten Abläufe könnte man die SPS nehmen ... und für die Visu das Script ..

    mmm .. hab ich habe leider nicht die Hardware um das zu testen .. aber können wir ja im Hinterkopf behalten !! wäre n Geiles Feature ...

  • Wenn ich mit dem PC auf die SPS zugreifen möchte, ist der PC der Client. So wie du es jetzt hast. Der Server stellt ja die Register bereit.
    Das Codesys Zeugs brauchst du eigentlich garnicht.
    Ich hab momentan den Fall das eine SPS von Phoenix auf eine SPS von Sick zugreifen soll über Modbus und die Register lesen bzw. schreiben soll.
    Dabei ist die SPS von Sick der Server, weil er stellt ja die Daten bereit, und die SPS von Phoenix ist der Client.
    Nun ist es so, dass ich die Seite mache der Phoenix SPS, Auf der Sick-Seite läuft ja alles. Da ist der Server in der Firmware hinterlegt. Nun hab ich aber (noch) nicht die Sick SPS, möchte ich aber gerne testen. Somit wollte ich mir dann einen Server in AutoIt basteln, der den Server der Sick SPS simuliert, also die Register bereistellt. Bis jetzt hatte ich immer die Hardwares da, aber nun dauert das Paket ein wenig länger.

  • mmm .. seltsam .. das habe ich anderst gelernt. ?(

    und zwar so : ...
    es gibt immer nur einen Server(Master) im System, welcher das "Programm" steuert.
    alles andere sind die Client(Salve) Systeme.

    also wäre bei mir die IO-Hardware egal in welcher Anzahl und welcher Hersteller der Client(Slave).
    Weil der Client ja ohne Server nix macht.( gar nix machen kann, weil er ja "dumm" ist.)

    und der Server wäre hier das Autoit Programm .. weil diese den Programmteil abarbeitet / Steuert.

    aber ist ja auch wurst .. wie wir das definieren ich weis jetzt was du jetzt willst.
    Du willst mit einem Modbus-Master auf Register zugreifen, welche der PC als Slave bereitstellt. ;)

    müsste doch gehen .. mit meinem "nativ" Code teil.

    Dort poole ich den TCP-Port bis wieder eine Antwort auf meine Frage kommt.

    Das könntest du als "Slave" umbauen.

    eine POOL-schleife, welche auf ein bestimmten Modbus String-Wartet.

    und entsprechend wie du es wünscht darauf Antworten.

    ich hab leider keinen anderen Master vor Ort. ich guck mal, ob ich vielleicht nen Zweiten Rechner als Master Startklar bekomme.

    Jetzt muss ich aber erst mal das mit dem Steppercontroller hin bekommen ;)

  • Das ist wie bein einem NAS-Server an einem Router. Auf dem NAS-Server liegen verschiedene Daten (Filme, Musik, Bilder, ...). Wenn dein PC darauf zugreift und z.B. einen Film streamt, ist dein PC der Client (Slave). Und es können ja mehrere PCs darauf zugreifen. Aber es gibt immer nur einen Server (Master).

    Genauso ist das mit deinem Koppler. Er stellt die Register bereit mit den Werten drin. Der Clint bekommt dann mit Hilfe von Anfragen die Werte aus den Registern des Servers.

  • Danke für's Beispiel.
    Bei Modbus TCP ist der Server ein Slave (reagiert nur auf Anfragen) und der Client ein Master (aktiv)
    der Client verbindet sich zum Server. Es kann auch mehrere Master geben!

  • vivus: Erst einmal Danke für dein spitzen ModBus-UDF! Allerdings habe ich noch zwei kleine Probleme, wo du mir, oder auch gerne ein anderer, ggf. helfen könntest.

    Ich habe einen Beckhoff Koppler BK9050 und einige Module zum Testen zu Verfügung. Der Koppler mit Digitalen IO's funktioniert grundsätzlich mit deiner UDF (mit DLL) schon sehr gut. Allerdings wenn ich einen Disconnect mache, dann geht der Koppler in Störung, die sich nur durch AEG (ausschalten, einschalten, geht) lösen lässt. Das passiert allerdings nur, wenn ich nach einem Connect einen Ausgang gesetzt hatte.

    Zudem schaffe ich es einfach nicht einen Analogausgang zu beschreiben. Eigentlich dachte ich, das ich dem WriteRegister lediglich eine andere Adresse mitgeben muß, aber das funktioniert so leider nicht.

    Vielen Dank schon mal für deine (eure) Hilfe!

    Gruß
    Homer J. S.

    ...wenn die Donuts auch nur halb so gut schmecken wie sie aussehen, dann sehen sie doppelt so gut aus wie sie schmecken...

  • Homer J. S.: vivus = Letzte Aktivität 6. Mai 2015, also kein Grund hier die Leichen auszugraben.

    Andy hat mir ein Schnitzel gebacken aber da war ein Raupi drauf und bevor Oscar das Bugfixen konnte kam Alina und gab mir ein AspirinJunkie.

  • Homer J. S.: vivus = Letzte Aktivität 6. Mai 2015, also kein Grund hier die Leichen auszugraben.


    @chip: Prinzipiell gebe ich dir ja recht, aber da es so ein spezielles Thema ist, wollte ich keinen neuen Thread erstellen. Zudem bekommt @vivus im Regelfall eine E-Mail Benachrichtigung, wenn sich was in diesem Thread tut. Was wäre den deiner Meinung nach der richtige Weg?

    Gruß
    Homer J. S.

    ...wenn die Donuts auch nur halb so gut schmecken wie sie aussehen, dann sehen sie doppelt so gut aus wie sie schmecken...

  • Zudem bekommt @vivus im Regelfall eine E-Mail Benachrichtigung

    Wie kommt darauf? Wenn er das Thema nicht bewusst abboniert hat bekommt er keine Email.

    Was wäre den deiner Meinung nach der richtige Weg?


    Neuer Thread mit einem Verweis auf diesen hier.

    Andy hat mir ein Schnitzel gebacken aber da war ein Raupi drauf und bevor Oscar das Bugfixen konnte kam Alina und gab mir ein AspirinJunkie.

  • Hmm, als relativer Neuling hier zögere ich zwar, einem gestandenen (und geschätzten, stets hilfbereiten) Poweruser zu widersprechen, aber ich möchte sagen, dass ich es optimal finde, so wie Homer es gemacht hat.
    Einerseits aus den von ihm schon genannten Gründen, andererseits weil man so alles, was thematisch zusammen gehört, schön in einem einzelnen Thread hat. Das ist sehr vorteilhaft, wenn man die Suchfunktion benutzt.
    Statt abertausender Threads, mit losen Informationshäppchen, hat man am Ende weniger Threads, aber die sind voller Gehalt und alle vielleicht wichtigen Nebenaspekte werden mit angesprochen.

    Übrigens wusste ich noch gar nicht, dass der Modbus so ein verbreiteter Standard ist. Ich dachte immer, jeder SPS-Hersteller kocht sein eigenes Süppchen. Für mich war dieser Thread hier daher sehr wertvoll, weil er Anstoß gab, mal anderweitig kurz zu recherchieren. Dabei stellte ich fest, dass der Modbus genau das bringt, was ich als Projekt (eigene SPS) schon jahrelang vor mir her schiebe und dass meine Eigenentwicklung eines Busprotokolls obsolet ist. Mein eigenes Protokoll war, wie ich hier & heute feststellte, zu praktisch 100% identisch mit dem, was in Form des Modbusses bereits ewig existiert.
    Das wäre mir vermutlich entgangen, hätte Homer einen neuen Thread aufgemacht; trotz Verweis, auf den alten Thread, gemäß chips Vorschlag.

    Ich code, also bin ich!

  • Wie kommt darauf? Wenn er das Thema nicht bewusst abboniert hat bekommt er keine Email.

    ...da gebe ich dir recht. Habe mich diesbezüglich im Forum geirrt - Sorry.


    aber ich möchte sagen, dass ich es optimal finde, so wie Homer es gemacht hat.
    Einerseits aus den von ihm schon genannten Gründen, andererseits weil man so alles, was thematisch zusammen gehört, schön in einem einzelnen Thread hat. Das ist sehr vorteilhaft, wenn man die Suchfunktion benutzt.

    ...das war auch mein Denken bezüglich "Leiche ausgraben" ;)

    Gruß
    Homer J. S.

    ...wenn die Donuts auch nur halb so gut schmecken wie sie aussehen, dann sehen sie doppelt so gut aus wie sie schmecken...