32-Bit-Floats über Modbus lesen: ABCD, CDAB, BADC und DCBA

· Von Vladimir Chemeris, Entwickler von Modbus TCP FieldKit

Kurzantwort: Modbus-Register haben 16 Bit, ein float32 braucht also zwei, und das Protokoll legt nicht fest, welches zuerst kommt. Lesen Sie einen bekannten Wert, probieren Sie im Float-Konverter alle vier Reihenfolgen und speichern Sie die passende.

Warum das passiert

Die Spezifikation definiert Register als 16-Bit-Werte, die ein Gerät Big-Endian sendet, High-Byte zuerst. Wie ein Gerät zwei Register zu einer Zahl kombiniert, regelt sie nicht. Das entscheiden die Hersteller. Nennen Sie die vier Bytes eines IEEE-754-Floats A B C D, wobei A das höchstwertige ist, ergeben sich vier Anordnungen:

Reihenfolge Register enthalten Gängiger Name
ABCD AB, CD Big-Endian
CDAB CD, AB Word Swap, Little-Endian-Wortreihenfolge
BADC BA, DC Byte Swap
DCBA DC, BA Little-Endian

Echte Werte

Wir haben 123.456 in zwei Anordnungen in einen Server mit pymodbus 3.16.1 geladen. In IEEE 754 ist 123.456 gleich 42 F6 E9 79.

Als ABCD gespeichert an Adresse 10:

TX 00 01 00 00 00 06 01 03 00 0A 00 02
RX 00 01 00 00 00 07 01 03 04 42 F6 E9 79

Als CDAB gespeichert an Adresse 12:

TX 00 01 00 00 00 06 01 03 00 0C 00 02
RX 00 01 00 00 00 07 01 03 04 E9 79 42 F6

Dekodieren Sie die erste Antwort, 42F6 E979, in allen vier Reihenfolgen, und nur eine liefert ein sinnvolles Ergebnis:

Gelesen als Ergebnis
ABCD 123.456
CDAB -1.88e+25
BADC -9.86e+32
DCBA 1.52e+35

Das Vertauschen von Bytes verschiebt Mantissenbits in den Exponenten, deshalb liefert eine falsche Reihenfolge meist eine riesige oder winzige Zahl. Eine Ausnahme gibt es: 0.0 liest sich in allen vier Reihenfolgen als 0.0, testen Sie also mit einem Wert ungleich null.

Die Reihenfolge an einem Gerät finden

  1. Wählen Sie einen Wert, den Sie unabhängig prüfen können: eine Spannung auf dem Display, eine Temperatur oder einen Sollwert, den Sie selbst steuern.
  2. Lesen Sie zwei Register an der dokumentierten Adresse. Achten Sie auf den Off-by-one-Fehler: Wer ein Register zu spät beginnt, erhält Müll, den keine Reihenfolge korrigieren kann.
  3. Dekodieren Sie in allen vier Reihenfolgen.
  4. Ändern Sie den Wert am Gerät und lesen Sie erneut. Die richtige Reihenfolge folgt der Änderung.

Dasselbe gilt für 32-Bit-Ganzzahlen

Ein uint32-Energiezähler hat dasselbe Problem. Bei einem kleinen Wert ist das High-Word null, ein vertauschter Lesewert ist daher ein exaktes Vielfaches von 65536: Ein Zähler bei 1000 liest sich als 65536000. Sieht der Summenwert eines Zählers so aus, verdächtigen Sie zuerst die Wortreihenfolge.

Bei 64-Bit-Werten gilt derselbe Gedanke für vier Register, und auch dort sind sich die Hersteller nicht einig.

Die Antwort speichern

In FieldKit speichert jede Registerdefinition in einem Profil Format, Byte- und Wortreihenfolge, Skalierung und Einheit. Sobald Sie die Reihenfolge gefunden haben, zeigt der Registerbrowser 123.456 statt zweier Ganzzahlen, und Sie behalten diese Einstellung für das nächste Gerät desselben Modells.

Quellen

FAQ

Welche Wortreihenfolge ist bei Modbus-Floats am häufigsten?

Es gibt keinen Standard. Die Spezifikation definiert 16-Bit-Register und überlässt Werte aus mehreren Registern dem Hersteller. Prüfen Sie das Handbuch und bestätigen Sie mit einem bekannten Wert. ABCD und CDAB begegnen Ihnen am häufigsten.

Was bedeutet Word Swap?

Die beiden 16-Bit-Register kommen in umgekehrter Reihenfolge an, die Bytes innerhalb jedes Registers bleiben aber an ihrem Platz. In der Buchstabennotation ist das CDAB.

Wie finde ich die Reihenfolge ohne Handbuch?

Lesen Sie zwei Register, während das Gerät einen bekannten Wert anzeigt, etwa eine Spannung auf dem Display. Dekodieren Sie sie in allen vier Reihenfolgen und wählen Sie die, die passt.