This Modbus RTU slave library uses callbacks to handle modbus requests for one or multiple slave ids. Handler functions are called on modbus a request, and the users can implement them within their sketch.
Register a handler function:
slave.cbVector[CB_READ_INPUT_REGISTERS] = ReadAnalogIn;
Implement it:
void ReadAnalogIn(uint8_t fc, uint16_t address, uint16_t length) {
for (int i = 0; i < length; i++)
slave.writeRegisterToBuffer(i, analogRead(address + i));
}
And thats it, your sketch is modbus enabled. (see the full examples for more detail)
Download the zip package, and install it into your Arduino IDE. See the Arduino tutorial about installing 3rd party libraries: https://www.arduino.cc/en/Guide/Libraries#toc4
Users register handler functions into the callback vector of the slave.
This can be done independently for one or multiple slaves with different IDs.
The callback vector has 7 slots for request handlers:
A handler functions must return an uint8_t code and take the following as parameters:
Usable return codes:
#include <ModbusSlave.h>
// Implicitly set stream to use the Serial serialport.
Modbus slave(1, 8); // [stream = Serial,] slave id = 1, rs485 control-pin = 8
void setup() {
// Register functions to call when a certain function code is received.
// If there is no handler assigned to the function code a valid but empty message will be replied.
slave.cbVector[CB_WRITE_COILS] = writeDigitalOut;
// Start the slave at a baudrate of 9600bps on the Serial port.
Serial.begin(9600);
slave.begin(9600);
}
void loop() {
// Listen for modbus requests on the serial port.
// When a request is received it's going to get validated.
// And if there is a function registered to the received function code, this function will be executed.
slave.poll();
}
// Handel Force Single Coil (FC=05).
uint8_t writeDigitalOut(uint8_t fc, uint16_t address, uint16_t length) {
if (slave.readCoilFromBuffer(0) == HIGH)
{
digitalWrite(address, HIGH);
}
else
{
digitalWrite(address, LOW);
}
return STATUS_OK;
}
#include <ModbusSlave.h>
// Explicitly set a stream to use the Serial port.
Modbus slave(Serial, 1, 8); // stream = Serial, slave id = 1, rs485 control-pin = 8
void setup() {
// Register functions to call when a certain function code is received.
// If there is no handler assigned to the function code a valid but empty message will be replied.
slave.cbVector[CB_WRITE_COILS] = readAnalogIn;
// Start the slave at a baudrate of 9600bps on the Serial port.
Serial.begin(9600);
slave.begin(9600);
}
void loop() {
// Listen for modbus requests on the serial port.
// When a request is received it's going to get validated.
// And if there is a function registered to the received function code, this function will be executed.
slave.poll();
}
// Handle Read Input Registers (FC=04).
uint8_t readAnalogIn(uint8_t fc, uint16_t address, uint16_t length) {
// Write the result of analogRead() into the response buffer.
for (int i = 0; i < length; i++) {
slave.writeRegisterToBuffer(i, analogRead(address + i));
}
return STATUS_OK;
}