R421A Relay Boards


These are inexpensive and readily available MODBUS multi-channel relay boards. Both 8 and 4-channel versions have been tested.

Device properties include:


The address of a modbus slave. Modbus docs. call this the slave ID.


Represents something a slave device does. Modbus relay boards have one node for each output it controls.

Node ID

The channel a node lives on. For the R421Axx relay boards this is the address or channel number. In a modbus transaction this is the address field.

namespace IO::Modbus::R421A
class Device : public IO::Modbus::Device
#include <Device.h>

Public Functions

virtual IO::Request *createRequest() override

Create a request object for this device.


Request* – Caller must destroy or submit the request

inline virtual DevNode::ID nodeIdMin() const override

Get minimum valid Node ID for this device.

Typically devices have a contiguous valid range of node IDs

inline virtual DevNode::ID nodeIdMax() const override

Get maximum valid Node ID for this device.

inline virtual uint16_t maxNodes() const override

Determine maximum number of nodes supported by the devicce.


uint16_t – 0 if device doesn’t support nodes

virtual DevNode::States getNodeStates(DevNode node) const override

Return the current set of states for all nodes controlled by this device.

Used to determine if, say, all nodes are ON, OFF or a combination.

virtual void handleEvent(IO::Request *request, Event event) override

Implementations may override this method to customise event handling.

struct Config
#include <Device.h>

R421A device configuration.

Public Members

Modbus::Device::Config modbus

Basic modbus configuration.

uint8_t channels

Number of channels (typically 4 or 8)

class Factory : public IO::Device::Factory
#include <Device.h>

Public Functions

inline virtual IO::Device *createDevice(IO::Controller &controller, const char *id) const override

Create a new device instance.

Called by DeviceManager::createDevice()

  • controller – The owning controller

  • id – Unique identifier for the device


Device* – The constructed instance

inline virtual const FlashString &controllerClass() const override

Return the expected controller type for this device class, e.g. ‘rs485’.

The Device Manager uses this value to verify that devices are constructed using the correct controller.

inline virtual const FlashString &deviceClass() const override

Return the Device class name, e.g. ‘r421a’.

class Request : public IO::Modbus::Request
#include <Request.h>

Public Functions

virtual ErrorCode parseJson(JsonObjectConst json) override

Fill this request from a JSON description.

virtual void getJson(JsonObject json) const override

Get result of a completed request in JSON format.

virtual bool setNode(DevNode node) override

If nodes are supported, implemented this method.

virtual DevNode::States getNodeStates(DevNode node) override

Query node status from response.

virtual ErrorCode callback(PDU &pdu) override

Process a received PDU.




ErrorCode – If request is re-submitted, return Error::pending, otherwise request will be completed with given error.