For the complete documentation index, see llms.txt. This page is also available as Markdown.

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:

Need
Example

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:

Rule
Why

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-UInt16 for everything. It is the iDM3 default, it carries both on/off (as 0 and 1) 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:

Role
IP address

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.

Register
Direction
Carries
Data type
Scaling

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:

Register
Direction
Carries
Data type
Scaling

09

A → B

commands from A to B

Holding Register UInt16

Not-Used

1019

B → A

status back from B

Holding Register UInt16

Not-Used

100109

B → A

temperatures ×10

Holding Register UInt16

Multiplication 10x

Leave gaps and group by direction. Reserving 0–9 for one direction and 10–19 for 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

  1. Project ribbon tab → Device manager.

  2. Select the central unit at the top of the tree.

  3. Click New slave.

  4. Choose Modbus-IP-SlaveOK.

"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:

Parameter
Set it to

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 DescriptionModbus link to CU-A.

Step 3 — Add the slave unit

  1. Select the Modbus-IP-Slave module.

  2. Click New unit.

  3. Choose Modbus-IP-Slave-UnitOK.

  4. 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:

Parameter
Set it to
Why

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).

  1. Design workspace tab → Controls ribbon tab.

  2. Drag an object onto the floor plan and Connect it to Modbus-Device1. Name it Cmd from CU-A.

  3. Confirm the yellow dot has gone.

  4. Function workspace tab → Functions ribbon tab → Add connection.

  5. Drag from Cmd from CU-A → the hall light output. Switch Add connection off.

  6. Functions ribbon tab → Wire manager → select the new wire → name it Hall light from CU-A → click + twice:

Action
User function
Result

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:

Action
Condition
User function

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.

  1. 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 change and is written with analog functions — even when the only values you ever put in it are 0 and 1. 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

  1. Device manager → select the central unit.

  2. New slaveModbus-IP-MasterOK.

  3. 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

  1. Select the Modbus-IP-Master module.

  2. New unitModbus-IP-Master-UnitOK.

  3. Describe it — CU-B.

  4. In Parameters, set the two connection settings:

Parameter
Set it to
Must match

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-Unit under 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:

Parameter
Set it to
Must match 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.

  1. Design tab → place an object, Connect it to Modbus-Device1, name it Cmd to CU-B.

  2. Function tab → Add connection → drag from your buttonCmd to CU-B.

  3. Wire manager → name it Hall light to CU-B+:

Action
User function
Effect

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 Analog functions, not System ones. The register is an analog object, so Analog set level is what writes to it. Sys int set is for system integers — a different thing, despite both holding numbers.

  1. Save, then Save to central unit.

Check what actually lands in the register. For 0 and 1 this 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.

Symptom
Cause
Fix

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

Value stops at
Look at

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-UInt16 handles both on/off and numbers; use it for everything

  • A register is an analog object: Analog in value change reads it, Analog set level writes it

  • IP and port are set once on the unit; each register is a Modbus-Device beneath it

  • The 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