Bekijk alle lessen
Deel 1
Basis
Deel 2
Modbus RTU
- Les 5RS485 uitgelegd: A, B, common en terminatie20 min
- Les 6Baudrate en pariteit: waarom 8E1 de default is16 min
- Les 7Het Modbus RTU frame byte voor byte, plus CRC18 min
- Les 8Meerdere Modbus apparaten op een bus zetten16 min
- Les 9Je eerste Modbus apparaat uitlezen met mbpoll22 min
- Les 10Modbus RTU storing zoeken: symptoom en oorzaak20 min
Deel 3
Modbus TCP
Deel 4
Gevorderd
- Les 16Veilig naar een Modbus apparaat schrijven18 min
- Les 17Word order en float: dezelfde bytes, andere waarde22 min
- Les 18Pollinterval en busbelasting zelf berekenen18 min
- Les 19Modbus beveiligen: het protocol doet het niet16 min
- Les 20Modbus integreren: PLC, Home Assistant of cloud20 min
- Les 21Modbus checklist voor oplevering en overdracht18 min
Een Modbus registerkaart lezen zonder gokken
Een Modbus registerkaart lezen is een vaardigheid. In een regel als 30001 float 2 registers zitten vier keuzes, en je leert ze alle vier bewust maken.
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 kaart | Grootheid | Type | Eenheid |
|---|---|---|---|
| 30001 | Fase 1 spanning L-N | float32 | V |
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:
| Byte | Waarde | Betekenis |
|---|---|---|
| 1 | 04 | function code FC04, lees input registers |
| 2 tot 3 | 00 00 | startadres, PDU-adres 0 |
| 4 tot 5 | 00 02 | aantal registers: 2 |
En dit komt terug:
| Byte | Waarde | Betekenis |
|---|---|---|
| 1 | 04 | dezelfde function code, dus geen exception |
| 2 | 04 | byte count, want 2 registers is 4 bytes |
| 3 tot 4 | 43 66 | hoogste 16 bits |
| 5 tot 6 | 80 00 | laagste 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.
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.
- 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." - 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.
- 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.
| Type | Registers | Bereik of eigenschap |
|---|---|---|
| uint16 | 1 | 0 tot 65535 |
| int16 | 1 | -32768 tot 32767 |
| uint32 en int32 | 2 | tot ruim 4,29 miljard, of met teken |
| float32 | 2 | IEEE 754, 1 tekenbit, 8 exponentbits, 23 mantissebits |
| string | meer | twee 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.
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.
| Datatype | Sentinel voor "niet ingevuld" |
|---|---|
| int16 en sunssf | 0x8000 |
| uint16 | 0xFFFF |
| int32 | 0x80000000 |
| uint32 | 0xFFFFFFFF |
| float32 | 0x7FC00000 |
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.
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.
- Welk blok? Het blokcijfer of de kop boven de tabel geeft je de function code: FC03 voor holding registers, FC04 voor input registers.
- Welke telling? Zoek de expliciete zin of de tweede kolom. Vind je geen van beide, test dan tegen een bekende waarde.
- Hoe breed? Een register is 16 bits. Bij twee of meer registers hoort er een uitspraak over de woordvolgorde bij.
- Welke schaal? Een vaste deler uit de tekst, een apart schaalfactorregister, of niets.
- 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
Pak een regel uit de registerkaart
De kaart van je eigen apparaat of de protocoldocumentatie van de Eastron SDM630. Een regel is genoeg.
- 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
Beantwoord de vier vragen op papier
Blok, telling, breedte en schaal, voordat je iets uitleest. Schrijf ook op welke waarde je verwacht.
- 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
-tvolgt het blokcijfer uit de kaart, dus-t 3voor 3xxxx en-t 4voor 4xxxx:mbpoll -m rtu -a 1 -b 9600 -P none -t 3:hex -r 1 -c 2 -1 /dev/ttyUSB0 - 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,0x7FC00000en 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
Zelf zien hoe het werkt?
De ModbusCloud Gateway leest de apparaten uit deze cursus uit zonder dat je registers hoeft te programmeren.