### Initialize Serial and Modbus Library Source: https://github.com/cmb27/modbusrtuslave/blob/main/README.md For versions 2.x.x to 3.x.x, ensure the Serial object is initialized before initializing the Modbus library. This example shows the correct order for Serial1. ```C++ Serial1.begin(38400); modbus.begin(38400); ``` -------------------------------- ### Complete Modbus RTU Slave Example Source: https://context7.com/cmb27/modbusrtuslave/llms.txt Demonstrates all four Modbus data types (coils, discrete inputs, holding registers, input registers) with hardware integration for LEDs, buttons, and potentiometers. Configure Modbus data arrays and poll continuously in the loop. ```cpp #include // Serial port selection based on board type #if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega2560__) #define MODBUS_SERIAL Serial #else #define MODBUS_SERIAL Serial1 #endif const int dePin = 13; // RS-485 driver enable pin // Hardware pin assignments const int buttonPins[2] = {2, 3}; const int ledPins[4] = {5, 6, 7, 8}; const int knobPins[2] = {A0, A1}; // Create Modbus slave with RS-485 support ModbusRTUSlave modbus(MODBUS_SERIAL, dePin); // Modbus data arrays const uint8_t numCoils = 2; const uint8_t numDiscreteInputs = 2; const uint8_t numHoldingRegisters = 2; const uint8_t numInputRegisters = 2; bool coils[numCoils]; // Addresses 0-1: LED on/off control bool discreteInputs[numDiscreteInputs]; // Addresses 0-1: Button states uint16_t holdingRegisters[numHoldingRegisters]; // Addresses 0-1: PWM brightness uint16_t inputRegisters[numInputRegisters]; // Addresses 0-1: Potentiometer values void setup() { // Configure hardware pins pinMode(knobPins[0], INPUT); pinMode(knobPins[1], INPUT); pinMode(buttonPins[0], INPUT_PULLUP); pinMode(buttonPins[1], INPUT_PULLUP); for (int i = 0; i < 4; i++) { pinMode(ledPins[i], OUTPUT); } // Configure Modbus data arrays modbus.configureCoils(coils, numCoils); modbus.configureDiscreteInputs(discreteInputs, numDiscreteInputs); modbus.configureHoldingRegisters(holdingRegisters, numHoldingRegisters); modbus.configureInputRegisters(inputRegisters, numInputRegisters); // Initialize serial and Modbus (slave ID: 1, baud: 38400, config: 8N1) MODBUS_SERIAL.begin(38400, SERIAL_8N1); modbus.begin(1, 38400, SERIAL_8N1); } void loop() { // Read physical inputs into Modbus data arrays inputRegisters[0] = map(analogRead(knobPins[0]), 0, 1023, 0, 255); inputRegisters[1] = map(analogRead(knobPins[1]), 0, 1023, 0, 255); discreteInputs[0] = !digitalRead(buttonPins[0]); // Active low buttons discreteInputs[1] = !digitalRead(buttonPins[1]); // Process Modbus communication modbus.poll(); // Write Modbus data to physical outputs analogWrite(ledPins[0], holdingRegisters[0]); // PWM brightness from master analogWrite(ledPins[1], holdingRegisters[1]); digitalWrite(ledPins[2], coils[0]); // On/off from master digitalWrite(ledPins[3], coils[1]); } ``` -------------------------------- ### Initialize and Poll ModbusRTUSlave Source: https://github.com/cmb27/modbusrtuslave/wiki/poll() This example demonstrates how to initialize the ModbusRTUSlave object and continuously poll for incoming requests within the Arduino loop function. Ensure SoftwareSerial and ModbusRTUSlave libraries are included. ```cpp #include #include byte buf[256]; boolean coils[8]; SoftwareSerial mySerial(10, 11); ModbusRTUSlave modbus(mySerial, buf, 256); char coilRead(word address) { return coils[address]; } boolean coilWrite(word address, boolean value) { coils[address] = value; return true; } void setup() { mySerial.begin(38400); modbus.begin(1, 38400); modbus.configureCoils(8, coilRead, coilWrite); } void loop() { modbus.poll(); } ``` -------------------------------- ### ModbusRTUSlave Constructor Examples Source: https://context7.com/cmb27/modbusrtuslave/llms.txt Instantiate the ModbusRTUSlave object, specifying the serial port and optionally RS-485 driver enable pins. Ensure the serial port is compatible with your hardware. ```cpp #include // Basic setup with just serial port ModbusRTUSlave modbus(Serial1); ``` ```cpp #include // With RS-485 driver enable pin (goes HIGH when transmitting) const int dePin = 13; ModbusRTUSlave modbus(Serial1, dePin); ``` ```cpp #include // With both driver enable and receiver enable pins const int dePin = A6; const int rePin = A5; ModbusRTUSlave modbus(Serial1, dePin, rePin); ``` -------------------------------- ### Configure Modbus Slave Coils Source: https://github.com/cmb27/modbusrtuslave/wiki/configureCoils() Call `configureCoils` in `setup()` before `poll()` if coils are used. Requires user-defined `coilRead` and `coilWrite` functions. ```cpp #include #include byte buf[256]; boolean coils[8]; SoftwareSerial mySerial(10, 11); ModbusRTUSlave modbus(mySerial, buf, 256); char coilRead(word address) { if (address < 8) return coils[address]; else return -1; } boolean coilWrite(word address, boolean value) { if (address < 8) { coils[address] = value; return true; } else return false; } void setup() { mySerial.begin(38400); modbus.begin(1, 38400); modbus.configureCoils(8, coilRead, coilWrite); } void loop() { modbus.poll(); } ``` -------------------------------- ### begin() Method Source: https://context7.com/cmb27/modbusrtuslave/llms.txt Initializes the Modbus slave with a device ID and communication parameters. This method must be called after configuring data arrays and initializing the serial port. ```APIDOC ## begin() Initializes the Modbus slave with a unique device ID and communication parameters. The slave ID (typically 1-247) identifies this device on the Modbus network. The baud rate must match the master device, and serial configuration must use 8 data bits. Call `begin()` after configuring data arrays but before calling `poll()`. ### Parameters - **id** (uint8_t) - Required - The unique Modbus slave ID (1-247). - **baudRate** (unsigned long) - Required - The communication baud rate (e.g., 9600, 38400). - **serialConfig** (SerialConfig) - Optional - The serial communication configuration (e.g., `SERIAL_8N1`, `SERIAL_8E1`, `SERIAL_8O1`). Defaults to `SERIAL_8N1`. ### Code Example ```cpp #include ModbusRTUSlave modbus(Serial1, 13); bool coils[4]; uint16_t holdingRegisters[4]; void setup() { // Configure data arrays first modbus.configureCoils(coils, 4); modbus.configureHoldingRegisters(holdingRegisters, 4); // Initialize serial port before Modbus Serial1.begin(38400, SERIAL_8N1); // Initialize Modbus with slave ID 1, baud rate 38400, default config (8N1) modbus.begin(1, 38400); // Or specify serial configuration explicitly // modbus.begin(1, 38400, SERIAL_8N1); // No parity (default) // modbus.begin(1, 9600, SERIAL_8E1); // Even parity // modbus.begin(1, 9600, SERIAL_8O1); // Odd parity } void loop() { modbus.poll(); } ``` ``` -------------------------------- ### Initialize Modbus Slave with begin() Source: https://context7.com/cmb27/modbusrtuslave/llms.txt Initialize the Modbus slave by calling `begin()` after configuring data arrays and the serial port. Specify the slave ID and baud rate. The serial configuration (8N1, 8E1, 8O1) can also be explicitly set. ```cpp #include ModbusRTUSlave modbus(Serial1, 13); bool coils[4]; uint16_t holdingRegisters[4]; void setup() { // Configure data arrays first modbus.configureCoils(coils, 4); modbus.configureHoldingRegisters(holdingRegisters, 4); // Initialize serial port before Modbus Serial1.begin(38400, SERIAL_8N1); // Initialize Modbus with slave ID 1, baud rate 38400, default config (8N1) modbus.begin(1, 38400); // Or specify serial configuration explicitly // modbus.begin(1, 38400, SERIAL_8N1); // No parity (default) // modbus.begin(1, 9600, SERIAL_8E1); // Even parity // modbus.begin(1, 9600, SERIAL_8O1); // Odd parity } void loop() { modbus.poll(); } ``` -------------------------------- ### ModbusRTUSlave Initialization Source: https://github.com/cmb27/modbusrtuslave/wiki/begin() Initializes the Modbus slave. The `begin()` method must be called before `poll()`. ```APIDOC ## ModbusRTUSlave Initialization ### Description Initializes the Modbus slave. `begin()` needs to be called before `poll()`. ### Syntax `modbus.begin(id, baud)` `modbus.begin(id, baud, config)` ### Parameters * `modbus`: a Modbus slave object. Allowed data types `ModbusRTUSlave`. * `id`: the Modbus slave id address. Allowed data types: `byte`. * `baud`: the baud rate of the port used. Allowed data types: `long`. * `config`: the config of the port used. Valid values are: `SERIAL_8N1` (the default) `SERIAL_8N2` `SERIAL_8E1`: even parity `SERIAL_8E2` `SERIAL_8O1`: odd parity `SERIAL_8O2` ### Returns Nothing ### Example ```cpp #include byte buf[256]; boolean coils[8]; ModbusRTUSlave modbus(Serial, buf, 256); char coilRead(word address) { return coils[address]; } boolean coilWrite(word address, boolean value) { coils[address] = value; return true; } void setup() { Serial.begin(38400, SERIAL_8E1); modbus.begin(1, 38400, SERIAL_8E1); modbus.configureCoils(8, coilRead, coilWrite); } void loop() { modbus.poll(); } ``` ``` -------------------------------- ### Initialize ModbusRTUSlave Source: https://github.com/cmb27/modbusrtuslave/wiki/begin() Initializes the Modbus slave object. `begin()` must be called before `poll()`. The baud rate and serial configuration are set here. ```cpp #include byte buf[256]; boolean coils[8]; ModbusRTUSlave modbus(Serial, buf, 256); char coilRead(word address) { return coils[address]; } boolean coilWrite(word address, boolean value) { coils[address] = value; return true; } void setup() { Serial.begin(38400, SERIAL_8E1); modbus.begin(1, 38400, SERIAL_8E1); modbus.configureCoils(8, coilRead, coilWrite); } void loop() { modbus.poll(); } ``` -------------------------------- ### ModbusRTUSlave Constructor Source: https://github.com/cmb27/modbusrtuslave/wiki/ModbusRTUSlave() This section describes the constructor for the ModbusRTUSlave class, detailing its parameters and return type. ```APIDOC ## ModbusRTUSlave Constructor ### Description Creates an object of type ModbusRTUSlave. ### Syntax `ModbusRTUSlave(serial, buf, bufSize)` `ModbusRTUSlave(serial, buf, bufSize, dePin)` `ModbusRTUSlave(serial, buf, bufSize, dePin, responseDelay)` ### Parameters #### Path Parameters - **serial** (Stream) - Required - A serial port object. - **buf** (array of byte) - Required - A byte array used to store Modbus messages; nominally 256 bytes long. - **bufSize** (word or unsigned int) - Required - The size of the byte array. - **dePin** (byte) - Optional - The pin connected to the DE and RE pins of an RS-485 transceiver. Can be set to `NO_DE_PIN` if a response delay is desired, without a DE pin. - **responseDelay** (unsigned long) - Optional - Parameter to delay the response to the master device. Units are in milliseconds. ### Returns An instance of this class. Data type `ModbusRTUSlave`. ### Example ```cpp #include #include byte buf[256]; boolean coils[8]; SoftwareSerial mySerial(10, 11); ModbusRTUSlave modbus(mySerial, buf, 256, 12, 10); char coilRead(word address) { return coils[address]; } boolean coilWrite(word address, boolean value) { coils[address] = value; return true; } void setup() { mySerial.begin(38400); modbus.begin(1, 38400); modbus.configureCoils(8, coilRead, coilWrite); } void loop() { modbus.poll(); } ``` ``` -------------------------------- ### Instantiate ModbusRTUSlave Source: https://github.com/cmb27/modbusrtuslave/wiki/ModbusRTUSlave() Initializes a ModbusRTUSlave object. Requires a serial port, a buffer for messages, the buffer size, and optionally a DE/RE pin and response delay. Ensure the serial port and Modbus baud rates match. ```cpp #include #include byte buf[256]; boolean coils[8]; SoftwareSerial mySerial(10, 11); ModbusRTUSlave modbus(mySerial, buf, 256, 12, 10); char coilRead(word address) { return coils[address]; } boolean coilWrite(word address, boolean value) { coils[address] = value; return true; } void setup() { mySerial.begin(38400); modbus.begin(1, 38400); modbus.configureCoils(8, coilRead, coilWrite); } void loop() { modbus.poll(); } ``` -------------------------------- ### ModbusRTUSlave Initialization Source: https://github.com/cmb27/modbusrtuslave/blob/main/README.md Initializes the Modbus RTU slave with a slave ID and baud rate. Optionally configures serial port settings. ```APIDOC ## ModbusRTUSlave Initialization ### Description Sets the slave/server id and the data rate in bits per second (baud) for serial transmission. Optionally it also sets the data configuration. Note, there must be 8 data bits for Modbus RTU communication. The default configuration is 8 data bits, no parity, and one stop bit. ### Syntax - `modbus.begin(slaveId, baud)` - `modbus.begin(slaveId, config)` ### Parameters #### Path Parameters - **modbus** (ModbusRTUSlave) - Required - A ModbusRTUSlave object. - **slaveId** (uint8_t or byte) - Required - The number used to identify this device on the Modbus network. - **baud** (unsigned long) - Required - The baud rate to use for Modbus communication. Common values are: `1200`, `2400`, `4800`, `9600`, `16200`, `38400`, `57600`, and `115200`. - **config** (serial port configuration) - Optional - The serial port configuration to use. Valid values are: `SERIAL_8N1` (no parity - default), `SERIAL_8N2`, `SERIAL_8E1` (even parity), `SERIAL_8E2`, `SERIAL_8O1` (odd parity), `SERIAL_8O2`. ``` -------------------------------- ### configureCoils() Source: https://github.com/cmb27/modbusrtuslave/blob/main/README.md Configures the storage location and number of coils for the Modbus slave. ```APIDOC ## configureCoils() ### Description Tells the library where coil data is stored and the number of coils. If this function is not run, the library will assume there are no coils. ### Syntax `modbus.configureCoils(coils, numCoils)` ### Parameters - `coils`: A pointer to the array where coil data is stored. - `numCoils`: The number of coils available. ### Request Body ```json { "coils": "pointer to coil data array", "numCoils": "integer" } ``` ### Response This method does not return a value. ``` -------------------------------- ### configureDiscreteInputs() Source: https://context7.com/cmb27/modbusrtuslave/llms.txt Configures the discrete inputs data array. Discrete inputs are read-only boolean values that the master can read using function code 2. These typically represent sensor states or button presses. Update the array values in your loop to reflect current input states. ```APIDOC ## configureDiscreteInputs() ### Description Configures the discrete inputs data array. Discrete inputs are read-only boolean values that the master can read using function code 2. These typically represent sensor states or button presses. Update the array values in your loop to reflect current input states. ### Method `configureDiscreteInputs(bool* array, uint16_t size)` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```cpp #include ModbusRTUSlave modbus(Serial1, 13); // Define discrete inputs array - read-only boolean values bool discreteInputs[4]; const int buttonPins[4] = {2, 3, 4, 5}; void setup() { // Configure button pins as inputs with pull-up resistors for (int i = 0; i < 4; i++) { pinMode(buttonPins[i], INPUT_PULLUP); } modbus.configureDiscreteInputs(discreteInputs, 4); Serial1.begin(38400); modbus.begin(1, 38400); } void loop() { // Update discrete inputs with current button states before polling // Buttons with pull-up: pressed = LOW, so invert for logical state discreteInputs[0] = !digitalRead(buttonPins[0]); discreteInputs[1] = !digitalRead(buttonPins[1]); discreteInputs[2] = !digitalRead(buttonPins[2]); discreteInputs[3] = !digitalRead(buttonPins[3]); modbus.poll(); // Master reads will return current button states } ``` ### Response #### Success Response (200) None #### Response Example None ``` -------------------------------- ### ModbusRTUSlave() Constructor Source: https://github.com/cmb27/modbusrtuslave/blob/main/README.md Creates a ModbusRTUSlave object and configures the serial port and optional driver enable/read enable pins for Modbus communication. ```APIDOC ## ModbusRTUSlave() Constructor ### Description Creates a ModbusRTUSlave object and sets the serial port to use for data transmission. Optionally sets a driver enable pin. This pin will go `HIGH` when the library is transmitting. This is primarily intended for use with an RS-485 transceiver, but it can also be a handy diagnostic when connected to an LED. ### Syntax - `ModbusRTUSlave(serial)` - `ModbusRTUSlave(serial, dePin)` - `ModbusRTUSlave(serial, dePin, rePin)` ### Parameters - `serial`: the `Stream` object to use for Modbus communication. Usually something like `Serial1`. - `dePin`: the driver enable pin. This pin is set HIGH when transmitting. If this parameter is set to `-1`, this feature will be disabled. The default value is `-1`. Allowed data types: `int`. - `rePin`: the read enable pin. This pin is always set `LOW`. If this parameter is set to `-1`, this feature will be disabled. The default value is `-1`. Allowed data types: `int`. ### Example ``` C++ # include const int dePin = A6; const int rePin = A5; ModbusRTUSlave modbus(Serial, dePin, rePin); ``` ``` -------------------------------- ### configureCoils() Method Source: https://context7.com/cmb27/modbusrtuslave/llms.txt Configures the array of boolean coils that the Modbus slave will manage. These coils can be read and written by the master device. ```APIDOC ## configureCoils() Configures the coils data array for the Modbus slave. Coils are boolean values that can be read and written by the master device using function codes 1, 5, and 15. Pass a boolean array and its size. If not configured, the library assumes no coils exist. ### Parameters - **coils** (bool*) - Required - A pointer to the boolean array representing the coils. - **size** (size_t) - Required - The number of coils in the array. ### Code Example ```cpp #include ModbusRTUSlave modbus(Serial1, 13); // Define coils array - each element is one coil (addresses 0, 1, 2, 3) bool coils[4] = {false, false, false, false}; void setup() { // Configure coils before begin() modbus.configureCoils(coils, 4); Serial1.begin(38400); modbus.begin(1, 38400); } void loop() { modbus.poll(); // Coils are automatically updated by master write requests // Use coil values to control outputs digitalWrite(LED_BUILTIN, coils[0]); // Coil 0 controls built-in LED digitalWrite(5, coils[1]); // Coil 1 controls pin 5 digitalWrite(6, coils[2]); // Coil 2 controls pin 6 digitalWrite(7, coils[3]); // Coil 3 controls pin 7 } ``` ``` -------------------------------- ### Modbus RTU Slave Arduino Sketch Source: https://github.com/cmb27/modbusrtuslave/blob/main/README.md This sketch sets up a Modbus RTU slave device using the ModbusRTUSlave library. It configures digital pins for coils and discrete inputs, initializes the Modbus communication, and continuously polls for incoming Modbus requests while updating the state of coils based on received data. ```C++ # include const uint8_t coilPins[2] = {4, 5}; const uint8_t discreteInputPins[2] = {2, 3}; ModbusRTUSlave modbus(Serial); bool coils[2]; bool discreteInputs[2]; void setup() { pinMode(coilPins[0], OUTPUT); pinMode(coilPins[1], OUTPUT); pinMode(discreteInputPins[0], INPUT); pinMode(discreteInputPins[1], INPUT); modbus.configureCoils(coils, 2); modbus.configureDiscreteInputs(discreteInputs, 2); Serial.begin(38400); modbus.begin(1, 38400); } void loop() { discreteInputs[0] = digitalRead(discreteInputPins[0]); discreteInputs[1] = digitalRead(discreteInputPins[1]); modbus.poll(); digitalWrite(coilPins[0], coils[0]); digitalWrite(coilPins[1], coils[1]); } ``` -------------------------------- ### Instantiate ModbusRTUSlave with Pins Source: https://github.com/cmb27/modbusrtuslave/blob/main/README.md Creates a ModbusRTUSlave object using a specified serial port and driver enable/read enable pins. The driver enable pin is set HIGH during transmission, useful for RS-485 transceivers or diagnostics. If pins are set to -1, the feature is disabled. ```C++ # include const int dePin = A6; const int rePin = A5; ModbusRTUSlave modbus(Serial, dePin, rePin); ``` -------------------------------- ### Configure Discrete Inputs Source: https://github.com/cmb27/modbusrtuslave/blob/main/README.md Configures the discrete inputs for the Modbus RTU slave, specifying the array of discrete input values and the number of discrete inputs. ```APIDOC ## Configure Discrete Inputs ### Description Tells the library where to read discrete input data and the number of discrete inputs. If this function is not run, the library will assume there are no discrete inputs. ### Syntax `modbus.configureDiscreteInputs(discreteInputs, numDiscreteInputs)` ### Parameters #### Path Parameters - **modbus** (ModbusRTUSlave) - Required - A ModbusRTUSlave object. - **discreteInputs** (array of bool) - Required - An array of discrete input values. - **numDiscreteInputs** (uint16_t) - Required - The number of discrete inputs. This value must not be larger than the size of the array. ``` -------------------------------- ### configureHoldingRegisters() Source: https://context7.com/cmb27/modbusrtuslave/llms.txt Configures the holding registers data array. Holding registers are 16-bit values that can be read and written by the master using function codes 3, 6, and 16. Commonly used for setpoints, configuration values, and bidirectional data exchange. ```APIDOC ## configureHoldingRegisters() ### Description Configures the holding registers data array. Holding registers are 16-bit values that can be read and written by the master using function codes 3, 6, and 16. Commonly used for setpoints, configuration values, and bidirectional data exchange. ### Method `configureHoldingRegisters(uint16_t* array, uint16_t size)` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```cpp #include ModbusRTUSlave modbus(Serial1, 13); // Define holding registers - 16-bit read/write values uint16_t holdingRegisters[4] = {0, 0, 0, 0}; const int pwmPins[2] = {9, 10}; void setup() { pinMode(pwmPins[0], OUTPUT); pinMode(pwmPins[1], OUTPUT); modbus.configureHoldingRegisters(holdingRegisters, 4); Serial1.begin(38400); modbus.begin(1, 38400); } void loop() { modbus.poll(); // Holding registers are updated by master write requests // Use values to control PWM outputs (constrain to 0-255 for analogWrite) analogWrite(pwmPins[0], constrain(holdingRegisters[0], 0, 255)); analogWrite(pwmPins[1], constrain(holdingRegisters[1], 0, 255)); // Registers 2 and 3 could store configuration or other data // holdingRegisters[2] - e.g., operating mode // holdingRegisters[3] - e.g., threshold value } ``` ### Response #### Success Response (200) None #### Response Example None ``` -------------------------------- ### Configure Holding Registers Source: https://github.com/cmb27/modbusrtuslave/wiki/configureHoldingRegisters() Configures the Modbus slave's holding registers. Requires user-defined functions for reading and writing. ```APIDOC ## POST /configureHoldingRegisters ### Description Configures the Modbus slave's holding registers. Two user-defined functions must be provided for accessing holding registers. If holding registers are used, `configureHoldingRegisters()` must be called before `poll()`. ### Method POST ### Endpoint /configureHoldingRegisters ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **modbus** (ModbusRTUSlave) - Required - A Modbus slave object. - **numHoldingRegisters** (word or unsigned int) - Required - The number of holding registers to configure. - **holdingRegisterRead** (function) - Required - The function to call for reading holding registers. This function must take a `word` or `unsigned int` (address) as a parameter and return a `long` (value). If the register cannot be accessed, it should return -1. - **holdingRegisterWrite** (function) - Required - The function to call for writing to holding registers. This function must take a `word` or `unsigned int` (address) and a `word` or `unsigned int` (value) as parameters and return a boolean. It should return `true` if the write was successful, and `false` otherwise. ### Request Example ```cpp // Example user-defined functions long holdingRegisterRead(word address) { // ... implementation ... return value; } boolean holdingRegisterWrite(word address, word value) { // ... implementation ... return true/false; } // Calling the configuration function modbus.configureHoldingRegisters(8, holdingRegisterRead, holdingRegisterWrite); ``` ### Response #### Success Response (200) - **None** - This function does not return any value. #### Response Example None ``` -------------------------------- ### Configure Modbus Slave Discrete Inputs Source: https://github.com/cmb27/modbusrtuslave/wiki/configureDiscreteInputs() Call `configureDiscreteInputs()` before `poll()` if discrete inputs are used. A custom function is required for accessing discrete inputs. ```cpp #include #include byte buf[256]; SoftwareSerial mySerial(10, 11); ModbusRTUSlave modbus(mySerial, buf, 256); char discreteInputRead(word address) { if (address < 8) return digitalRead(2 + address); else return -1; } void setup() { for (byte i = 2; i <= 9; i++) { pinMode(i, INPUT); } mySerial.begin(38400); modbus.begin(1, 38400); modbus.configureDiscreteInputs(8, discreteInputRead); } void loop() { modbus.poll(); } ``` -------------------------------- ### Configure Coils Data Array Source: https://context7.com/cmb27/modbusrtuslave/llms.txt Configure the boolean coils data array using `configureCoils()`. This array is used for Modbus function codes 1, 5, and 15. Call this before `begin()`. The coils are automatically updated by master write requests. ```cpp #include ModbusRTUSlave modbus(Serial1, 13); // Define coils array - each element is one coil (addresses 0, 1, 2, 3) bool coils[4] = {false, false, false, false}; void setup() { // Configure coils before begin() modbus.configureCoils(coils, 4); Serial1.begin(38400); modbus.begin(1, 38400); } void loop() { modbus.poll(); // Coils are automatically updated by master write requests // Use coil values to control outputs digitalWrite(LED_BUILTIN, coils[0]); // Coil 0 controls built-in LED digitalWrite(5, coils[1]); // Coil 1 controls pin 5 digitalWrite(6, coils[2]); // Coil 2 controls pin 6 digitalWrite(7, coils[3]); // Coil 3 controls pin 7 } ``` -------------------------------- ### Configure Input Registers Source: https://github.com/cmb27/modbusrtuslave/blob/main/README.md Configures the input registers for the Modbus RTU slave, specifying the array of input register values and the number of input registers. ```APIDOC ## Configure Input Registers ### Description Tells the library where to read input register data and the number of input registers. If this function is not run, the library will assume there are no input registers. ### Syntax `modbus.configureInputRegisters(inputRegisters, numInputRegisters)` ### Parameters #### Path Parameters - **modbus** (ModbusRTUSlave) - Required - A ModbusRTUSlave object. - **inputRegisters** (array of uint16_t) - Required - An array of input register values. - **numInputRegisters** (uint16_t) - Required - The number of input registers. This value must not be larger than the size of the array. ``` -------------------------------- ### Configure Discrete Inputs for Modbus RTU Slave Source: https://context7.com/cmb27/modbusrtuslave/llms.txt Configures an array of boolean discrete inputs. These are read-only and typically represent sensor states or button presses. Update the array in the loop to reflect current states. ```cpp #include ModbusRTUSlave modbus(Serial1, 13); // Define discrete inputs array - read-only boolean values bool discreteInputs[4]; const int buttonPins[4] = {2, 3, 4, 5}; void setup() { // Configure button pins as inputs with pull-up resistors for (int i = 0; i < 4; i++) { pinMode(buttonPins[i], INPUT_PULLUP); } modbus.configureDiscreteInputs(discreteInputs, 4); Serial1.begin(38400); modbus.begin(1, 38400); } void loop() { // Update discrete inputs with current button states before polling // Buttons with pull-up: pressed = LOW, so invert for logical state discreteInputs[0] = !digitalRead(buttonPins[0]); discreteInputs[1] = !digitalRead(buttonPins[1]); discreteInputs[2] = !digitalRead(buttonPins[2]); discreteInputs[3] = !digitalRead(buttonPins[3]); modbus.poll(); // Master reads will return current button states } ``` -------------------------------- ### Configure Discrete Inputs Source: https://github.com/cmb27/modbusrtuslave/wiki/configureDiscreteInputs() Configures the Modbus slave's discrete inputs. A user-defined function is required for accessing these inputs. This function must be called before `poll()` if discrete inputs are utilized. ```APIDOC ## POST /configureDiscreteInputs ### Description Configures the Modbus slave's discrete inputs. A user defined function will need to be written for accessing discrete inputs. If discrete inputs are used, `configureDiscreteInputs()` needs to be called before `poll()`. ### Method POST ### Endpoint /configureDiscreteInputs ### Parameters #### Request Body - **modbus** (ModbusRTUSlave) - Required - A Modbus slave object. - **numDiscreteInputs** (word | unsigned int) - Required - The number of discrete inputs to configure. - **discreteInputRead** (function) - Required - The function to call for reading discrete inputs. This function must take a `word` or `unsigned int` as a parameter (the address of the discrete input) and return a `char` representing the value of the discrete input. Return -1 if the discrete input cannot be accessed. ### Request Example ```json { "modbus": "", "numDiscreteInputs": 8, "discreteInputRead": "char discreteInputRead(word address)" } ``` ### Response #### Success Response (200) - **None** - This function does not return any value. #### Response Example ```json { "message": "Discrete inputs configured successfully." } ``` ``` -------------------------------- ### configureInputRegisters() Source: https://context7.com/cmb27/modbusrtuslave/llms.txt Configures the input registers data array. Input registers are read-only 16-bit values that the master can read using function code 4. Typically used for sensor readings, measurements, and status values. Update array values before polling. ```APIDOC ## configureInputRegisters() ### Description Configures the input registers data array. Input registers are read-only 16-bit values that the master can read using function code 4. Typically used for sensor readings, measurements, and status values. Update array values before polling. ### Method `configureInputRegisters(uint16_t* array, uint16_t size)` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```cpp #include ModbusRTUSlave modbus(Serial1, 13); // Define input registers - read-only 16-bit values uint16_t inputRegisters[4]; const int analogPins[2] = {A0, A1}; void setup() { pinMode(analogPins[0], INPUT); pinMode(analogPins[1], INPUT); modbus.configureInputRegisters(inputRegisters, 4); Serial1.begin(38400); modbus.begin(1, 38400); } void loop() { // Update input registers with current sensor values before polling inputRegisters[0] = analogRead(analogPins[0]); // Raw ADC value 0-1023 inputRegisters[1] = analogRead(analogPins[1]); // Raw ADC value 0-1023 inputRegisters[2] = map(inputRegisters[0], 0, 1023, 0, 500); // Scaled value inputRegisters[3] = millis() / 1000; // Uptime in seconds modbus.poll(); // Master reads will return current values } ``` ### Response #### Success Response (200) None #### Response Example None ``` -------------------------------- ### Configure Coils Source: https://github.com/cmb27/modbusrtuslave/blob/main/README.md Configures the coils for the Modbus RTU slave, specifying the array of coil values and the number of coils. ```APIDOC ## Configure Coils ### Description Tells the library where to read coil data and the number of coils. If this function is not run, the library will assume there are no coils. ### Syntax `modbus.configureCoils(coils, numCoils)` ### Parameters #### Path Parameters - **modbus** (ModbusRTUSlave) - Required - A ModbusRTUSlave object. - **coils** (array of bool) - Required - An array of coil values. - **numCoils** (uint16_t) - Required - The number of coils. This value must not be larger than the size of the array. ``` -------------------------------- ### Configure Modbus Slave Input Registers Source: https://github.com/cmb27/modbusrtuslave/wiki/configureInputRegisters() Call `configureInputRegisters()` before `poll()` if input registers are used. A custom function is required for reading these registers. ```cpp #include #include byte buf[256]; SoftwareSerial mySerial(10, 11); ModbusRTUSlave modbus(mySerial, buf, 256); long inputRegisterRead(word address) { if (address < 6) return analogRead(A0 + address); else return -1; } void setup() { for (byte i = A0; i <= A5; i++) { pinMode(i, INPUT); } mySerial.begin(38400); modbus.begin(1, 38400); modbus.configureInputRegisters(6, inputRegisterRead); } void loop() { modbus.poll(); } ``` -------------------------------- ### Set Response Delay Source: https://github.com/cmb27/modbusrtuslave/blob/main/README.md Sets an optional delay in milliseconds before the slave device sends its response to a request. ```APIDOC ## Set Response Delay ### Description Sets an optional delay in milliseconds between when a request from a master device has been processed and when the slave device sends its response. By default this value is `0`. This may be useful when tight control over the DE pin of an RS-485 transceiver on a master device is not possible. Adding a delay will give the master more time to set the DE pin `LOW` and avoid issues with multiple active drivers on the RS-485 bus. This function should only be used as a last resort. ### Syntax `modbus.setResponseDelay(responseDelay)` ### Parameters #### Path Parameters - **modbus** (ModbusRTUSlave) - Required - A ModbusRTUSlave object. - **responseDelay** (unsigned long) - Required - Number of milliseconds to wait before responding to requests. ``` -------------------------------- ### Configure Modbus RTU Slave Coils Source: https://github.com/cmb27/modbusrtuslave/wiki/configureCoils() Configures the Modbus slave's coils. Requires user-defined functions for reading and writing coil values. `configureCoils()` must be called before `poll()` if coils are used. ```APIDOC ## POST /api/modbus/configureCoils ### Description Configures the Modbus slave's coils. Two user-defined functions will need to be written for accessing coils. If coils are used, `configureCoils()` needs to be called before `poll()`. ### Method POST ### Endpoint /api/modbus/configureCoils ### Parameters #### Request Body - **numCoils** (word or unsigned int) - Required - The number of coils to configure. - **coilRead** (function) - Required - The function to call for reading coils. This function must take a `word` or `unsigned int` as a parameter (the address of the coil to be read) and return a `char`. If the coil cannot be accessed, it should return -1. - **coilWrite** (function) - Required - The function to call for writing to coils. This function must take a `word` or `unsigned int` (the address of the coil to be written to) followed by a `boolean` (the value to be written) as parameters and return a boolean. It should return `true` if the coil was successfully written to and `false` if it was not. ### Request Example ```json { "numCoils": 8, "coilRead": "char coilRead(word address)", "coilWrite": "boolean coilWrite(word address, boolean value)" } ``` ### Response #### Success Response (200) - **message** (string) - Indicates successful configuration. #### Response Example ```json { "message": "Coils configured successfully." } ``` ``` -------------------------------- ### Configure Holding Registers Source: https://github.com/cmb27/modbusrtuslave/blob/main/README.md Configures the holding registers for the Modbus RTU slave, specifying the array of holding register values and the number of holding registers. ```APIDOC ## Configure Holding Registers ### Description Tells the library where holding register data is stored and the number of holding registers. If this function is not run, the library will assume there are no holding registers. ### Syntax `modbus.configureHoldingRegisters(holdingRegisters, numHoldingRegisters)` ### Parameters #### Path Parameters - **modbus** (ModbusRTUSlave) - Required - A ModbusRTUSlave object. - **holdingRegisters** (array of uint16_t) - Required - An array of holding register values. - **numHoldingRegisters** (uint16_t) - Required - The number of holding registers. This value must not be larger than the size of the array. ``` -------------------------------- ### Configure Input Registers Source: https://github.com/cmb27/modbusrtuslave/wiki/configureInputRegisters() Configures the Modbus slave's input registers. A user-defined function is required for accessing these registers. Call this function before `poll()` if input registers are used. ```APIDOC ## POST /configureInputRegisters ### Description Configures the Modbus slave's input registers. A user defined function will need to be written for accessing input registers. If input registers are used, `configureInputRegisters()` needs to be called before `poll()`. ### Method POST ### Endpoint /configureInputRegisters ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **modbus** (ModbusRTUSlave) - Required - A Modbus slave object. - **numInputRegisters** (word or unsigned int) - Required - The number of input registers to configure. - **inputRegisterRead** (function) - Required - The function to call for reading input registers. This function must take a `word` or `unsigned int` as a parameter and return a `long`. The parameter is the address of the input register to be read. The return value is the value of the input register; if the input register cannot be accessed a `-1` should be returned. e.g. `long inputRegisterRead(word address)` ### Request Example ```json { "modbus": "", "numInputRegisters": 6, "inputRegisterRead": "long inputRegisterRead(word address)" } ``` ### Response #### Success Response (200) - **None** - This function does not return any value. #### Response Example None ```