Skip to content

Modbus RTU Slave

Giampiero Baggiani edited this page Aug 8, 2021 · 50 revisions

This sketch implements a fully functional standard Modbus RTU slave, configurable via serial console, to monitor and control all I/O lines of the Iono Uno and Iono MKR modules.

You can find the source code here.

This app requires the IonoModbusRtu library. Make sure to have it installed together with its dependencies.

Console

The configuration console can be accessed through Iono's RS-485 port or Arduino's USB port using any serial communication application (e.g. the Serial Monitor of the Arduino IDE).

Set the communication speed to 9600, 8 bits, no parity, no flow-control and connect the cable.

When Iono is powered-up or reset, you can enter console mode by typing five or more consecutive space characters within 15 seconds from reset. If any other character is received, Iono will enter the normal Modbus RTU mode.

Enter 0 to show the current configuration, 1 to 3 to set the serial port speed, serial port parity, and the Modbus address

=== Sfera Labs - Modbus RTU Slave configuration menu - v3.1 ===
0. Print current configuration
1. Speed (baud)
2. Parity
3. Modbus device address
4. Input/Output rules
5. Save configuration and restart
Type a menu number (0, 1, 2, 3, 4, 5): 0

Current configuration:
Speed (baud): 115200
Parity: Even
Modbus device address: 2
Input/Output rules: - - - - - -

Enter 4 to define the Input/Output rules. With these rules you can configure each one of the digital inputs to control the corresponding output relay. The rules string consists of six characters, where the leftmost character represents the rule for DI1/DO1 and the rightmost character for DI6/DO6 (for Iono MKR only the the first four rules apply). The possible rules are:

F: follow - the relay is closed when input is high

I: invert - the relay is closed when input is low

H: flip on L>H transition - the relay is flipped at any input transition from low to high

L: flip on H>L transition - the relay is flipped at any input transition from high to low

T: flip on any transition - the relay is flipped at any input transition, both high to low and low to high

-: no rule - no control rule set for this relay.

Enter 5 to review the configuration and confirm to save it. When the new configuration is saved, Arduino will automatically reset and restart with the new configuration.

The configuration is permanently stored in the Arduino's EEPROM memory, and retained across restarts and power cycles.

Modbus address tables and functions

Device ID

Use Modbus function Read Input Registers on register address 99 to read the ID of the module:

  • Iono Uno: 0x10
  • Iono MKR: 0x20

Relays

Use Modbus function Read Coils, at coil address 1 to 6 (4 for MKR), to read the status of the output relays.

Use functions Write Single Coil or Write Multiple Coils to control the relays output.

Address (decimal) Size [bit] Description R/W Functions
1 1 relay 1 status r/w 1,5,15
2 1 relay 2 status r/w 1,5,15
3 1 relay 3 status r/w 1,5,15
4 1 relay 4 status r/w 1,5,15
5 1 relay 5 status r/w 1,5,15
6 1 relay 6 status r/w 1,5,15

Use function Write Single Register or Write Multiple Registers to temporarily close the relays.

Address (decimal) Size [word] Description R/W Functions Type Range Unit
11 1 relay 1 close time w 6,16 unsigned short 1 - 65535 s/10
12 1 relay 2 close time w 6,16 unsigned short 1 - 65535 s/10
13 1 relay 3 close time w 6,16 unsigned short 1 - 65535 s/10
14 1 relay 4 close time w 6,16 unsigned short 1 - 65535 s/10
15 1 relay 5 close time w 6,16 unsigned short 1 - 65535 s/10
16 1 relay 6 close time w 6,16 unsigned short 1 - 65535 s/10

Analog (PWM) output

Use Modbus function Read Holding Registers at address 601 to read the status of the analog output AO1. The returned value is in mV, so the value range is 0 to 10000.

Use function Write Single Register to control the voltage output of AO1.

Address (decimal) Size [word] Description R/W Functions Type Range Unit
601 1 write analog voltage output AO1 r/w 3,6 unsigned short 0 - 10000 mV

Digital inputs

Digital inputs DI1 to DI6 can be read at two different address ranges, using function Read Discrete Inputs. Reading addresses 101 to 106 returns the value of the input pins filtered with a de-bounce function. This filter has a 25 ms time constant, so that a value change is reported only after being stable for at least 25 milliseconds.

Reading addresses 111 to 116 returns the instantaneous value of the input pins, with no de-bounce filter applied.

Address (decimal) Size [bit] Description R/W Functions
101 1 read digital input DI1 (with de-bounce) r 2
102 1 read digital input DI2 (with de-bounce) r 2
103 1 read digital input DI3 (with de-bounce) r 2
104 1 read digital input DI4 (with de-bounce) r 2
105 1 read digital input DI5 (with de-bounce) r 2
106 1 read digital input DI6 (with de-bounce) r 2
111 1 read digital input DI1 (no de-bounce) r 2
112 1 read digital input DI2 (no de-bounce) r 2
113 1 read digital input DI3 (no de-bounce) r 2
114 1 read digital input DI4 (no de-bounce) r 2
115 1 read digital input DI5 (no de-bounce) r 2
116 1 read digital input DI6 (no de-bounce) r 2

Analog inputs and digital counters

Use Modbus function Read Input Registers to read the values of analog inputs. Reading addresses 201 to 204 returns the voltage on AV1 to AV4 in mV, from 0 to 10000 (30000 for MKR). Reading addresses 301 to 304 returns the current on AI1 to AI4 in mA/1000 (µA), from 0 to 20000 (25000 for MKR).

Registers 211 to 214 and 311 to 314 contain the above values averaged on 32 subsequent readings.

This sketch also implements counters on digital inputs. Reading input registers at address 1001 to 1006 returns unsigned short values from 0 to 65535. These counters are incremented by one (and rolled back to 0 after reaching 65535) on the positive rise of their respective inputs, after the de-bounce filter.

Address (decimal) Size [word] Description R/W Functions Type Range Unit
201 1 read analog voltage input AV1 r 4 unsigned short 0-30000 mV
202 1 read analog voltage input AV2 r 4 unsigned short 0-30000 mV
203 1 read analog voltage input AV3 r 4 unsigned short 0-30000 mV
204 1 read analog voltage input AV4 r 4 unsigned short 0-30000 mV
211 1 read analog voltage input AV1 (averaged) r 4 unsigned short 0-30000 mV
212 1 read analog voltage input AV2 (averaged) r 4 unsigned short 0-30000 mV
213 1 read analog voltage input AV3 (averaged) r 4 unsigned short 0-30000 mV
214 1 read analog voltage input AV4 (averaged) r 4 unsigned short 0-30000 mV
301 1 read analog current input AI1 r 4 unsigned short 0-25000 µA
302 1 read analog current input AI2 r 4 unsigned short 0-25000 µA
303 1 read analog current input AI3 r 4 unsigned short 0-25000 µA
304 1 read analog current input AI4 r 4 unsigned short 0-25000 µA
311 1 read analog current input AI1 (averaged) r 4 unsigned short 0-25000 µA
312 1 read analog current input AI2 (averaged) r 4 unsigned short 0-25000 µA
313 1 read analog current input AI3 (averaged) r 4 unsigned short 0-25000 µA
314 1 read analog current input AI4 (averaged) r 4 unsigned short 0-25000 µA
1001 1 read digital input DI1 counter r 4 unsigned short 0-65535 n/a
1002 1 read digital input DI2 counter r 4 unsigned short 0-65535 n/a
1003 1 read digital input DI3 counter r 4 unsigned short 0-65535 n/a
1004 1 read digital input DI4 counter r 4 unsigned short 0-65535 n/a
1005 1 read digital input DI5 counter r 4 unsigned short 0-65535 n/a
1006 1 read digital input DI6 counter r 4 unsigned short 0-65535 n/a

1-Wire Dallas temperature sensors

Inputs DI5 and DI6 (with internal jumpers set to BYP position) can alternatively be used as 1-Wire bus lines. This sketch supports up to 8 Dallas temperature sensors connected to each bus line.

Each bus is activated by performing a read of registers 5000 (DI5 bus) and 6000 (DI6 bus) which return the number of detected devices.

Once enabled, discovered devices' addresses are available at registers 5001-5064 for DI5 and 6001-6064 for DI6. Each address consists of 8 bytes split in 8 consecutive registers, i.e. the first device address of bus DI5 is contained in registers 5001-5008, the second in 5009-5016, and so on.

Temperature values are requested every 10 seconds and available at registers 5101-5108 for bus DI5 and 6101-6108 for bus DI6.

Address (decimal) Size [word] Description R/W Functions Type Range Unit
5000 1 enable bus DI5 and get number of discovered devices r 3 unsigned short 0-8 n/a
6000 1 enable bus DI6 and get number of discovered devices r 3 unsigned short 0-8 n/a
5001-5064 1 devices' addresses bytes (DI5 bus) r 3 unsigned short 0-255 n/a
6001-6064 1 devices' addresses bytes (DI6 bus) r 3 unsigned short 0-255 n/a
5101-5108 1 read temperature (DI5 bus) r 4 signed short device dependent. Error = -12700 °C/100
6101-6108 1 read temperature (DI6 bus) r 4 signed short device dependent. Error = -12700 °C/100
Clone this wiki locally