Embedded

ESP32 + Modbus RTU: What the Docs Don't Tell You

November 2, 2025 8 min

When I started using the ESP32-S3 as a Modbus RTU Master, I thought: "Read the protocol, add a library, done." Reality had other plans.

The Timing Problem

Modbus RTU requires a pause of at least 3.5 characters between frames. At 9600 baud, that's about 4 milliseconds. Sounds trivial — until FreeRTOS intervenes. A task switch at the wrong moment, and the slave interprets two connected frames as separate messages.

Solution: Dedicated UART task with highest priority and vPortEnterCritical() for time-critical sequences. Not pretty, but reliable.

Half-Duplex Is Tricky

RS485 shares one line for sending and receiving. The ESP32 must toggle the DE/RE pin (Driver Enable) at exactly the right moment — after the last sent byte, but before the slave response.

The problem: The UART TX buffer reports "done" while the last byte is still in the shift register. Switch to receive immediately, and the last byte is lost.

Solution: Insert a short delay after TX complete (dependent on baud rate) before switching to RX.

247 Devices, One Bus

In theory, Modbus supports 247 slaves. In practice, things get tight above 30 devices — not because of the protocol, but because of electrical signal quality. Termination resistors, cable length, and stub lines make the difference.

Conclusion

Modbus RTU is a robust protocol — if you know the pitfalls. The official docs describe the "what", but rarely the "why". For production systems, you need experience, patience, and a good oscilloscope.

ESP32ModbusEmbedded
All articles