Tutorial 11 — linking two central units over Modbus IP
Part 2 — Tutorials. Assumes Chapter 32.
What you will build
Two separate iNELS installations, each with its own central unit, talking to each other over the network. A button on CU-A switches a light wired to CU-B.
By the end you will be able to share any value — a switch state, a temperature, a mode — in either direction between central units.
This tutorial assumes you have never configured Modbus before. Every step says what to type and why it matters.
33.1 Why you would do this
A single central unit has limits — how many units on the bus, how much current, how many wires. Large sites therefore end up with more than one CU: one per floor, one per building, one for the plant room.
Left alone, those are separate installations that know nothing about each other. Modbus IP is what joins them, over the network cable that is already there.
Typical reasons:
One button controls something on another CU
Reception switches the car-park lights
Share a measured value
One outdoor sensor feeds every building
A global mode
"Holiday" set once, obeyed everywhere
Central override
A master "all off" across the whole site
Report a state upward
Plant-room alarm shown on the main CU
This is the same mechanism as talking to third-party equipment. The other CU is simply another Modbus device. Nothing new to learn beyond Chapter 32 — the only twist is that you configure both ends yourself.
33.2 The idea in one picture
One CU offers values. The other fetches them. The link is a numbered pigeonhole — a register — that both sides agree on.
Register 0 is the pigeonhole. CU-A writes into it; CU-B reads out of it. They must both use the same register number, or nothing happens.
The three rules
Everything that goes wrong with CU-to-CU Modbus comes from breaking one of these:
1. Same register number on both sides
Different numbers = different pigeonholes. No error is shown.
2. Same data type on both sides
One side reading 16-bit while the other writes 32-bit gives nonsense
3. Same Value specification on both sides
Scale on one side only and the value is out by 10 or 100
Write these three down for every value you link. That table is your register map.
Use
Read-Write-Holding-Register-UInt16for everything. It is the iDM3 default, it carries both on/off (as0and1) and numbers (0–65535), and it is readable and writable. Mixing coils and registers works, but doubles the ways you can mismatch the two ends. One type everywhere is the easier system to hand over.
33.3 Before you start
Two central units
Any models — Modbus IP works on all of them (§32.3)
Both on the same network
Each must be able to reach the other's IP
Static IP addresses
See the warning below
A project for each
They are separate .elp files, edited separately
Firmware supporting Modbus IP
Give both central units static IP addresses before you start. If CU-B gets its address from DHCP, that address can change — and the moment it does, CU-A is pointing at nothing. The link dies silently, with no error anywhere. Set a static address in CU configuration (Chapter 22), or a permanent DHCP reservation on the router. This is the single most common cause of a CU-to-CU link that "worked last month".
Our example:
CU-A
Master — has the button
192.168.1.10
CU-B
Slave — has the light
192.168.1.11
33.4 Plan the register map first
Do this on paper before touching iDM3. Two minutes here saves an afternoon later.
0
A → B
Hall light command (0 = off, 1 = on)
Holding Register UInt16
Not-Used
That is the whole map for this tutorial. On a real site it grows:
0–9
A → B
commands from A to B
Holding Register UInt16
Not-Used
10–19
B → A
status back from B
Holding Register UInt16
Not-Used
100–109
B → A
temperatures ×10
Holding Register UInt16
Multiplication 10x
Leave gaps and group by direction. Reserving
0–9for one direction and10–19for the other means adding a value later never renumbers anything. Renumbering means editing both projects and re-uploading both CUs.
One register carries one direction. If you want A to control B and B to report back, use two registers — one for each way. Pointing both CUs at the same register to write is how you get two systems fighting over one value.
33.5 Part 1 — Configure CU-B, the slave
The slave is the CU that owns the light and waits to be told what to do.
Open CU-B's project.
Step 1 — Add the Modbus IP slave module
Project ribbon tab → Device manager.
Select the central unit at the top of the tree.
Click New slave.
Choose
Modbus-IP-Slave→ OK.
"New slave" here means "add a module under the CU" — it is the ordinary Device manager button from Chapter 5, nothing to do with Modbus slave role. The coincidence of wording is unfortunate. You use New slave to add Modbus master modules too.
Step 2 — Set the port
Select the Modbus-IP-Slave module. In Parameters there is one setting:
Port:
502
502 is the standard Modbus TCP port. Use it unless something else on the CU already occupies it. Whatever you choose here must be typed identically on CU-A later.
Give it a Description — Modbus link to CU-A.
Step 3 — Add the slave unit
Select the
Modbus-IP-Slavemodule.Click New unit.
Choose
Modbus-IP-Slave-Unit→ OK.Describe it —
Link registers.
This unit has no parameters of its own. It is a container for the registers. An empty Parameters panel here is correct, not a fault.
Step 4 — Create the register
The unit arrives holding a single Modbus-Device1. One Modbus-Device is one register — not one device. That naming trips up everyone; see §32.5.
Select Modbus-Device1 and set its three parameters:
Register address:
0
The pigeonhole number, from your map
Data type:
Read-Write-Holding-Register-UInt16
16-bit, readable and writable
Value specification:
Not-Used
An on/off command needs no scaling
Describe it — Hall light command.
Need more values? Add another Modbus-Device for each, with the next register number.
Step 5 — Wire the register to the light
This is the step that makes it real, and the one people miss. So far you have a register sitting in memory connected to nothing.
The Modbus register is an ordinary object in your project. Wire it exactly as you would a button (Chapter 2).
Design workspace tab → Controls ribbon tab.
Drag an object onto the floor plan and Connect it to
Modbus-Device1. Name itCmd from CU-A.Confirm the yellow dot has gone.
Function workspace tab → Functions ribbon tab → Add connection.
Drag from
Cmd from CU-A→ the hall light output. Switch Add connection off.Functions ribbon tab → Wire manager → select the new wire → name it
Hall light from CU-A→ click + twice:
Analog in value change
DIGITAL_COPY
The light follows the register value
Or, if you prefer explicit control over the two states, use two functions with conditions:
Analog in value change
Restriction value — the register = 1
DIGITAL_ON
Analog in value change
Restriction value — the register = 0
DIGITAL_OFF
The copy approach is shorter; the conditional approach is clearer to read six months later and extends naturally when you add more values. Either is correct.
Save, then Save to central unit.
Why an analog action for an on/off command? A 16-bit holding register is an analog object in iDM3, whatever you use it to carry. So it raises
Analog in value changeand is written with analog functions — even when the only values you ever put in it are0and1. That surprises people; it is correct.
CU-B is done. It is now listening on port 502 and will act on whatever arrives in register 0.
33.6 Part 2 — Configure CU-A, the master
The master is the CU with the button, and the one that does the asking.
Open CU-A's project — a different .elp file.
Step 1 — Add the Modbus IP master module
Device manager → select the central unit.
New slave →
Modbus-IP-Master→ OK.Describe it —
Modbus link to CU-B.
This module has no parameters at all. Nothing to configure at this level — the connection details live on the unit beneath it. An empty Parameters panel is expected.
Step 2 — Add the unit and point it at CU-B
Select the
Modbus-IP-Mastermodule.New unit →
Modbus-IP-Master-Unit→ OK.Describe it —
CU-B.In Parameters, set the two connection settings:
IP Address:
192.168.1.11
CU-B's actual IP address
Port:
502
The Port: you set on CU-B's Modbus-IP-Slave module
One unit = one remote central unit. The IP and port are entered once, here — not on every register. If you later link to a third CU, that is a second
Modbus-IP-Master-Unitunder the same module, with its own IP.
Step 3 — Create the matching register
Select the unit's Modbus-Device1 and set the same three parameters as on CU-B:
Register address:
0
Yes — exactly
Data type:
Read-Write-Holding-Register-UInt16
Yes — exactly
Value specification:
Not-Used
Yes — exactly
Describe it — Hall light cmd to CU-B.
Check these three against CU-B now, character by character. A mismatch produces no error message on either central unit. The link simply does nothing, and you will spend an hour looking at wiring that is perfectly fine.
Step 4 — Wire the button to the register
Same idea as CU-B, in the opposite direction: the register is now a consumer.
Design tab → place an object, Connect it to
Modbus-Device1, name itCmd to CU-B.Function tab → Add connection → drag from your button →
Cmd to CU-B.Wire manager → name it
Hall light to CU-B→ +:
Short down
MODBUS_WRITE_1
Writes 1 → light on
Long down
MODBUS_WRITE_0
Writes 0 → light off
Define those two in Function manager (Tutorial 2 §3):
MODBUS_WRITE_1
MODBUS_WRITE_0
Function type:
Analog
Analog
Select function:
Analog set level
Analog set level
Analog level
1
0
Use
Analogfunctions, notSystemones. The register is an analog object, soAnalog set levelis what writes to it.Sys int setis for system integers — a different thing, despite both holding numbers.
Save, then Save to central unit.
Check what actually lands in the register. For
0and1this is straightforward. If you later write larger numbers — a setpoint, a mode — watch the value in Monitor on CU-B and confirm it matches what you set, rather than assuming. Analog levels are conventionally a percentage, and how that maps onto a 0–65535 register is worth seeing once with your own eyes before you rely on it.
33.7 Part 3 — Test it
Do this in order. Each step isolates a different failure.
1. Can they see each other?
From a PC on the same network, ping CU-B's address. If that fails, stop — it is a network problem, not an iNELS one. Check the IP, the subnet, VLANs and any firewall between them.
2. Watch the register on CU-A
Connect iDM3 to CU-A and open Managers → Monitor. Find your Modbus object.
Press the button. The value should change to 1.
It changes → CU-A is writing correctly. Move on.
It does not → the fault is on CU-A: the wire, the function, or a yellow dot on the object. Nothing to do with Modbus yet.
3. Watch the register on CU-B
Now connect iDM3 to CU-B and open Monitor. Press the button on CU-A again.
The value appears → the link works. Any remaining problem is CU-B's wire to the light.
Nothing arrives → the link itself is broken. Work through §33.8.
4. The light
Press the button. The light on CU-B switches.
Expect a short delay. The master polls; it does not receive instant notifications. A fraction of a second to a couple of seconds is normal and cannot be tuned away. See §33.9.
33.8 When it does not work
Almost every failure is one of six things.
Value moves on CU-A, never on CU-B
Register address differs
Compare both. They must be identical.
Value arrives but is wildly wrong
Data type differs
Both must be Read-Write-Holding-Register-UInt16
Value is out by 10 or 100
Value specification differs
Both Not-Used, or both the same multiplication
Nothing at all, ever
Wrong IP Address: or Port: on CU-A's unit
Compare with CU-B's slave module port
Worked, then stopped
CU-B's IP changed — DHCP
Set a static address, then correct CU-A
Value arrives, light does nothing
The wire on CU-B, or a yellow dot
Check in Wire manager and on the plan
Nothing on either side
One CU was never uploaded
Save to central unit on both
The commonest mistake of all: changing one project and not the other. Both central units hold their own copy. Editing CU-A's register number and re-uploading only CU-A breaks the link, and the only symptom is silence. Every change to a linked register means editing and uploading both projects.
Reading the fault from where the value stops
Never appears on CU-A's Monitor
CU-A's wire, function, or object assignment
Appears on CU-A, not on CU-B
The link — register, type, scaling, IP, port
Appears on CU-B, light does not move
CU-B's wire to the output
33.9 What to know before you rely on this
Honest limitations, worth understanding before you design around them.
It is polled, not instant. The master asks repeatedly. Expect a fraction of a second to a couple of seconds. Fine for lighting, scenes, modes and setpoints. Not suitable for safety interlocks or anything needing guaranteed timing.
A broken link is silent. Pull the network cable and the last value simply stays there — CU-B does not know it has gone stale. If that matters, build your own watchdog: have CU-A increment a counter into a spare register every minute, and have CU-B raise an alarm if it stops changing.
Each CU is still independent. They do not share projects, groups, programs or time. Each holds its own configuration and keeps running alone if the other fails — usually a strength.
Only what you map crosses. There is no automatic discovery. A device added on CU-B is invisible to CU-A until you add a register for it on both sides.
Both projects must stay in step. Treat the register map as a shared contract. Keep it with both projects, and update it whenever either side changes.
33.10 Growing it
More values — add another Modbus-Device under the same unit on each CU, with the next register number. The IP and port are already set; you never re-enter them.
Both directions — give each CU both a Modbus-IP-Slave module (so it can be asked) and a Modbus-IP-Master module (so it can ask). Use separate registers for each direction, exactly as in §33.4.
Three or more CUs — the usual pattern is a hub: one CU is master, every other is slave, each with its own Modbus-IP-Master-Unit on the hub carrying that CU's IP. Avoid every CU polling every other — the register map becomes unmanageable.
Sharing a temperature — the only differences are that the source is a sensor rather than a button, and you set Value specification to Multiplication 10x on both sides so 21.5 °C survives the trip as 215.
A site-wide mode — link a system bit (Tutorial 8) rather than a physical device. Set HOLIDAY_MODE on one CU, write it to a register, and have every other CU read it into its own system bit. Each CU then uses its local bit in conditions, so the logic stays readable and works even if the link drops.
What you learned
Two central units link over Modbus IP: one slave (offers values), one master (fetches them)
A register is a numbered pigeonhole both sides must agree on
Register address, Data type and Value specification must match exactly — mismatches fail silently
Read-Write-Holding-Register-UInt16handles both on/off and numbers; use it for everythingA register is an analog object:
Analog in value changereads it,Analog set levelwrites itIP and port are set once on the unit; each register is a
Modbus-Devicebeneath itThe register does nothing until you wire it on both central units
Static IPs are essential — DHCP will break the link eventually
One register carries one direction; use two registers for two-way
Every change to a linked register means editing and uploading both projects
Before handover
See also: Chapter 32 — Modbus RTU and IP · Chapter 22 — Central unit configuration · Chapter 26 — Monitor