A complete Modbus RTU communication project implemented from scratch using an Arduino Mega 2560 (Master) and an ESP32 (Slave) over RS485 (MAX485).
This project focuses on understanding the Modbus RTU protocol at the frame level rather than relying on external Modbus libraries. Every Modbus frame, CRC calculation, UART transmission, and response parsing is implemented manually.
Modbus_Project/
│
├── README.md
├── .gitignore
│
├── 01_Modbus_RTU/
│ ├── 01_Modbus_RTU.ino
│ ├── uart.cpp
│ ├── uart.h
│ ├── rs485.cpp
│ ├── rs485.h
│ ├── modbus.cpp
│ ├── modbus.h
│ ├── crc16.cpp
│ ├── crc16.h
│ └── README.md
│
├── 01_Modbus_RTU_Slave/
│ ├── 01_Modbus_RTU_Slave.ino
│ ├── uart.cpp
│ ├── uart.h
│ ├── rs485.cpp
│ ├── rs485.h
│ ├── slave.cpp
│ ├── slave.h
│ ├── crc16.cpp
│ ├── crc16.h
│ └── README.md
│
├── captures/
│ ├── rs485_uart_verification.sr
│ ├── rs485_uart_verification.pvs
│ ├── modbus_rtu_frame_verification.sr
│ ├── modbus_rtu_frame_verification.pvs
│ ├── modbusRTU_request_response_verification.sr
│ └── modbusRTU_request_response_verification.pvs
│
└── images/
├── modbus_rtu_complete_hardware_setup.png
├── modbus_rtu_request_logic_analyzer.png
├── modbusRTU_request_response_verification.png
└── rs485_uart_waveform_decoded.png
- Arduino Mega 2560 (Master)
- ESP32 DevKit V1 (Slave)
- 2 × MAX485 RS485 Modules
- USB Logic Analyzer (24 MHz)
- PulseView (Sigrok)
- Breadboard & Jumper Wires
The hardware consists of:
- Arduino Mega acting as the Modbus Master
- ESP32 acting as the Modbus Slave
- Two MAX485 transceivers
- USB Logic Analyzer connected for UART frame verification
Arduino Mega
│
│ UART1
▼
MAX485 Module
│
====== RS485 Bus ======
│
MAX485 Module
▼
ESP32
Before implementing Modbus RTU, UART communication through the MAX485 transceivers was verified using a USB Logic Analyzer.
Verified:
- UART timing
- Baud Rate
- Start Bit
- Stop Bit
- Byte Order
- Correct waveform
The master constructs the Modbus RTU request frame manually.
Request sent:
01 03 00 00 00 02 C4 0B
Meaning:
| Byte | Description |
|---|---|
| 01 | Slave Address |
| 03 | Read Holding Registers |
| 00 00 | Start Address |
| 00 02 | Quantity |
| C4 0B | CRC16 |
Logic Analyzer verification:
Both request and response were captured and decoded using PulseView.
Master Request
01 03 00 00 00 02 C4 0B
Slave Response
01 03 04 04 D2 16 2E D5 46
Decoded values:
Register 1 = 1234
Register 2 = 5678
- Manual Modbus RTU implementation
- Manual CRC16 calculation
- Manual UART frame generation
- Manual frame parsing
- MAX485 direction control
- Request/Response verification
- Logic Analyzer verification
- PulseView captures included
- Arduino IDE
- PulseView
- Sigrok
- USB Logic Analyzer
- Git
- GitHub
- Embedded C++
- UART Communication
- RS485 Communication
- Modbus RTU Protocol
- CRC16 Implementation
- Protocol Debugging
- Logic Analyzer Usage
- Embedded System Verification
| Folder | Description |
|---|---|
| 01_Modbus_RTU | Arduino Mega Modbus Master |
| 01_Modbus_RTU_Slave | ESP32 Modbus Slave |
| captures | PulseView capture sessions |
| images | Project screenshots |
| README.md | Project overview |
- Multiple Slave Devices
- Function Code 06
- Function Code 16
- Exception Responses
- Modbus Poll Compatibility
- Industrial PLC Testing
Varun Bhandekar
GitHub:
This project was implemented for learning industrial communication protocols by developing the complete Modbus RTU stack from scratch without using third-party Modbus libraries.



