Polling Modbus RTU slaves with timeouts and 32-bit values
A Modbus RTU master on an ESP32 PLC opens the door to everything hanging off the RS-485 bus: energy meters, drives, machine controllers. This example wraps the whole transaction in one generic function — peticionModbusFC3(slave, address, count, timeout) — that returns a vector of registers or an empty one on failure, plus helpers to combine register pairs into 32-bit values. It comes straight from a real textile machine monitoring deployment.
One generic function for every read
Instead of scattering request and response handling through the firmware, a single function sends the FC3 read, waits for the reply inside a bounded loop, and returns a std::vector of registers. Empty vector means error or timeout — the caller checks the size and moves on. Adding a new device to poll becomes one line, not a new state machine.
Timeouts keep the bus from owning your loop
An unplugged or powered-off slave is normal life on a factory bus, not an exception. The response wait is capped at a configurable timeout (200 ms here), so the worst case is a short, bounded pause instead of a frozen monitoring node. The function returns on the first complete response — good or error — and the rest of the firmware, pulse counting included, keeps running untouched.
Two registers, one 32-bit value
Modbus registers are 16 bits wide, but the values actually worth logging — totalizers, energy counters, accumulated production — are almost always 32. regsToU32() shifts the high word left and ORs in the low word; regsToS32() reinterprets the same bit pattern as two's complement for signed quantities like power flow. Word order varies between vendors, with some sending the low word first, so the helpers keep the big-endian assumption explicit in one place and trivial to flip per device.
A snippet from the implementation
Straight from the example as deployed on the ESP32 PLC — copy it freely:
The full example is a complete program — wiring header, setup and main loop — ready to adapt to your application.
Frequently asked questions
How many slaves can I put on one RS-485 bus?
Modbus RTU allows up to 247 addresses, and 32 devices per segment without repeaters is the practical RS-485 limit. Poll them sequentially with the same function, one slave ID at a time.
My 32-bit values look wrong — why?
Almost always word order. Some vendors send the low word first. Swap the arguments to regsToU32() or add a little-endian variant; the bytes within each register are defined by Modbus and rarely the issue.
Can the same PLC also publish this data over MQTT?
Yes — that is the production setup. The Modbus poll fills a JSON document that the MQTT module publishes and the SD module buffers offline, so meter data gets the same offline-first treatment as machine inputs.