Skip to content
A library that allows your ESP8266/ESP32 to communicate via Modbus protocol, acting as a master, slave or both. Supports IP via wireless network (Modbus IP) and RTU via Serial line (Modbus RTU).
Branch: master
Clone or download
Pull request Compare This branch is 178 commits ahead of andresarmento:master.

ModbusRTU and ModbusIP Master-Slave Library for ESP8266/ESP32 v3.0

If this project is helpfull for you projects you can give me a glass of beer paypal

Release state: DEVELOPMENT Everything including API is subject to be changed during this stage.

Visit Releases page for stable one.

This library allows your ESP8266/ESP32 to communicate via Modbus protocol. The Modbus is a master-slave protocol used in industrial automation and can be used in other areas, such as home automation.

The Modbus generally uses serial RS-232 or RS-485 as physical layer (then called Modbus Serial) and TCP/IP via Ethernet or WiFi (Modbus IP).

In the current version the library allows the ESP8266/ESP32 operate as a master and/or slave, supporting Modbus IP via wireless network and Modbus RTU over serial. For more information about Modbus see:


  • Supported platforms are
    • ESP8266
    • ESP32
  • Operates as
    • slave
    • master
  • Supports
    • Modbus IP (TCP)
    • Modbus RTU (RS-485)
  • Reply exception messages for all supported functions
  • Modbus functions supported:
    • 0x01 - Read Coils
    • 0x02 - Read Input Status (Read Discrete Inputs)
    • 0x03 - Read Holding Registers
    • 0x04 - Read Input Registers
    • 0x05 - Write Single Coil
    • 0x06 - Write Single Register
    • 0x0F - Write Multiple Coils
    • 0x10 - Write Multiple Registers
  • Callbacks for
    • Master connect (ModbusIP)
    • Master/Slave disconnect (ModbusIP)
    • Read specific Register
    • Write specific Register
    • Slave transaction finish


  1. The offsets for registers are 0-based. So be careful when setting your supervisory system or your testing software. For example, in ScadaBR offsets are 0-based, then, a register configured as 100 in the library is set to 100 in ScadaBR. On the other hand, in the CAS Modbus Scanner offsets are 1-based, so a register configured as 100 in library should be 101 in this software.
  2. For API refer
  3. Modbus RTU maximum incoming frame size is determinated by HardwareSerial buffer size. For SoftwareSerial buffer must be set to 256 bytes.
  4. Probably it's possible to use ModbusRTU with other AVR boards using from Standard C++ for Arduino (port of uClibc++).
  5. RS-485 transivers based on MAX-485 is working on at least up to 57600. XY-017/XY-485 working only up to 9600 for some reason.

Last Changes

// 3.0.0-DEVEL
+ ModbusRTU Slave
+ ModbusRTU Master
+ Registers are now shared between Modbus* instances by default
+ Fix functions register count limits to follow Modbus specification (or RX buffer limitations)
+ ModbusRTU examples added
+ CRC tables stored in PROGMEM
+ TX control pin support to work with MAX-485
- Test multiple Modbus* instances
+ Change to 'uint32_t eventSource()'. Implemented for ModbusRTU and ModbusIP both.
+ Documentation changes
+ Allow to specify local TCP port for Slave (default is 502)
+ Allow to specify TCP port for remote Slave connection (default is 502)
// ToDo later
- 0x14 - Read File Records function
- 0x15 - Write File Records function
- 0x16 - Write Mask Register function
- 0x17 - Read/Write Registers function
- 0x08 - Serial Diagnostics functions
// 2.1.0
+ Slave. Fix error response on write multiple Hregs\Coils
+ Slave. Fix writeCoil() for multiple coils
+ Master. dropTransactions()
+ Master. disconnect()
+ ~ModbusIP()
+ task() cleanup
+ Modify examples
+ Slave. Allow only single incoming master connection per IP
// 2.0.1
+ Master. Fix readCoil\Hreg\Ists\Ireg not read value from slave
+ Fix crash on disconnect with Arduino Core 2.5.x
// 2.0.0
+ Remove memory allocation checking for small blocks as anyway firmware will fail if so low memory available.
+ Change object's list implementation to *std::vector*
+ Modbus class refactoring
+ ModbusIP networking code refactoring and error reporting
+ Global registers storage to share between multiple Modbus* instances
+ Move rest of implementations from Modbus.h
+ Modbus master implementation
+ Move enum constants. E.g. MB_FC_READ_COIL => Modbus::FC_READ_COIL
+ Back to marking private for onSet, onGet, addReg and Reg methods
+ Added callback-related eventSource method, onDisconnect and transaction result callbacks
+ Extend register addressing to 0..65535
+ removeCoil, removeIsts, removeIreg, removeHreg, (removeReg)
+ readCoil, readHreg, readIsts, readIreg
+ push\pullCoil, push\pullHreg, pullIsts, pullIreg
+ pullCoilToIsts, pullHregToIreg, pushIstsToCoil, pushIregToHreg
+ optimize code around std::vector processing
+ extend removeCoil/Hreg/... to remove multiple registers
+ multiple callbacks => memory usage optimization
+ added removeOnSetCoil\... methods
+ added read/write/push/pullCoil/Hreg/Ireg/Ists() parameter to specify Modbus unit id
+ added ability to auto connect to slave. Setting is global. Disabled by default.


Original version:

prof (at) andresarmento (dot) com


The code in this repo is licensed under the BSD New License. See LICENSE.txt for more info.

You can’t perform that action at this time.