RS485 / Modbus RTU

The Eziwan Gateway features a native RS485/RS232 port on the terminal block. This interface allows you to collect data from your sensors, PLCs, and meters using the Modbus RTU protocol—and publish it to the cloud without a separate gateway.


Physical Connection

RS485 Terminal Block Wiring

Terminal Block Pins

PinSignalDescription
ARS485+Positive differential line
BRS485−Negative differential line
GNDGroundCommon reference
Polarity Check (A/B)

Reversing A and B causes communication errors but does not damage the equipment. If no device responds, test by reversing A and B.

Termination Resistors

On an RS485 bus with multiple slaves:

  • 120Ω on the first and last devices on the bus
  • The Eziwan Gateway has an internal jumper to enable termination (hardware documentation)
  • On intermediate devices: termination disabled

Configuring Modbus Polling

Via the Eziwan dashboard

Device → Configuration → RS485 / Modbus

Graphical interface: Add each slave and each register, and set the polling interval and the target MQTT topic.

Via the API / YAML

# Configuration RS485 + Modbus RTU
rs485:
enabled: true
baud_rate: 9600 # 1200, 2400, 4800, 9600, 19200, 38400, 115200
parity: none # none, even, odd
data_bits: 8 # 7 ou 8
stop_bits: 1 # 1 ou 2
polling_interval_sec: 10 # Overall polling interval (seconds)

modbus:
slaves:
- slave_id: 1
name: "Compteur énergie Schneider PM2200"
timeout_ms: 1000
retries: 3
registers:
- address: "0x0048"
type: holding # holding, input, coil, discrete_input
format: float32_abcd
tag: active_power
unit: kW
scale: 1.0
mqtt_topic: "site/usine-01/energie/puissance_active"

- address: "0x004A"
type: holding
format: float32_abcd
tag: reactive_power
unit: kVAr
scale: 1.0
mqtt_topic: "site/usine-01/energie/puissance_reactive"

- address: "0x0156"
type: holding
format: float32_abcd
tag: energy_total_kwh
unit: kWh
scale: 1.0
mqtt_topic: "site/usine-01/energie/index_kwh"

- slave_id: 2
name: "Capteur température / humidité"
timeout_ms: 500
registers:
- address: "0x0001"
type: input
format: int16
tag: temperature
unit: "°C"
scale: 0.1 # Valeur brute 245 → 24,5°C
mqtt_topic: "site/usine-01/environnement/temperature"

- address: "0x0002"
type: input
format: uint16
tag: humidity
unit: "%RH"
scale: 0.1
mqtt_topic: "site/usine-01/environnement/humidite"

- slave_id: 3
name: "Automate Schneider TM3 — Station de pompage"
polling_interval_sec: 30 # Override the global interval
registers:
- address: "0x0000"
type: holding
format: uint16
tag: pump_status
unit: ""
# 0=off, 1=on, 2=fault
mqtt_topic: "site/pompe-01/etat/pompe"

- address: "0x0001"
type: holding
format: int16
tag: pressure_bar
unit: bar
scale: 0.01
mqtt_topic: "site/pompe-01/mesures/pression"

- address: "0x0002"
type: holding
format: uint16
tag: flow_m3h
unit: "m³/h"
scale: 0.1
mqtt_topic: "site/pompe-01/mesures/debit"

Supported Log Formats

FormatDescriptionRegisters
int1616-bit signed integer1
uint1616-bit unsigned integer1
int32_abcd32-bit signed integer, big-endian2
int32_cdab32-bit signed integer, little-endian2
uint32_abcd32-bit unsigned integer, big-endian2
float32_abcdIEEE 754 float, big-endian2
float32_cdabIEEE 754 float, little-endian (Schneider)2
float32_badcIEEE 754 float, mid-big-endian2
coilModbus coil (1 bit)1 coil
bitExtract a bit from a uint16 register1
Endianness

If the values read appear to be inconsistent (e.g., 1234 read as 12340000), try float32_cdab instead of float32_abcd. The convention varies by manufacturer.


MQTT Publication

Modbus data is automatically published to the Eziwan MQTT broker:

Topic Structure

eziwan/{device_id}/modbus/{slave_id}/{tag_name}

Example:

eziwan/d_a1b2c3d4/modbus/1/active_power

JSON Payload

{
"value": 42.7,
"unit": "kW",
"timestamp": "2025-06-15T14:23:45.123Z",
"slave_id": 1,
"register": "0x0048",
"quality": "good"
}

The "quality" field can take the following values:

  • "good" — read successful
  • "timeout" — slave did not respond
  • "error" — Modbus error (code included in "error_code")

Subscribe from your system

# Subscribe to all tags on a site
mosquitto_sub -h mqtt.eziwan.com -p 8883 \
--cert client.crt --key client.key --cafile ca.crt \
-t "eziwan/d_a1b2c3d4/modbus/#"

# Subscribe to a specific tag
mosquitto_sub -h mqtt.eziwan.com -p 8883 \
--cert client.crt --key client.key --cafile ca.crt \
-t "eziwan/d_a1b2c3d4/modbus/1/active_power"

Equipment Tested

ManufacturerModelProtocolNotes
Schneider ElectricPM2100, PM2200Modbus RTUEnergy meter — float32
Schneider ElectricTM3, TM2Modbus RTUPLC — coils + holding registers
SiemensSENTRON PAC 3200Modbus RTUEnergy meter
Carlo GavazziEM24, EM340Modbus RTUThree-phase/single-phase meter
ABBB23, B24Modbus RTUEnergy meter
Wago750-xxxModbus RTUI/O bus coupler
Phoenix ContactILB ETH 2TXModbus TCPVia TCP bridge
HagerECR380DModbus RTUEnergy meter
EastronSDM630Modbus RTUThree-phase meter
GenericAny Modbus RTUModbus RTUSlave ID 1–247

Troubleshooting

Communication Test from Eziwan

Dashboard → Device → Tools → Modbus Test

Enter the slave ID, type, and register address → Eziwan sends a read request and displays the raw response in real time. Ideal for diagnostics without physical access to the site.

Modbus Error Codes

CodeMeaningSolution
TIMEOUTSlave not respondingCheck wiring, baud rate, slave ID, termination
01Function not supportedUse holding instead of input (or vice versa)
02Invalid register addressCheck the register in the equipment documentation
03Invalid data valueValue outside the allowed range
04Internal slave faultCheck the equipment log

Wiring Checklist

If no slave responds:

  • Check the A/B polarity (try reversing it)
  • Check the baud rate (9600 is the most common)
  • Verify that the slave IDs are unique on the bus
  • Enable the 120Ω termination on the first and last devices
  • Test with a single slave (isolate the problem)
  • Measure the A−B differential voltage: must be > 200 mV in standby mode

Reference Differential Voltage

Bus in standby mode (no transmission):
V(A−B) > +200 mV → polarisation correcte

Pendant transmission :
V(A−B) > +1.5V → signal dominant (1 logique)
V(A−B) < −1.5V → signal récessif (0 logique)

Modbus TCP tip

Do you have Modbus TCP devices (on an Ethernet network)? Eziwan also supports the Modbus TCP → MQTT bridge. See the Modbus TCP documentation →

Support Info

Frequently Asked Questions

How many devices can be connected to a single RS-485 bus?

32 slaves per segment without a repeater, over a maximum length of approximately 1,200 m at 9,600 baud. Beyond that, divide the system into multiple buses or add repeaters.

Is a terminating resistor necessary?

On long or high-speed buses, yes: 120 Ω at each end prevents reflections that corrupt the frames. On a short bus (a few meters, 9,600 baud), its absence often goes unnoticed—until the day it stops working.

What polling rate should you choose?

Adjust the polling frequency to match the process dynamics: every 10 to 60 seconds for energy or level measurements, and every 1 to 5 seconds for machine monitoring. Polling too frequently on a slow bus causes a cascade of timeouts.

How do you mix equipment with different speeds?

Do not mix serial settings on the same bus: all slaves must share the same baud rate, parity, and stop bits. Otherwise, distribute them across the gateway's various RS-485 ports.