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
Pollinterval en busbelasting zelf berekenen
Je Modbus pollinterval volgt uit een som, niet uit een gevoel. Reken de cyclustijd uit, gebruik blokreads en houd de busbelasting onder de vijftig procent.
Wat deze les behandelt
- Hoe lang een enkele transactie duurt bij jouw baudrate
- De cyclustijd van je hele bus, en de vuistregel van vijftig procent
- Blokreads die bijna zes keer schelen, en wat een dood apparaat kost
Lees eerst: Baudrate en pariteit: waarom 8E1 de default is, Meerdere Modbus apparaten op een bus zetten
Je pollinterval volgt uit een som, niet uit een gevoel: reken uit hoe lang een pollronde over al je apparaten duurt, en kies daarna een interval dat minstens twee keer zo lang is. Die som kost vijf minuten en verklaart meteen waarom losse reads een installatie bijna zes keer trager maken dan blokreads. Na deze les reken je je eigen bus door en onderbouw je het interval dat je instelt.
Hoe lang duurt een enkele lezing?
Bij 9600 baud kost het lezen van tien holding registers ongeveer 46 milliseconden aan bustijd, en dat getal komt uit het frame zelf. Dit is het verzoek dat de client op de lijn zet: tien holding registers vanaf PDU-adres 0 bij server 1.
01 03 00 00 00 0A C5 CD
| Byte | Waarde | Betekenis |
|---|---|---|
| 1 | 01 | serveradres, dit verzoek is voor server 1 |
| 2 | 03 | FC03, lees holding registers |
| 3 en 4 | 00 00 | startadres, PDU-adres 0 |
| 5 en 6 | 00 0A | aantal registers: 10 |
| 7 en 8 | C5 CD | CRC-16, low byte eerst |
Acht bytes, altijd. Een FC03-verzoek heeft geen variabel deel. Het antwoord wel:
01 03 14 00 0A 00 0B 00 0C 00 0D 00 0E 00 0F 00 10 00 11 00 12 00 13 29 D6
| Byte | Waarde | Betekenis |
|---|---|---|
| 1 | 01 | serveradres, hetzelfde als in het verzoek |
| 2 | 03 | FC03 ongewijzigd, bij een exception had hier 83 gestaan |
| 3 | 14 | byte count, 0x14 is 20 databytes |
| 4 tot 23 | 00 0A tot en met 00 13 | tien registerwaarden van 2 bytes elk |
| 24 en 25 | 29 D6 | CRC-16 |
Vijfentwintig bytes, en dat is precies 5 + 2N met N is 10. Nu de klok erbij. Een RTU-karakter is altijd 11 bits op de lijn, dus bij 9600 baud duurt een byte 11 / 9600 = 1,1458 ms. Tussen twee frames hoort minimaal t3,5 stilte, bij 9600 baud 4,010 ms, en die stilte heb je twee keer nodig: een keer tussen verzoek en antwoord, een keer voor het volgende verzoek. Samen 7 karaktertijden.
t_transactie = (bytes verzoek + bytes antwoord + 7) x 11 / baudrate
Ingevuld: 8 + 25 + 7 = 40 karaktertijden, maal 1,1458 ms, is 45,83 ms. Daar komt nog de tijd bij die de server nodig heeft om zijn antwoord samen te stellen, en die staat zelden in een datasheet.
Waarom blokreads zoveel schelen
Omdat de overhead per transactie vast is. Acht bytes verzoek, vijf bytes antwoordoverhead en zeven karaktertijden stilte zijn samen altijd 20 karaktertijden, of je nu twee registers vraagt of vierentwintig. Elk extra register kost daarna maar 2 bytes. Hetzelfde verzoek als hierboven dus, met alleen het aantal registers anders:
| Read | Karaktertijden | Waarvan overhead |
|---|---|---|
| 2 registers | 20 vast + 4 data = 24 | 83 procent |
| 10 registers | 20 vast + 20 data = 40 | 50 procent |
| 24 registers | 20 vast + 48 data = 68 | 29 procent |
Bij twee registers per transactie gaat 83 procent van je bustijd op aan het vragen zelf. Bij vierentwintig registers is dat nog 29 procent. Dat is geen kwestie van iets zuiniger zijn: de overhead per meetwaarde daalt met bijna een orde van grootte.
De cyclustijd van je hele installatie
Tel de transacties op, meer is het niet. Neem tien energiemeters op een RS485-bus van 9600 baud, met per meter twaalf float32-meetwaarden en dus 24 registers. Welke meter hoeveel registers per meting nodig heeft, lees je terug in de vergelijking van Modbus energiemeters voor installateurs.
| Aanpak | Per transactie | Per meter | Tien meters |
|---|---|---|---|
| Een blokread van 24 registers | 68 karaktertijden = 77,92 ms, plus 20 ms verwerking | 97,92 ms | 979,2 ms |
| Twaalf losse reads van 2 registers | 24 karaktertijden = 27,5 ms, plus 20 ms verwerking | 570 ms | 5.700 ms |
Ongeveer 0,98 seconde tegen 5,7 seconden, een factor 5,8. Dezelfde data, dezelfde bus, alleen anders gevraagd.
Op 19200 baud wordt dezelfde blokread-cyclus 589,6 ms in plaats van 979,2 ms. Ruwweg de helft, maar niet exact de helft, want die aangenomen 20 ms verwerking per verzoek schaalt niet mee met de baudrate. Bij lange blokken helpt een hogere baudrate dus veel, bij veel korte reads is de server de bottleneck. Wat baudrate en pariteit verder met je timing doen, staat in de les over baudrate, pariteit en timing.
Van cyclustijd naar pollinterval
Deel de cyclustijd door het interval en je hebt de busbelasting.
busbelasting = cyclustijd / pollinterval
Voor de cyclus van 0,979 s hierboven:
| Pollinterval | Busbelasting | Oordeel |
|---|---|---|
| 1 seconde | 97,9 procent | onwerkbaar, elke hapering geeft een gat |
| 2 seconden | 49,0 procent | krap maar haalbaar |
| 5 seconden | 19,6 procent | comfortabel |
| 10 seconden | 9,8 procent | ruim, en voor energiemonitoring genoeg |
| 60 seconden | 1,6 procent | gangbaar voor warmtepompen en gebouwbeheer |
Blijf onder de 50 procent. Dat is een vuistregel van deze cursus en geen eis uit de standaard, maar de reden is concreet: boven de helft is er geen ruimte meer voor een retry, voor een traag antwoord, of voor een tweede functie op dezelfde bus.
Of je dat interval vrij kunt kiezen, hangt van je client af. In ModbusCloud Diagnostics stel je het in tussen 500 ms en 10 s, genoeg om te zien wat een korter interval met je busbelasting doet voordat je het in je eigen client vastlegt.
Wat de fabrikant je toestaat
Minder dan de standaard, bijna altijd. De spec staat 125 registers per FC03- of FC04-verzoek toe, maar het apparaat bepaalt de echte grens.
| Apparaat | Grens per transactie |
|---|---|
| Modbus-standaard, FC03 en FC04 | 125 registers |
| Eastron SDM630 | 80 registers, en altijd een even aantal |
| Daikin DCOM-LT/MB | 64 registers voor FC03, FC04 en FC16 |
| NIBE S-serie | 20 registers per query, en maximaal 100 registers per seconde |
| SMA | 5 waarden tegelijk, en minstens 10 seconden tussen datatransfers |
Neem per apparaat het kleinste getal en snij je blokken daarop. Let ook op de grens die over tijd gaat in plaats van over blokgrootte: bij de NIBE S-serie kost 60 registers per seconde al 60 procent van het budget. En groot is niet altijd beter. De maximale Eastron-blokread van 80 registers duurt bij 9600 baud 206,25 ms aan bustijd, dus tien meters op die blokgrootte kosten samen ruim twee seconden per ronde. Wat je mag lezen is bovendien niet hetzelfde als wat er bestaat: een blok dat over een gat in de registerkaart loopt kan exception 02 opleveren.
Wat een dood apparaat met je cyclus doet
Dat verdubbelt je cyclus bijna, in zijn eentje. Neem dezelfde tien meters met een cyclus van 979 ms en haal meter 7 eruit, zekering los of klem eraf. De client stuurt zijn verzoek en wacht de volle response timeout af. De standaard noemt bij 9600 bps een gebruikelijke timeout van 1 seconde tot enkele seconden.
9 werkende meters x 97,92 ms + 1 timeout van 1000 ms = 1.881 ms
Van 0,98 naar 1,88 seconde. Doet je client drie retries voordat hij opgeeft, dan wordt het 881 + 3000 = 3.881 ms, bijna vier keer zo traag. Dat is de gebruikelijke verklaring voor de klacht dat sinds vorige week alles traag is.
Drie maatregelen horen daarbij. Zet de response timeout niet hoger dan nodig: meet de antwoordtijd van je traagste apparaat en neem daar een marge van drie op. Laat je client een niet-reagerend apparaat tijdelijk overslaan, bijvoorbeeld na drie mislukte cycli nog een keer per minuut. En alarmeer apart op "apparaat reageert niet", want dat voorspelt de waarden die daarna wegvallen. Hoe je apparaten over een bus verdeelt en adresseert, staat in de les over meerdere apparaten op een bus.
Op TCP rekent het anders
Daar is de kabel niet de rem maar het apparaat. Op Modbus TCP vervalt de verplichte stilte tussen frames, de MBAP header kost 7 bytes tegen 3 bytes adres en CRC op RTU, en de standaard staat toe dat een client meerdere verzoeken naar dezelfde server stuurt zonder op een antwoord te wachten, 1 tot 16 tegelijk. De frametijd verdwijnt daarmee praktisch uit je som.
Wat overblijft zijn apparaatlimieten. SolarEdge accepteert 1 gelijktijdige Modbus TCP-verbinding en sluit een sessie na 2 minuten inactiviteit, dus daar moet je pollinterval onder blijven. SMA houdt zijn 10 seconden aan, ook over ethernet, en de NIBE S-serie zijn 100 registers per seconde. Wat een cloudplatform daarbovenop nog aan pollcadans oplegt, staat in de uitleg over Modbus monitoring via de cloud.
Een uitzondering die veel mensen over het hoofd zien: achter een RTU-over-TCP gateway geldt de RTU-som onverkort, want daarachter hangt nog steeds een bus van 9600 baud. "We zitten nu op ethernet, dus het is snel" klopt daar niet, ook niet als de verbinding naar die gateway over 4G loopt. Wat zo'n verbinding wel en niet oplost, staat in het artikel over 4G Modbus gateways.
Veelgemaakte fouten
Elk register los uitlezen. Wie per meetwaarde een verzoek stuurt, betaalt 20 karaktertijden vaste overhead per waarde. Bij twee registers per transactie is 83 procent van je bustijd overhead, bij vierentwintig registers nog 29 procent. Voeg opeenvolgende registers samen tot een blokread en kijk daarna pas naar de baudrate.
Zo snel mogelijk pollen voor de zekerheid. Op 97,9 procent busbelasting is er geen ruimte meer voor een retry en laat elke hapering een gat in je data achter. Reken je cyclus uit en kies een interval van minstens twee keer die tijd.
De limiet van de fabrikant negeren. SMA vraagt minstens 10 seconden tussen datatransfers. Sneller pollen levert geen betere data op, alleen wisselvalliger. Zoek per apparaat de kleinste grens op.
Een uitgevallen apparaat in de cyclus laten staan. Met een timeout van 1 seconde en drie retries kost een dood apparaat 3 seconden per ronde, meer dan de negen werkende meters samen. Laat je client zo'n apparaat na een paar mislukte cycli tijdelijk overslaan.
Aan de slag
Je rekent je eigen installatie door en past het pollinterval aan op de uitkomst.
- 1
Tel registers en verzoeken
Noteer per apparaat hoeveel registers je nodig hebt en hoeveel losse leesopdrachten je client daar nu voor doet.
- 2
Reken een transactie uit
Neem 20 karaktertijden vaste overhead en tel er 2 karaktertijden per register bij op. Vermenigvuldig met de karaktertijd van je baudrate, bij 9600 baud 1,1458 ms.
- 3
Tel op tot een cyclustijd
Tel de transacties van alle apparaten bij elkaar en reken per verzoek een verwerkingstijd mee. Zolang je die niet gemeten hebt is dat een aanname, dus noteer welke waarde je koos.
- 4
Deel door je pollinterval
Kom je boven de 50 procent uit, dan is er werk te doen.
- 5
Voeg reads samen en reken opnieuw
Maak van opeenvolgende losse reads een blokread, binnen de grens van dat apparaat, en kijk hoeveel je wint.
- 6
Meet het na
Laat mbpoll een minuut doorpollen zonder
-1en deel die minuut door het aantal pollcycli. mbpoll is gratis te gebruiken, ook zakelijk.
mbpoll -m rtu -a 1 -b 9600 -P none -t 4 -r 1 -c 24 /dev/ttyUSB0
Zonder hardware. Reken het voorbeeld uit deze les na: tien meters, 24 registers per meter, 9600 baud. Kom je op ongeveer 0,98 s, en daarna op ongeveer 0,59 s bij 19200 baud? Verwacht resultaat: een uitgerekende cyclustijd, een onderbouwd pollinterval en minstens een plek waar losse reads een blokread zijn geworden.
Samenvatting
- De tijd van een Modbus RTU-transactie is (bytes verzoek + bytes antwoord + 7) maal 11 gedeeld door de baudrate, plus de verwerkingstijd van de server.
- De vaste overhead per FC03-transactie is 20 karaktertijden, dus tien meters met blokreads kosten ongeveer 0,98 seconde en dezelfde data met twaalf losse reads per meter ongeveer 5,7 seconden.
- Busbelasting is cyclustijd gedeeld door pollinterval, en deze cursus adviseert onder de 50 procent te blijven.
- Een uitgevallen apparaat met een timeout van 1 seconde tilt die cyclus van 0,98 naar 1,88 seconde, en met drie retries naar 3,88 seconde.
- Op Modbus TCP is niet de bustijd de rem maar de apparaatlimiet, terwijl achter een RTU-over-TCP gateway de RTU-som gewoon weer geldt.
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.