This repository hosts a Modbus Master library implemented in C++ for Embarcadero C++Builder and RAD Studio. The library supports Modbus RTU, Modbus TCP/UDP and a dummy protocol. It provides a protocol-agnostic API for reading and writing Modbus registers and coils from a master application.
Modbus.h: core types, exceptions,ContextandMaster::Protocolinterface.ModbusRTU.*: implementation of Modbus RTU over serial (CommPorthelper, CRC, frame format).ModbusTCP_IP.*: Modbus TCP/BMAP frame layer with validation and parsing.ModbusTCP_Indy.*,ModbusUDP_Indy.*: Indy-based TCP/UDP transport classes.ModbusDummy.*: no-op implementation for testing.CommPort.*: serial control layer for RTU.SerEnum.*: serial port enumeration utilities.
Encapsulates slave unit ID and transaction identifier for request/response correlation.
SlaveAddrType: uint8_tTransactionIdType: uint16_t
Abstract base class exposing:
Open()/Close()/IsConnected()GetProtocolName()/GetProtocolParamsStr()ReadHoldingRegisters(),ReadInputRegisters()PresetSingleRegister(),PresetMultipleRegisters(),MaskWrite4XRegister()
SessionManager RAII wrapper ensures connection lifecycle.
- Read holding/input registers
- Preset single/multiple registers
- Mask write registers
- Standard exceptions: IllegalFunction, IllegalDataAddress, IllegalDataValue, SlaveDeviceFailure, etc.
Modbus::Master::RTUProtocol- Serial config:
CommPort,CommSpeed,CommParity,CommBits,CommStopBits. - Retries via
RetryCount; timeout viaTimeoutValue. - CRC-16 and frame-level logic.
Modbus::Master::TCPIPProtocolBMAP layerModbus::Master::TCPProtocolIndy(TCP)Modbus::Master::UDPProtocolIndy(UDP)- Defaults: host
localhost, port502.
Modbus::Master::DummyProtocol- No actual transport; useful for unit tests and placeholder behavior.
Use this to test read/write operations against a Modbus slave.
Example:
#include "ModbusTCP_Indy.h"
#include "Modbus.h"
using namespace Modbus;
using namespace Modbus::Master;
int main() {
TCPProtocolIndy master("192.168.0.10", 502);
SessionManager session(master);
Context ctx(1, 1); // slave address 1, transaction 1
RegDataType regs[10];
master.ReadHoldingRegisters(ctx, 0, 10, regs);
for (int i = 0; i < 10; ++i) {
printf("R[%d]=%u\n", i, regs[i]);
}
master.PresetSingleRegister(ctx, 0, 12345);
return 0;
}For a server-demo, run an emulator or physical slave, then connect from the client.
- Use Modbus slave tools like
modbuspoll,mbslave,CAS Modbus Scanner. - For RTU, use virtual COM ports or actual serial.
- Emulate holding registers and validate client reads/writes.
- Start slave emulator/device.
- Run client demo.
- Verify register reads match expected values.
- Validate writes by reading registers back.
- Target C++Builder / RAD Studio (Windows).
- Add all sources to project:
Modbus.h/cpp,ModbusRTU.*,ModbusTCP_IP.*,ModbusTCP_Indy.*,ModbusUDP_Indy.*,ModbusDummy.*,CommPort.*,SerEnum.*. - Required Indy units:
IdTCPClient,IdUDPClient,IdIOHandler,IdIOHandlerSocket. - Optional:
boost::crcfor RTU CRC. - C++17 compatible compiler settings are recommended.
- Use Modbus slave simulator to verify opearations.
- Create small harness for protocol validation and exception cases.
- Fork, implement features in protocol abstraction.
- Add tests under the same module.
- Keep existing API stability.
MIT (see LICENSE).