Hallo,
ich bin mal wieder beim Versuch verschiedene Janitzas per Modbus auszulesen. Mein Versuch erst mal nur einen Janitza auszulesen funktioniert teilweise.
Bei manschen "Starts" bekomme ich die angefrageten Werte - bei den nächsten "Starts" ist die Antwort zu kurz und die falschen Register werden ausgelesen.
Bild "matrix_ok" zeigt einen gelungenen Versuch 64 Register (float).
Bild "matrix_falsch" zeigt einen misslungenen Versuch 64 Register (float).
Ich habe viel rumprobiert - komme aber zu keiner Lösung. Vielen Dank schon mal!
AutoIt
; Abfragen von Modbusstationen,
#include <WinAPI.au3>
#include <Misc.au3>
#include <Array.au3>
#include <File.au3>
#include <FTPEx.au3>
#include <Timers.au3>
#include <GUIConstants.au3>
#include <MsgBoxConstants.au3>
#include <TrayConstants.au3>
#Include <GuiListView.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <EditConstants.au3>
#include <StaticConstants.au3>
#include <ListviewConstants.au3>
Global $ModbusTCP_Debug_Send = 1
Global $ModbusTCP_Debug_Recv = 1
;$anzahl_stationen = 10 ;;;;; Unbedingt noch aus inia die Anzahl ermitteln
$anzahl_janitzas = 1
$FC2 = "04"
$s_uID = "02"
$s_port = 502;
$Start_regJanitza = 19000
Local $iTimeout = 5
;;;;;;;;;;;; Hier gehts los
HotKeySet("{F8}","_stopIt") ; F8 Beendet Programm
$runner = True
$hTimer = TimerInit() ; Begin the timer and store the handle in a variable.
;MsgBox($MB_SYSTEMMODAL, "Time Difference", $fDiff)
While $runner
_INI_zu_ARRAY_janitza()
TCPStartup()
For $s = 1 TO UBound($listeJan)-1 ;Anzahl Janitzas
$s_port = $listeJan[$s][2]
$s_uID = $listeJan[$s][3]
Global $iSock = TCPConnect($listeJan[$s][1], $s_port)
If $iSock = -1 Then
ConsoleWrite("Fehler Verbindungsaufbau TCP Modbus" & $listeJan[$s][1] & @LF)
;Exit
EndIf
If $iSock <> -1 Then
ConsoleWrite(" TCP Modbus OK " & $listeJan[$s][1] & @LF)
;Exit
$aWR_meter = _ModbusTCP_ReadValues($iSock, $FC2, $Start_regJanitza,64, "float") ;
_ArrayDisplay($aWR_meter)
TCPCloseSocket($iSock)
TCPShutdown()
exit
EndIf ;; Verbinugsaufbau OK
;_____________________________________________________________
NEXT ; Nächste Station
TCPCloseSocket($iSock)
sleep(Abs($timer *1000) - (_Timer_Diff($hStarttime)))
WEnd
TCPShutdown()
Exit
;;;____________________________________________FUNKTIONEN_________________________________________________________________________________;;;;;;;
Func _stopIt()
$runner = False
TCPCloseSocket($iSock)
TCPShutdown()
Exit
EndFunc
;;;;;;;;;;;;;;; INI ZU ARRAY JANITZA
Func _INI_zu_ARRAY_janitza()
Global $listeJan[$anzahl_janitzas+1][14] ;zeile, spalte
FOR $i = 1 To $anzahl_janitzas
$spalte1 = IniRead(@ScriptDir & "\janitza.ini", $i, "Janiza", "xxx") ;IP Adresse
$spalte2 = IniRead(@ScriptDir & "\janitza.ini", $i, "PORT", "xxx") ;Modbus Port
$spalte3 = IniRead(@ScriptDir & "\janitza.ini", $i, "MODBUS_ID", "xxx") ;Modbus uID
$spalte4 = IniRead(@ScriptDir & "\janitza.ini", $i, "KOPF", "xxx") ;Kopf
$spalte5 = IniRead(@ScriptDir & "\janitza.ini", $i, "ID", "xxx") ;ID
$spalte6 = IniRead(@ScriptDir & "\janitza.ini", $i, "MANUFAKTUR", "xxx") ;Hersteller
$spalte7 = IniRead(@ScriptDir & "\janitza.ini", $i, "MODEL", "xxx") ;Model
$spalte8 = IniRead(@ScriptDir & "\janitza.ini", $i, "SERIAL", "xxx") ;Sereiennummer
$spalte9 = IniRead(@ScriptDir & "\janitza.ini", $i, "NIX", "xxx") ;Sereiennummer
$spalte10 = IniRead(@ScriptDir & "\janitza.ini", $i, "FTP_HOST", "xxx") ;FTP host
$spalte11 = IniRead(@ScriptDir & "\janitza.ini", $i, "FTP_USER", "xxx") ;FTuser
$spalte12 = IniRead(@ScriptDir & "\janitza.ini", $i, "PTP_PAS", "xxx") ;FTPpa
$spalte13 = IniRead(@ScriptDir & "\janitza.ini", $i, "FTP_PFAD", "xxx") ;FT Pfad
$listeJan[$i][1] = $spalte1 ;zeile, spalte
$listeJan[$i][2] = $spalte2
$listeJan[$i][3] = $spalte3
$listeJan[$i][4] = $spalte4
$listeJan[$i][5] = $spalte5
$listeJan[$i][6] = $spalte6
$listeJan[$i][7] = $spalte7
$listeJan[$i][8] = $spalte8
$listeJan[$i][9] = $spalte9
$listeJan[$i][10] = $spalte10
$listeJan[$i][11] = $spalte11
$listeJan[$i][12] = $spalte12
$listeJan[$i][13] = $spalte13
NEXT
EndFunc
;;;;;;;;;;;;;;; ENDE INI ZU ARRAY Janitza
;;;;;;;;;;;;;FUNC MODBUS;;;;;;;;;;;;;;;;;;;;;;
Func _ModbusTCP_ReadValues($mainsocket, $FC2, $iStart, $iNum, $sType)
Local Static $TI = 0
$TI += 1
Local $iBytesToSend = 6
_ModbusTCP_Send($mainsocket, "0x" & Hex($TI, 4) & "0000" & Hex($iBytesToSend, 5) & $s_uID & Hex($FC2, 2) & Hex($iStart, 4) & Hex($iNum, 4)) ;; komisch Hex($iBytesToSend, 4) ist sonst OK
;_ModbusTCP_Send($mainsocket, "0x" & Hex($__TID, 4) & "0000" & Hex($iBytesToSend, 4) & $ID & Hex($FC, 2) & Hex($iStart, 4) & Hex($iNum, 4))
MsgBox(0, "", "$iSock: "& $iSock & ' IP: ' &$listeJan[$s][1] &' uID: '& $s_uID &' Port: '& $s_port &' FC: '& $FC2 &' Reg: '& $Start_regJanitza &' iNum: '& $iNum)
If @error Then Return SetError(1, 0, 0)
Local $sRecv
Do
$sRecv = _ModbusTCP_Recv($mainsocket, 512)
;MsgBox(0, "", "FEHLER: "& "**" & 'local : ' & $sRecv & ' FC : '& $FC2)
Until @error Or $sRecv <> ""
If @error Then Return SetError(2, 0, 0)
If Int(String(BinaryMid($sRecv, 1, 2))) <> $TI Then Return SetError(3, 0, 0)
Local $iSize = 4 ; default
Switch $sType
Case "word"
$iSize = 2
Case "float"
$iSize = 4
Case "double"
$iSize = 8
EndSwitch
Local $aRet[$iNum / ($iSize / 2)], $iTemp ;$iSize
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
Func _ModbusTCP_Send($mainsocket, $data)
If $ModbusTCP_Debug_Send Then ConsoleWrite("_ModbusTCP_Send(" & $mainsocket & ", """ & $data & """)" & @CRLF)
;$TextZeile_log = $TextZeile_log & "_ModbusTCP_Send(" & $mainsocket & ", """ & $data & """)" & @CRLF
Local $Send = TCPSend($mainsocket, $data)
Return SetError(@error, 0, $Send)
EndFunc ;==>_ModbusTCP_Send
Func _ModbusTCP_Recv($mainsocket, $maxlen = 256, $flag = 0)
Local $sRecv = TCPRecv($mainsocket, $maxlen, $flag)
Local $error = @error
If $sRecv <> "" And $ModbusTCP_Debug_Recv Then ConsoleWrite("_ModbusTCP_Recv: " & $sRecv & @CRLF)
;$TextZeile_log = $TextZeile_log & "_ModbusTCP_Recv: " & $sRecv & @CRLF
Return SetError($error, 0, $sRecv)
EndFunc ;==>_ModbusTCP_Recv
; #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 $tInt64 = DllStructCreate("INT64")
Local $tDouble = DllStructCreate("double", DllStructGetPtr($tInt64))
DllStructSetData($tInt64, 1, $iInt64)
Return DllStructGetData($tDouble, 1)
EndFunc ;==>_WinAPI_Int64ToDouble
; #FUNCTION# ====================================================================================================================
; Name...........: UAS E`WEB https://www.autoitscript.com/forum/topic/49435-lparam-array/?tab=comments#comment-373039
; Description ...: WORD zu Dword
; Modified.......:
; Remarks .......:
; Related .......:
; Link ..........:
; E
$iWord = MakeWord(0x34,0x12)
ConsoleWrite("0x" & Hex($iWord) & @CRLF)
ConsoleWrite("0x" & Hex(LoByte($iWord)) & @CRLF);These output original values passed to MakeWord()
ConsoleWrite("0x" & Hex(HiByte($iWord)) & @CRLF)
;$TextZeile_log = $TextZeile_log & "0x" & Hex($iWord) & @CRLF
Func LoByte($iWord)
Return BitAND($iWord, 0xFF)
EndFunc ;==>LoByte
Func HiByte($iWord)
Return BitAND($iWord, 0xFF00) / 0x100
EndFunc ;==>HiByte
Func MakeWord($iLoByte, $iHiByte)
If $iHiByte < 0x80 Then
Return BitOR($iHiByte * 0x100, $iLoByte)
Else
Return BitOR($iHiByte, 0xFF00) * BitOR(0x100, $iLoByte)
EndIf
EndFunc ;==>MakeWord
Alles anzeigen