AnB

Perché un float Modbus legge 1.5E+35

Ti aspetti 123.456 e a schermo compare 1.5184998E+35. Il dispositivo funziona, il cablaggio pure: i quattro byte sono giusti, vengono solo letti nell'ordine sbagliato.

Il sintomo

Un dispositivo invia un float a 32 bit in due registri. Per 123.456 i registri contengono 42F6 e E979. Letti nell'ordine giusto, i quattro byte 42 F6 E9 79 danno 123.456. Letti in un altro ordine, gli stessi byte danno qualcosa che sembra rumore:

Ordine dei byteByteFloat
ABCD42 F6 E9 79123.456
CDABE9 79 42 F6-1.8833671E+25
BADCF6 42 79 E9-9.8611155E+32
DCBA79 E9 F6 421.5184998E+35

L'indizio è la grandezza del numero. Le grandezze fisiche raramente richiedono esponenti oltre ±10: un valore intorno a E+25, E+35 o E-38 quasi mai è una misura reale. È un valore corretto con i byte rimescolati.

Perché succede

Modbus trasmette ogni registro a 16 bit con il byte alto per primo, ma non dice nulla su come dividere un valore a 32 bit tra due registri. Lo sceglie il costruttore, e il master deve fare la stessa scelta.

La seconda causa spesso è nel nostro codice. Il processore di un PC è little-endian, quindi la riga di C# più naturale legge i quattro byte al contrario:

// bytes = 42 F6 E9 79, nell'ordine in cui sono arrivati
float value = BitConverter.ToSingle(bytes, 0);  // 1.5184998E+35 su un PC

È esattamente il numero del titolo, da byte perfettamente corretti.

Come correggerlo

In C#, dichiara esplicitamente l'ordine che ti aspetti:

using System.Buffers.Binary;

float value = BinaryPrimitives.ReadSingleBigEndian(bytes);  // 123.456

Se il dispositivo usa le word scambiate (CDAB), inverti i due registri prima di decodificare. In uno SCADA o in un master commerciale cerca un'opzione chiamata byte order, word swap o swap registers: il nome cambia da prodotto a prodotto.

Trovare l'ordine in un passaggio

Quando il manuale non lo dice, leggi un valore che conosci all'incirca, come un setpoint che hai impostato o la tensione di rete, e incolla i registri grezzi nel decoder registri insieme al valore atteso. Lo strumento mostra i quattro ordini ed evidenzia quello che corrisponde. Una volta trovato, di solito vale per tutti i valori di quel dispositivo.