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
rtuovertcp: het verschil, en wat je gateway doet
Het verschil tussen rtuovertcp en echt Modbus TCP kost veel mensen een hele avond. Leer wat een gateway met je frame doet en kies daarna bewust RTU of TCP.
Wat deze les behandelt
- De bytes die rtuovertcp van echt Modbus TCP onderscheiden
- Wat een gateway met de unit id en de CRC doet, en wat hij laat staan
- De keuze tussen RTU en TCP, en de foutbeelden die een gateway toevoegt
Lees eerst: Het Modbus RTU frame byte voor byte, plus CRC, Poort 502, de MBAP header en de unit id, Modbus TCP in je netwerk: IP, VLAN, firewall
rtuovertcp is geen tweede protocol, maar een RTU-frame dat ongewijzigd door een TCP-verbinding wordt geduwd: serveradres vooraan, CRC-16 achteraan, en geen MBAP-header. Echt Modbus TCP doet het precies andersom. Na deze les zie je aan de bytes met welke van de twee je te maken hebt, weet je wat een gateway met je frame en met je unit id doet, en kies je in je client de stand die werkt.
Twee bytestromen die er hetzelfde uitzien
Ze lijken alleen op elkaar zolang je niet naar het begin en het eind kijkt. Dit is het verzoek "lees drie holding registers vanaf PDU-adres 107 bij serveradres 1", zoals echt Modbus TCP het over poort 502 stuurt:
00 01 00 00 00 06 FF 03 00 6B 00 03
Twaalf bytes. En dit is hetzelfde verzoek als RTU-frame, zoals het over RS485 gaat en zoals een eenvoudige seriële server het ongewijzigd door een TCP-verbinding duwt:
01 03 00 6B 00 03 74 17
Acht bytes. In allebei staan in het midden dezelfde vijf bytes: 03 00 6B 00 03. Dat is de PDU (protocol data unit): function code FC03, startadres 0x006B (PDU-adres 107, op een datasheet meestal het 1-gebaseerde nummer 40108) en het aantal 3. Alleen de verpakking verschilt.
| Echt Modbus TCP | RTU-frame door TCP | |
|---|---|---|
| Voor de PDU | MBAP header, 7 bytes | serveradres, 1 byte, hier 01 |
| Na de PDU | niets | CRC-16, 2 bytes, hier 74 17, low byte eerst |
| Totale lengte | 12 bytes | 8 bytes |
| Berichtgrens | het Length-veld in de header | 3,5 karaktertijden stilte op de seriële kant |
Home Assistant: type tcp tegenover type rtuovertcp
Voor de volledige afweging tussen beide transporten is de vergelijking van Modbus RTU en Modbus TCP de naslagpagina; deze les gaat over de bytes.
Wat een gateway precies doet met je frame
Uitpakken en opnieuw inpakken, meer niet. Een gateway die echt vertaalt, doorloopt per verzoek deze route:
- Hij accepteert je TCP-verbinding op poort 502, leest de MBAP-header en onthoudt de transaction id.
- Hij gooit die header weg en houdt de PDU over:
03 00 6B 00 03. - Hij zet de unit id uit de header ervoor als serveradres, rekent de CRC-16 over adres plus PDU uit en plakt die erachter. Vraag je unit id 1, dan staat er nu
01 03 00 6B 00 03 74 17op de bus. - Op de RS485-kant is hij zelf de client: hij zet het frame op de bus en wacht op antwoord of op zijn eigen timeout.
- Komt het antwoord, dan controleert hij de CRC, haalt adres en CRC eraf en bouwt de MBAP-header terug, met een Length die hij zelf uitrekent.
De unit id is dus geen decoratie. Bij een apparaat dat rechtstreeks aan het netwerk hangt vul je 0xFF in (255), of 0x00, omdat het IP-adres het apparaat al aanwijst. Achter een gateway is de unit id het echte serveradres op de bus, ergens tussen 1 en 247. Hoe je dat aan de kant van het kastje inricht, staat in de handleiding voor het installeren van een Modbus TCP gateway.
Waarom rtuovertcp bestaat
Omdat niet elk kastje met een netwerkpoort protocolvertaling doet. Een deel van de apparaten die je op een RS485-bus tegenkomt zijn seriële servers (in het Engels device server of serial server): ze nemen alles wat op de TCP-verbinding binnenkomt en zetten het byte voor byte op de seriële poort, en andersom. Ze kijken niet in het frame, ze kennen de MBAP-header niet, en ze rekenen geen CRC uit. Dat is goedkoper te bouwen en werkt ook voor protocollen die geen Modbus zijn.
Het gevolg is dat jouw client het werk doet dat de gateway niet doet: je stuurt een compleet RTU-frame met serveradres en CRC-16, zonder MBAP-header eromheen. Dat kost je ook de transaction id, dus je kunt geen twee verzoeken tegelijk laten lopen op die verbinding. Je vraagt, wacht op antwoord of timeout, en gaat pas dan verder, precies zoals op de bus zelf. Hoe die verbinding zich op je netwerk gedraagt, staat in de les over netwerkeisen, firewall en VLAN.
Welke instelling kies je in je client?
De stand die past bij wat er uit het apparaat komt, niet bij de kabel die erin gaat. In Home Assistant is dat het veld type in de modbus-integratie:
modbus:
- name: gateway
type: rtuovertcp
host: 192.168.1.50
port: 502
Het symptoom van de verkeerde keuze is herkenbaar: ping werkt, de poorttest slaagt, en toch lukt geen enkele lezing. Niemand klaagt namelijk. Zet je rtuovertcp tegen een apparaat dat echt Modbus TCP spreekt, dan leest dat apparaat jouw 01 03 als transaction id en 00 6B als protocol id. Dat is niet 0x0000, dus gooit het het bericht stilzwijgend weg zonder exception. Andersom zet de seriële server jouw MBAP-header gewoon op de bus, waar geen enkel apparaat er een geldige CRC in herkent.
Wanneer kies je RTU en wanneer TCP?
Zes situaties waarin de keuze zich vanzelf maakt:
| Situatie | Wat dat betekent |
|---|---|
| Er ligt al een werkende RS485-bus | RTU houden. Een gateway erbij is goedkoper dan alles opnieuw trekken |
| Meer dan 1000 m tussen client en apparaat bij 9600 baud | TCP. De standaard noemt 1000 m als maximale stamkabellengte bij 9600 baud met AWG26 of dikker |
| Meer dan 32 apparaten op één segment | TCP, of segmenteren met een repeater. 32 apparaten zonder repeater zijn altijd toegestaan |
| Het apparaat heeft alleen klemmen voor A, B en common | RTU, eventueel met een gateway ernaast |
| Er ligt al ethernet tot bij het apparaat | TCP, dan heb je geen extra kabel nodig |
| Meerdere systemen moeten hetzelfde apparaat uitlezen | TCP, want op een RS485-bus verdeelt een enkele client het woord |
De complete afweging inclusief kosten en beheer staat in de vergelijking van Modbus RTU en Modbus TCP, en welk kastje bij welke situatie past in de koopgids voor Modbus gateways.
Wat je met een gateway erbij krijgt aan foutbeelden
Twee exception codes die je zonder gateway nooit ziet, want ze komen van de gateway zelf. De standaard kent er negen (01 tot en met 06, 08, 0A en 0B), en juist deze twee staan er expliciet in als "specialized use in conjunction with gateways".
- Exception 0A, Gateway Path Unavailable. De gateway kon intern geen pad van zijn netwerkpoort naar zijn seriële poort vrijmaken. Meestal verkeerd geconfigureerd of overbelast door te veel gelijktijdige polls.
- Exception 0B, Gateway Target Device Failed To Respond. De gateway heeft je verzoek wel op de bus gezet, maar dat serveradres antwoordde niet. Dit is de TCP-vertaling van een seriële timeout, dus controleer serveradres, bedrading, baudrate en pariteit.
Zo ziet een 0B eruit op unit id 9, opgebouwd volgens de regels van de standaard:
00 01 00 00 00 03 09 83 0B
Length is 0x0003 (1 byte unit id plus 2 bytes PDU), de function code is 0x83 (0x03 plus 0x80) en de laatste byte is exception 0B. Krijg je in plaats daarvan helemaal niets, dan komt je verzoek niet eens tot de bus. Hoe je een frame byte voor byte uit elkaar haalt, staat in de les over het RTU-frame en de CRC.
Veelgemaakte fouten
tcp instellen waar rtuovertcp nodig is. Ping werkt, de poort staat open, en toch lukt geen enkele lezing. Dat is het handtekeningbeeld van deze fout. Wissel de stand om voordat je iets anders aanraakt, en verander verder niets.
Unit id 255 gebruiken achter een gateway. Achter een gateway is de unit id het echte serveradres tussen 1 en 247, geen betekenisloze vulwaarde. Met 255 vraag je naar een gereserveerd adres, en dat levert exception 0B of stilte op. Zoek het adres op de meter zelf op.
De gateway als onzichtbaar beschouwen. Hij is de client op de RS485-bus, met een eigen timeout en een eigen pollgedrag. Zet je er te veel gelijktijdige verzoeken in, dan krijg je exception 0A terug van een kastje dat je niet in je diagnose had staan.
RTU vervangen door TCP en de bus laten liggen. Een gateway lost netwerkbereik op, geen bekabelingsproblemen. Een slecht getermineerde bus blijft na de gateway net zo slecht getermineerd, alleen zie je de fout nu als exception 0B in plaats van als timeout.
Aan de slag
Je legt dezelfde vraag in twee verpakkingen naast elkaar en kijkt welke van de twee jouw gateway wil.
- 1
Schrijf het RTU-frame op
Noteer het verzoek "lees drie holding registers vanaf PDU-adres 107 bij serveradres 1" in RTU-vorm:
01 03 00 6B 00 03 74 17. Omcirkel de PDU. - 2
Schrijf hetzelfde verzoek in TCP-vorm
Dat wordt
00 01 00 00 00 06 FF 03 00 6B 00 03. Omcirkel ook hier de PDU, en leg de twee onder elkaar zodat de omcirkelde delen uitlijnen. - 3
Tel de bytes
8 tegen 12. Het verschil is 7 bytes header eraf en 1 byte adres plus 2 bytes CRC erbij, dus 12 min 7 plus 3 is 8. Klopt de som, dan heb je de envelop begrepen.
- 4
Zet je client een keer in elke stand
Heb je een gateway: configureer je client eerst als
tcp, daarna alsrtuovertcp, en noteer welke van de twee antwoord geeft. Verander verder niets, want anders weet je achteraf niet waardoor het ging werken. - 5
Vraag een adres op dat niet bestaat
Zet de unit id op een adres dat niet op de bus zit en noteer wat je krijgt. Exception 0B betekent dat de gateway meedenkt en het verzoek echt op de bus heeft gezet. Een kale timeout betekent dat hij alleen doorlust.
Zonder gateway. Stap 1 tot 3 hebben geen hardware nodig. Voor stap 4 en 5 kun je in de les over de MBAP header en de unit id hetzelfde frame in de builder zetten en de bytes vergelijken met het RTU-frame hierboven.
Verwacht resultaat: twee frames naast elkaar met in allebei dezelfde vijf PDU-bytes gemarkeerd, en de wetenschap welke verbindingsvorm jouw gateway wil.
Samenvatting
- Echt Modbus TCP zet een MBAP-header van 7 bytes voor de PDU en heeft geen CRC; een getunneld RTU-frame heeft juist een serveradres van 1 byte ervoor en een CRC-16 van 2 bytes erachter.
- Hetzelfde leesverzoek is 12 bytes over Modbus TCP en 8 bytes als RTU-frame, met in het midden allebei dezelfde PDU
03 00 6B 00 03. - Een gateway verandert niets aan de PDU: hij vervangt alleen de envelop, en de unit id uit de MBAP-header wordt het serveradres op de RS485-bus.
- Achter een gateway vul je een unit id tussen 1 en 247 in, bij een apparaat dat rechtstreeks aan het netwerk hangt
0xFFof0x00. - Exception 0A en exception 0B komen van de gateway zelf: 0A betekent dat hij intern geen pad vrij kreeg, 0B dat er op de bus niemand antwoordde.
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.