ich habe folgendes Setup.
Raspberry Pi 4 mit Codesys 3.5 SP18
Messgerät KIMO C 310
Auf dem Raspberry ist die IP Statisch vergeben 192.168.10.80
KIMO C 310 hat 192.168.10.135
Die Verbindung steht.
Ich muss das Register 0x7010 mit 4 bytes auslesen.
Meiner Erachtens ist das Funktionscode 4
Offset: 0x7010
Länge: 4
Ich bekomme aber den Fehler: ILLEGAL FUNKTON (Slave does not support the function code)
wir haben jetzt das Gerät gegen ein baugleiches Gerät (ebenfalls C 310) getauscht.
Dieses wird ebenfalls per ModbusTCP abgefragt, allerdings mit einer anderen Software.
Das Problem bleibt bestehen.
Verbindung ist da und der selbe Fehler.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
wir haben jetzt das Gerät gegen ein baugleiches Gerät (ebenfalls C 310) getauscht.
Dieses wird ebenfalls per ModbusTCP abgefragt, allerdings mit einer anderen Software.
Das Problem bleibt bestehen.
Verbindung ist da und der selbe Fehler.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Im Ausgangspost habe ich die Doku mit angehangen.
Das Gerät hat 4 Kanäle. Ich will Kanal 1 auslesen.
Laut Doku ist es 0x7010 mit 4 Bytes.
Abfragen muss ich mit Funktionscode 4.
Sollte doch richtig sein oder ?
Wir haben am Freitag es noch mit der anderen Software versucht, die auf dem anderen Raspi läuft. Es ist ein Pythonscript und auch dieses funktioniert auch nicht. Die Verbindung wird aufgebaut, es kommen aber keine Daten, sondern nur ein Fehler.
Wir haben nun den Raspi in Verdacht. Entweder stimmt was mit dem Routing nicht oder Ports.... Keine Ahnung.
Wir werden erstmal den Raspi neu installieren und es mit einem Frischen System noch mal Testen.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
hm, denke nicht das es am Raspi liegt, wieso Function Code 4?
Ich meine zu lesen das dieses Gerät Function Code 3,Funktion Code 16, Funktion Code 8 kann.
Vielleicht irre ich mich ja auch.
Den Function Code 3 hatte ich auch eingestellt, mit selbigen Ergebnis.
Was mich wundert, dass das Testscript welches auf einem anderen Raspi läuft, bei meinem nicht funktioniert. Das Testscript benutzt Function Code 4
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Ja die Runtime war gestoppt, bzw. über die Console beendet.
Ich habe jetzt noch 2 Ideen:
Den Netzwerkverkehr über Wireshark beobachten.
Den Wlanadapter deaktivieren.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
sie hatten Recht.
Es muss Functions Code 3 verwendet werden.
Zusätzlich muss das das Register 0x7010 in Hex 16#1B62 gewandelt werden.
Ich bin hier zufällig darauf gestoßen.
Eine Frage noch.
Da ich mich zum ersten mal mit Modbus beschäftige.
Wo sehe ich die einlaufenden Daten, oder muss ich diese explizit auffrischen?
Ich brauche doch noch einmal Hilfe.
Die Eingangsdaten müssen konvertiert werden.
Ich hätte jetzt angenommen, dass nach little/big endian BBAA >> AABB konvertiert werden muss.
Dass Messgerät zeigt auf Kanal 1 (0x7010) 1,75 bzw. 1,76 an.
Meine Eingangsdaten schwanken zwischen 16#47AE bzw. 16#8F5C
Aber egal wie ich die Bytes schiebe, ich bekomme kein sinnvolles Ergebnis welches mit den Messdaten korrespondiert.
Wie muss ich das richtig konvertieren?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
OK ich habs... fast.
Ich muss die Register 0x7010 und 0x7011 auslesen und entsprechend zusammensetzen.
AB CD >>> CDAB
Hab ich über eine Funktion gelöst.
Ist zwar jetzt nicht die sauberste lösung, aber funktioniert:
END_VAR
VAR_OUTPUT
Daten : LREAL;
END_VAR
VAR
rawLowerByte : DWORD;
rawUpperByte : DWORD;
Allerdings habe ich jetzt ein Darstellungsproblem:
Aus der Bytefolge (16#3F970A3D) Bekomme ich ein UINT32 Wert = 1.07E+09 (1066863165)
Richtig wäre aber FLOAT = 1.18
Wie kann ich das Umstellen, bzw. richtig darstellen?
Grüße
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
fast vergessen mich zu melden.
Ich hab mittlerweile das Problem gelöst.
Die Falsche Darstellung konnte ich mit OSCAT lösen
So sieht mein Code jetzt aus:
FUNCTION_BLOCK ModbusKonverter
VAR_INPUT
LowerByte : WORD; //CD
UpperByte : WORD; //AB
END_VAR
VAR_OUTPUT
Daten : REAL;
END_VAR
VAR
rawLowerByte : DWORD;
rawUpperByte : DWORD;
END_VAR
PS:
Mir ist allerdings unklar wie oscat_basic.DW_TO_REAL funktioniert.
Evtl. kann mir jemand folgende Codezeilen erklären?
pt := ADR(X);
DW_TO_REAL := pt^;
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
PS:
pt := ADR(X); // schreibt die Speicheradresse von x in then Pointer pt
DW_TO_REAL := pt^; // schreibt den Wert der an der Speicheradresse pt steht in DW_TO_REAL
// dereferenziert den Pointer
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
die Funktion MEM.PackWordsToDword... kannte ich noch gar nicht.
Also mit den Pointer und dereferenzieren greift man direkt auf die Speicheradresse
und hat sozusagen Zugriff auf die Rohdaten.
Aber warum macht man das?
Das erschließt sich mir nicht.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hallo zusammen,
ich habe folgendes Setup.
Raspberry Pi 4 mit Codesys 3.5 SP18
Messgerät KIMO C 310
Auf dem Raspberry ist die IP Statisch vergeben 192.168.10.80
KIMO C 310 hat 192.168.10.135
Die Verbindung steht.
Ich muss das Register 0x7010 mit 4 bytes auslesen.
Meiner Erachtens ist das Funktionscode 4
Offset: 0x7010
Länge: 4
Ich bekomme aber den Fehler: ILLEGAL FUNKTON (Slave does not support the function code)
Wo liegt mein Fehler ?
Danke im voraus
Nachtrag:
wir haben jetzt das Gerät gegen ein baugleiches Gerät (ebenfalls C 310) getauscht.
Dieses wird ebenfalls per ModbusTCP abgefragt, allerdings mit einer anderen Software.
Das Problem bleibt bestehen.
Verbindung ist da und der selbe Fehler.
Nachtrag:
wir haben jetzt das Gerät gegen ein baugleiches Gerät (ebenfalls C 310) getauscht.
Dieses wird ebenfalls per ModbusTCP abgefragt, allerdings mit einer anderen Software.
Das Problem bleibt bestehen.
Verbindung ist da und der selbe Fehler.
Sicher das der Offset und Länge und function code passen? Der Fehler sagt das es nicht passt..
Im Ausgangspost habe ich die Doku mit angehangen.
Das Gerät hat 4 Kanäle. Ich will Kanal 1 auslesen.
Laut Doku ist es 0x7010 mit 4 Bytes.
Abfragen muss ich mit Funktionscode 4.
Sollte doch richtig sein oder ?
Wir haben am Freitag es noch mit der anderen Software versucht, die auf dem anderen Raspi läuft. Es ist ein Pythonscript und auch dieses funktioniert auch nicht. Die Verbindung wird aufgebaut, es kommen aber keine Daten, sondern nur ein Fehler.
Wir haben nun den Raspi in Verdacht. Entweder stimmt was mit dem Routing nicht oder Ports.... Keine Ahnung.
Wir werden erstmal den Raspi neu installieren und es mit einem Frischen System noch mal Testen.
hm, denke nicht das es am Raspi liegt, wieso Function Code 4?
Ich meine zu lesen das dieses Gerät Function Code 3,Funktion Code 16, Funktion Code 8 kann.
Vielleicht irre ich mich ja auch.
Den Function Code 3 hatte ich auch eingestellt, mit selbigen Ergebnis.
Was mich wundert, dass das Testscript welches auf einem anderen Raspi läuft, bei meinem nicht funktioniert. Das Testscript benutzt Function Code 4
die runtime beendet wenn du das testscript aufrufst?
Ja die Runtime war gestoppt, bzw. über die Console beendet.
Ich habe jetzt noch 2 Ideen:
Den Netzwerkverkehr über Wireshark beobachten.
Den Wlanadapter deaktivieren.
Hallo Herr Schwellinger,
sie hatten Recht.
Es muss Functions Code 3 verwendet werden.
Zusätzlich muss das das Register 0x7010 in Hex 16#1B62 gewandelt werden.
Ich bin hier zufällig darauf gestoßen.
Eine Frage noch.
Da ich mich zum ersten mal mit Modbus beschäftige.
Wo sehe ich die einlaufenden Daten, oder muss ich diese explizit auffrischen?
Grüße
...wie immer mappen und in den Pou's verwenden nur dann werden die auch aktualisiert.
Dankeschön
Ich brauche doch noch einmal Hilfe.
Die Eingangsdaten müssen konvertiert werden.
Ich hätte jetzt angenommen, dass nach little/big endian BBAA >> AABB konvertiert werden muss.
Dass Messgerät zeigt auf Kanal 1 (0x7010) 1,75 bzw. 1,76 an.
Meine Eingangsdaten schwanken zwischen 16#47AE bzw. 16#8F5C
Aber egal wie ich die Bytes schiebe, ich bekomme kein sinnvolles Ergebnis welches mit den Messdaten korrespondiert.
Wie muss ich das richtig konvertieren?
OK ich habs... fast.
Ich muss die Register 0x7010 und 0x7011 auslesen und entsprechend zusammensetzen.
AB CD >>> CDAB
Hab ich über eine Funktion gelöst.
Ist zwar jetzt nicht die sauberste lösung, aber funktioniert:
END_VAR
VAR_OUTPUT
Daten : LREAL;
END_VAR
VAR
rawLowerByte : DWORD;
rawUpperByte : DWORD;
END_VAR
rawLowerByte := WORD_TO_DWORD(LowerByte);
rawUpperByte := SHL(WORD_TO_DWORD(UpperByte),16);
Daten := DWORD_TO_LREAL(rawLowerByte OR rawUpperByte);
Allerdings habe ich jetzt ein Darstellungsproblem:
Aus der Bytefolge (16#3F970A3D) Bekomme ich ein UINT32 Wert = 1.07E+09 (1066863165)
Richtig wäre aber FLOAT = 1.18
Wie kann ich das Umstellen, bzw. richtig darstellen?
Grüße
Hallo zusammen,
fast vergessen mich zu melden.
Ich hab mittlerweile das Problem gelöst.
Die Falsche Darstellung konnte ich mit OSCAT lösen
So sieht mein Code jetzt aus:
FUNCTION_BLOCK ModbusKonverter
VAR_INPUT
LowerByte : WORD; //CD
UpperByte : WORD; //AB
END_VAR
VAR_OUTPUT
Daten : REAL;
END_VAR
VAR
rawLowerByte : DWORD;
rawUpperByte : DWORD;
END_VAR
rawLowerByte := WORD_TO_DWORD(LowerByte);
rawUpperByte := SHL(WORD_TO_DWORD(UpperByte),16);
Daten := oscat_basic.DW_TO_REAL(rawLowerByte OR rawUpperByte);
PS:
Mir ist allerdings unklar wie oscat_basic.DW_TO_REAL funktioniert.
Evtl. kann mir jemand folgende Codezeilen erklären?
pt := ADR(X);
DW_TO_REAL := pt^;
Alternativ kannst du die 'CAA Memory' Bibliothek nutzen.
PS:
pt := ADR(X); // schreibt die Speicheradresse von x in then Pointer pt
DW_TO_REAL := pt^; // schreibt den Wert der an der Speicheradresse pt steht in DW_TO_REAL
// dereferenziert den Pointer
Ah Ok Danke,
die Funktion MEM.PackWordsToDword... kannte ich noch gar nicht.
Also mit den Pointer und dereferenzieren greift man direkt auf die Speicheradresse
und hat sozusagen Zugriff auf die Rohdaten.
Aber warum macht man das?
Das erschließt sich mir nicht.