In deze les

Wat deze les behandelt

  • De vier beslissingen in een regel als 30001 float 2 registers
  • Van ruwe registerwaarde naar volt, met schaalfactor en teken
  • Waarden die geen meting zijn, maar een sentinel

Lees eerst: Modbus adressering: van 40001 naar het adres, Exception codes lezen en de juiste function code kiezen

Een registerkaart lezen is niet het opzoeken van een adres, het is het nemen van vier beslissingen die de fabrikant in een enkele regel heeft samengeperst: welk blok, welke telling, hoe breed, en welke schaal. Wie er drie van aanneemt, leest een getal dat er plausibel uitziet en toch fout is. In deze les klap je een echte datasheetregel open, reken je hem terug naar volt, en leer je de waarden herkennen die helemaal geen meting zijn.

Vier beslissingen in een regel datasheet

Dit is een regel uit de protocoldocumentatie van een Eastron SDM630, een driefasen energiemeter die je in veel meterkasten tegenkomt:

Nummer in de kaartGrootheidTypeEenheid
30001Fase 1 spanning L-Nfloat32V

Op grond van die ene regel stuur je dit de bus op. Hier staat alleen de PDU, het deel dat bij Modbus RTU en Modbus TCP identiek is:

ByteWaardeBetekenis
104function code FC04, lees input registers
2 tot 300 00startadres, PDU-adres 0
4 tot 500 02aantal registers: 2

En dit komt terug:

ByteWaardeBetekenis
104dezelfde function code, dus geen exception
204byte count, want 2 registers is 4 bytes
3 tot 443 66hoogste 16 bits
5 tot 680 00laagste 16 bits

De vier databytes samen zijn 0x43668000. Gelezen als IEEE 754 float32 is dat 230,5 V, precies de orde van grootte die je bij een netspanning verwacht. Die plausibiliteitscontrole is de enige echte veiligheidsklep die je hebt, want het protocol keurt een verkeerde interpretatie nergens af.

Uit de protocoldocumentatie van een Eastron SDM63030001float322 registersVVier beslissingen in een regel1
Welk blok, dus welke function code?
3xxxx is een input register, dus FC04
2
Telt deze fabrikant vanaf 1 of vanaf 0?
30001 is het eerste nummer, dus PDU-adres 0
3
Hoe breed, en in welke woordvolgorde?
float32 over 2 registers, hoogste woord eerst
4
Welke schaalfactor en welke eenheid?
Geen factor genoemd, de float staat al in volt
Een regel uit een registerkaart is geen adres maar een set van vier beslissingen. Sla er een over en je leest een getal dat er plausibel uitziet en toch fout is.

Wat er verder in een registerkaart kan staan, vind je in het naslagartikel over Modbus registers en registerkaarten. Deze les gaat over de leesprocedure.

Welk blok, en dus welke function code?

Het eerste cijfer van het nummer in de kaart vertelt je in welk blok de waarde staat, en het blok bepaalt de function code. 3xxxx zijn input registers, die lees je met FC04. 4xxxx zijn holding registers, die lees je met FC03. 0xxxx zijn coils (FC01), 1xxxx zijn discrete inputs (FC02).

Dat blokcijfer gaat de draad niet op. In het bericht staan alleen de function code en het adres, en daarom kan PDU-adres 0 vier verschillende dingen betekenen, afhankelijk van of je FC01, FC02, FC03 of FC04 stuurt.

Zegt de kaart alleen "register 1" zonder blokcijfer, dan is de volgorde simpel: probeer FC03. Krijg je exception 01 terug (illegal function, het apparaat kent deze function code niet), dan probeer je FC04. Meer smaken zijn er bij registers niet. Krijg je exception 02 (illegal data address), dan was de function code juist en het adres niet, en dat is de volgende vraag. Hoe zo'n exception-antwoord eruitziet, staat in de les over function codes en exception codes.

In welke telling schrijft deze fabrikant?

Er zijn drie manieren waarop een fabrikant zijn telling prijsgeeft, en bij twee ervan hoef je niets te testen.

  1. Hij schrijft het op. Fronius zegt letterlijk dat je voor register 40001 het adres 40000 (0x9C40) gebruikt: het verzonden adres is altijd een lager dan het registernummer. Daikin houdt het korter: "Register Base 0."
  2. Hij zet twee kolommen naast elkaar. SolarEdge publiceert consequent een base 0 en een base 1 kolom in dezelfde tabel. Jij kiest de kolom die bij je tool hoort.
  3. Hij zegt niets. Dan test je het zelf.

De rekenregel eronder is er maar een: het PDU-adres is het datamodelnummer min 1. Datasheetnummer 40108 (1-gebaseerd) is dus PDU-adres 107, hex 0x006B. Home Assistant, pymodbus en libmodbus verwachten dat PDU-adres, terwijl veel datasheets van meters, drives en warmtepompen het 1-gebaseerde nummer geven.

Testen doe je met een waarde waarvan je de uitkomst kent. Lees de netfrequentie, verwacht ongeveer 50, en kijk wat er komt. Krijg je de buurwaarde of exception 02 (illegal data address), dan zit je er precies een naast. Het omrekenen zelf staat uitgewerkt in de les over Modbus adressering.

Hoeveel registers is deze waarde breed?

Een register is 16 bits, en alles wat daar niet in past staat in twee of meer opeenvolgende registers.

TypeRegistersBereik of eigenschap
uint1610 tot 65535
int161-32768 tot 32767
uint32 en int322tot ruim 4,29 miljard, of met teken
float322IEEE 754, 1 tekenbit, 8 exponentbits, 23 mantissebits
stringmeertwee ASCII-tekens per register

Binnen een register is Modbus big-endian: de hoge byte gaat eerst. De volgorde van twee registers bij een 32-bits waarde, de word order (woordvolgorde), legt de standaard niet vast, dus dat moet de fabrikant zeggen. Eastron doet dat: most significant register first, het hoogste woord eerst. Zet je die volgorde verkeerd, dan valt dat bij een float32 meteen op, maar bij een int32 krijg je een geloofwaardig verkeerd getal. Daar gaat de les over datatypes en word order over.

Van ruwe waarde naar echte eenheid

Een registerwaarde is een kaal getal zonder eenheid, en de datasheet vertelt je met welke factor je dat naar volt, ampere of graden brengt. Daar zijn twee families voor.

Familie 1: een vaste factor in de tekst. Daikin levert temperaturen in het formaat temp16 en schrijft erbij dat je de waarde als signed 16-bits getal leest en daarna door 100 deelt: ruw 3512 is 35,12 °C. NIBE doet hetzelfde met de buitentemperatuur, maar deelt door 10: ruw -47 is -4,7 °C. Twee merken, dezelfde grootheid, dezelfde breedte, andere deler. Wie de deler van het ene merk op het andere plakt, zit precies een factor 10 mis.

Familie 2: de factor staat in een eigen register. SunSpec kiest die route: de meetwaarde is een geheel getal en er staat een tweede register naast met de exponent van tien. De echte waarde is de ruwe waarde maal 10 tot de macht van dat schaalfactorregister. Bij SMA staat het actief vermogen op registernummer 40200 en de bijbehorende schaalfactor op 40201. Is die schaalfactor 1 en de ruwe waarde 550, dan lever je 550 maal 10 tot de macht 1 is 5500 W.

40200550×10^402011=5500 W
40200
ruwe waarde, actief vermogen (int16)
40201
schaalfactor (sunssf)
5500 W
werkelijke waarde
Bij SunSpec staat de schaal in een eigen register vlak naast de meetwaarde. Lees je alleen het vermogensregister, dan mis je een factor 10.

Dit tweede voorbeeld wijkt op precies een punt af van de Eastron-regel: dezelfde vier vragen, maar het antwoord op "welke schaal" komt nu uit een buurregister. Ga er niet van uit dat elke waarde er een heeft: bij SMA heeft registernummer 40219, de interne temperatuur, geen schaalfactorregister. Meer daarover staat in het artikel over SunSpec over Modbus.

Als het getal geen meting is

Sommige getallen zijn geen meting maar een mededeling dat er geen meting is. Een niet ingevuld register geeft namelijk geen leeg veld terug, maar een vaste sentinelwaarde.

DatatypeSentinel voor "niet ingevuld"
int16 en sunssf0x8000
uint160xFFFF
int320x80000000
uint320xFFFFFFFF
float320x7FC00000

Daikin doet het anders en gebruikt leesbare decimale sentinels: 32767 betekent dat het apparaat dit register niet kent, 32766 dat het register in deze configuratie niet bestaat, en 32765 dat de waarde nog geladen wordt. Een Daikin-temperatuurregister dat 32767 teruggeeft, is dus geen 327,67 °C.

Vermogensregister van een SMA-omvormer (int32)☀4200 W☾0x8000000021474836480 W
4200 W
Overdag, omvormer actief
0x80000000
's Nachts, omvormer uit
0 W
Sentinel, geen meting
Reken je die sentinel mee, dan staat er 's nachts ruim twee gigawatt op je dashboard. Filter hem in de mapping, niet in de grafiek.

De volgorde is dus: eerst controleren op de sentinelwaarden van dat merk, daarna pas schalen en interpreteren.

De vijf vragen die je aan elke kaart stelt

Dezelfde vijf vragen werken op elke registerkaart van elk merk, en in deze volgorde kost het je een minuut per waarde.

  1. Welk blok? Het blokcijfer of de kop boven de tabel geeft je de function code: FC03 voor holding registers, FC04 voor input registers.
  2. Welke telling? Zoek de expliciete zin of de tweede kolom. Vind je geen van beide, test dan tegen een bekende waarde.
  3. Hoe breed? Een register is 16 bits. Bij twee of meer registers hoort er een uitspraak over de woordvolgorde bij.
  4. Welke schaal? Een vaste deler uit de tekst, een apart schaalfactorregister, of niets.
  5. Is het wel een meting? Controleer eerst op de sentinelwaarden van dat merk.

Soms is het antwoord op vraag drie dat het helemaal geen getal is. Daikin zet met het type text16 twee ASCII-tekens in een register: 21816 is 0x5538, 0x55 is de letter U en 0x38 het cijfer 8, dus foutcode U8. Als getal gelezen is dat register betekenisloos.

Zonder kaart scant de Register Scanner in ModbusCloud Diagnostics een adresbereik af en toont welke adressen antwoorden. Betekenis vindt hij niet: de vijf vragen blijven.

Veelgemaakte fouten

De schaalfactor vergeten. Je leest 2305 en zet dat als 2305 V in je dashboard. Niemand merkt het tot iemand de grafiek opent. Controleer elke nieuwe kaart tegen een waarde waarvan je de orde van grootte kent: 230 V, 50 Hz, of de aflezing op het display van het apparaat zelf.

Een 32-bits waarde als twee losse registers lezen. Je krijgt twee getallen die geen van beide ergens op slaan, en je gaat de fout in het adres zoeken. De kaart zegt hoeveel registers de waarde breed is, en dat is geen detail maar een van de vier beslissingen.

Signed en unsigned door elkaar halen. Een buitentemperatuur van min 5 graden komt als 65531 binnen zodra je hem als unsigned leest. Bij NIBE, waar door 10 gedeeld wordt, springt min 5,0 °C zelfs naar 6548,6. Het patroon is herkenbaar: waarden net onder 65536 bij een grootheid die negatief kan worden.

Een sentinel voor een meting aanzien. De waarden uit de vorige sectie zijn geen extreme metingen maar mededelingen. Filter ze weg in je mapping, voordat je schaalt en voordat je alarmen instelt.

Aan de slag

Pas de procedure toe op een echte kaart en toets je interpretatie aan de werkelijkheid. Welke meters welke kaart meeleveren staat in de vergelijking van Modbus energiemeters.

  1. 1

    Pak een regel uit de registerkaart

    De kaart van je eigen apparaat of de protocoldocumentatie van de Eastron SDM630. Een regel is genoeg.

  2. 2

    Kies een waarde waarvan je het antwoord kent

    Pak de netspanning (rond de 230) of de frequentie (rond de 50). Een teller of een energiestand is ongeschikt, want daar heb je geen verwachting bij.

  3. 3

    Beantwoord de vier vragen op papier

    Blok, telling, breedte en schaal, voordat je iets uitleest. Schrijf ook op welke waarde je verwacht.

  4. 4

    Lees de ruwe registers uit

    Gebruik mbpoll (gratis te gebruiken, ook zakelijk) en vraag hex-uitvoer, zodat je de registerwaarden ziet en niet de interpretatie van de tool. Het cijfer achter -t volgt het blokcijfer uit de kaart, dus -t 3 voor 3xxxx en -t 4 voor 4xxxx:

    mbpoll -m rtu -a 1 -b 9600 -P none -t 3:hex -r 1 -c 2 -1 /dev/ttyUSB0
    
  5. 5

    Reken met de hand terug en herleid het verschil

    Zet de twee registers achter elkaar, pas de schaalfactor toe en vergelijk met je verwachting. Klopt de orde van grootte niet, dan zit de fout in een van de vier beslissingen en niet in de meting. Een factor 10 of 100 wijst naar de schaal, een buurwaarde naar de telling, en pure onzin naar de breedte of de woordvolgorde.

Zonder hardware. Start de simulator van pymodbus (ook gratis te gebruiken, ook zakelijk) en laat hem luisteren op poort 5020. Op PDU-adres 4 staat over twee registers een uint32 met de waarde 617001, en op adres 16 staat over vijf registers een string. Pas op allebei dezelfde procedure toe: welk blok, welke telling, hoe breed, welke schaal.

Verwacht resultaat: een ingevuld blaadje met vier antwoorden en een uitgelezen waarde die klopt met je verwachting, of een verschil dat je naar precies een van die vier beslissingen kunt herleiden.

Samenvatting

  • Een regel in een registerkaart bevat vier beslissingen: welk blok, welke telling, hoeveel registers breed, en welke schaal.
  • Het blokcijfer bepaalt de function code en gaat zelf niet mee in het bericht, dus 3xxxx lees je met FC04 en 4xxxx met FC03.
  • Het PDU-adres is het datamodelnummer min 1, en een fabrikant zegt dat expliciet, toont twee kolommen, of laat het aan jou over om te testen.
  • Een schaalfactor komt uit de tekst van de datasheet of uit een buurregister, en niet elke waarde heeft er een.
  • Waarden als 0x8000, 0xFFFF, 0x7FC00000 en de Daikin-codes 32767, 32766 en 32765 zijn geen metingen maar sentinels, dus filter ze weg voordat je schaalt.

Controleer jezelf

Vier vragen over deze les. Je krijgt bij elk antwoord uitleg.

Vraag 1 van 4
In de datasheet staat: 30001, float, 2 registers, Volts. Welke function code stuur je, en welk startadres?
Een register bevat de waarde 2305. De datasheet zegt: unit 0.1 V. Wat lees je af, en hoe controleer je dat?
Je leest een buitentemperatuur uit en krijgt 65531 terug, terwijl het buiten vriest. Wat is er aan de hand?
Een SMA-omvormer geeft 's nachts in het vermogensregister de waarde 0x80000000. Wat doe je daarmee in je monitoring?

Loopt het vast op een project?

Beschrijf wat je ziet en waar het misgaat. We kijken mee en zeggen wat we zouden doen.

Verder lezen in de kennisbank