#include /* Baud rate for UART */ #define BAUD 9600 /* * To match the parameters of HardwareSerial Rx/Tx functions with the Modbus * functions, wrappers around the ::read() and ::write() functions are * required */ MB_StatusTypeDef ArduinoSerial_Tx(void* serial, uint16_t* buf, uint8_t* len, uint8_t* timeout); MB_StatusTypeDef ArduinoSerial_Rx(void* serial, uint16_t* buf, uint8_t* len, uint8_t* timeout); MB_StatusTypeDef (*MB_UART_Tx)(void*, uint16_t*, uint8_t*, uint8_t*) = &ArduinoSerial_Tx; MB_StatusTypeDef (*MB_UART_Rx)(void*, uint16_t*, uint8_t*, uint8_t*) = &ArduinoSerial_Rx; /* Single modbus device node */ modbus_slave_device modbus_dev_single; /* Multiple modbus device nodes.. after all, what is the point of using Modbus * in a single point-to-point connection? */ /* Not illustrated beyond the definition, but should be clear enough */ modbus_slave_device modbus_dev_multiple[10]; uint16_t reg; void setup() { Serial.begin(BAUD); /* Set the slave ID to 1 */ modbus_dev_single.slave_id = 1; /* Attach the default HardwareSerial class instance to this node */ modbus_dev_single.modbus_uart = &Serial; /* Continuously read this input register in superloop */ reg = 30001; } void loop() { MB_StatusTypeDef status = ReadInputRegisters(&modbus_dev_single, reg, 1); if (status == MB_OK) { /* Do something with data in the response buffer */ /* ... */ ClearResponseBuffer(&modbus_dev_single); } } MB_StatusTypeDef ArduinoSerial_Tx(void* serial, uint16_t* buf, uint8_t* len, uint8_t* timeout) { HardwareSerial* _serial = static_cast(serial); if (_serial->availableForWrite()) { _serial->write((uint8_t)*buf); } _serial->flush(); /* HardwareSerial class funcs do not return any UART errors, sadly */ return MB_OK; } MB_StatusTypeDef ArduinoSerial_Rx(void* serial, uint16_t* buf, uint8_t* len, uint8_t* timeout) { HardwareSerial* _serial = static_cast(serial); buf = _serial->read(); /* HardwareSerial class funcs do not return any UART errors, sadly */ return MB_OK; }