> For the complete documentation index, see [llms.txt](https://wiki.inels.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://wiki.inels.com/inels-bus/inels-design-manager-idm3/idm3-modbus-rtu-and-ip-integration.md).

# Modbus — RTU and IP

*Connecting iNELS to third-party equipment.*

***

## What you will learn

* The difference between **Modbus RTU** and **Modbus IP**, and when to use each
* iNELS as a Modbus **master** — reading meters, HVAC plant, inverters
* iNELS as a Modbus **slave** — letting a BMS or SCADA read and control the installation
* Wiring an RS-485 bus properly
* Mapping registers to iNELS objects and using them in wires
* A complete worked example: a Carrier air-conditioning system

Read [Chapter 24](/inels-bus/inels-design-manager-idm3/idm3-external-systems-mqtt-modbus-cloud.md) first if you have not — it covers how devices are exposed to external systems generally.

***

## 32.1 Two transports, one protocol

Modbus is one protocol with two ways of carrying it. iNELS supports both, and the choice is usually made for you by the equipment you are connecting.

|                   | **Modbus RTU**                      | **Modbus IP**                          |
| ----------------- | ----------------------------------- | -------------------------------------- |
| Runs over         | RS-485 serial, twisted pair         | Ethernet, TCP                          |
| Speed             | 2400–115200 bps (**Boudrate:**)     | network speed                          |
| Distance          | up to \~1000 m                      | anywhere on the network                |
| Devices per bus   | \~32 without a repeater             | limited by the network                 |
| Addressing        | **Modbus Address:** `0–254`         | **IP Address:** + **Port:** per device |
| Cabling           | dedicated bus, daisy-chained        | existing network                       |
| Typical use       | HVAC plant, meters, older equipment | modern gear, BMS, PLCs                 |
| **Central units** | **CU3-10M only**                    | all central units                      |

**RTU is the more common on real sites**, because most HVAC translators, energy meters and heat pumps only speak it. **IP is easier** when the equipment supports it — no new cable.

> **They are not alternatives you get to pick between.** Look at what the third-party device offers. If it has an RS-485 terminal, that is RTU. If it has an Ethernet port and documents a Modbus TCP port (usually 502), that is IP. Some devices do both.

***

## 32.2 Master or slave — decide this first

The single most important decision, and people get it backwards.

| Role       | Meaning                                                                     | Use when                                                                         |
| ---------- | --------------------------------------------------------------------------- | -------------------------------------------------------------------------------- |
| **Master** | The CU asks. It polls other devices for values and writes commands to them. | You want iNELS to **read** an energy meter, or **control** a heat pump           |
| **Slave**  | The CU answers. Another system polls it.                                    | You want a **BMS or SCADA to read** the installation, or control it from outside |

```
   MASTER — iNELS is in charge
   ┌──────────┐  polls / writes   ┌─────────────────┐
   │  CU3     │ ────────────────▶ │ meter, HVAC,    │
   │ (master) │ ◀──────────────── │ inverter…       │
   └──────────┘     values        └─────────────────┘

   SLAVE — something else is in charge
   ┌──────────┐   polls / writes  ┌──────────┐
   │ BMS,     │ ────────────────▶ │  CU3     │
   │ SCADA    │ ◀──────────────── │ (slave)  │
   └──────────┘     values        └──────────┘
```

**You can be both at once** — master on one bus reading meters, slave on another so the building management system can see the whole installation.

> **Decide the transport before the role.** Serial Modbus in either role needs a **CU3-10M**; Modbus IP works on every central unit. See [§32.3](#which-central-unit--this-decides-everything).

***

## 32.3 The modules

Modbus is added in the **Device manager** as a module under the central unit (**New slave**), then the individual Modbus devices go under it (**New unit**).

| Module                   | Transport             | Role                                        |
| ------------------------ | --------------------- | ------------------------------------------- |
| `Internal-Modbus-Master` | serial — RTU or ASCII | The CU polls other devices                  |
| `Internal-Modbus-Slave`  | serial — RTU or ASCII | Other devices poll the CU                   |
| `Modbus-IP-Master`       | TCP                   | The CU polls other devices over the network |
| `Modbus-IP-Slave`        | TCP                   | Other systems poll the CU over the network  |

And the devices that go under them:

| Unit                    | Goes under             | Carries            |
| ----------------------- | ---------------------- | ------------------ |
| `Modbus-Unit`           | a serial Modbus module | `Modbus-Device1…n` |
| `Modbus-IP-Master-Unit` | `Modbus-IP-Master`     | `Modbus-Device1…n` |
| `Modbus-IP-Slave-Unit`  | `Modbus-IP-Slave`      | `Modbus-Device1…n` |

Each unit starts with a single `Modbus-Device1` and you add more as needed — one **device per register you want to read or write**. That is the key structural idea, and §32.5 returns to it.

> **A GRT3-100 can be a Modbus master too.** The `GRT3-100-MODBUS-MASTER` firmware turns that thermostat into a master with **24 device slots**, polling Modbus equipment itself rather than going through the CU. It adds two parameters the CU modules do not have: **Modbus Address:** (0–254) and **Modbus response timeout:** (0–254).

### Which central unit — this decides everything

**Serial Modbus needs an RS-485 port, and only one central unit has one.**

| Central unit | Serial (RTU / ASCII)   | Modbus IP (master & slave) |
| ------------ | ---------------------- | -------------------------- |
| **CU3-10M**  | **Yes — the only one** | Yes                        |
| CU3-09M      | No                     | Yes                        |
| CU3-08M      | No                     | Yes                        |
| CU3-07M      | No                     | Yes                        |

> **If the site does not have a CU3-10M, Modbus RTU is not an option.** No firmware update changes this — the other central units have no RS-485 port to put it on. Establish which CU is installed *before* you quote a job involving RTU equipment.

**When the equipment is RTU-only and the CU is not a CU3-10M**, you have three ways out:

| Option                       | What it means                                                                           |
| ---------------------------- | --------------------------------------------------------------------------------------- |
| **Specify a CU3-10M**        | Cleanest, if the CU is not yet installed                                                |
| **Modbus RTU → TCP gateway** | A small converter on the RS-485 bus; the CU then talks Modbus IP to it                  |
| **Add a GRT3-100 as master** | The `GRT3-100-MODBUS-MASTER` firmware polls RTU devices itself, independently of the CU |

The gateway route is the usual retrofit answer, and it is what the Carrier example in §32.8 refers to when it mentions an RS-485 → TCP converter.

***

## 32.4 Wiring RS-485 for Modbus RTU

Get this wrong and you will chase phantom communication faults for days. RTU is unforgiving.

| Rule                                                  | Why                                                                   |
| ----------------------------------------------------- | --------------------------------------------------------------------- |
| **Shielded twisted pair**                             | RS-485 is differential; the twist is what rejects noise               |
| **Daisy-chain only**                                  | No stars, no spurs. Each device in, each device out.                  |
| **A/B polarity must match**                           | Swap A and B and nothing communicates at all                          |
| **120 Ω terminator at&#x20;*****both*****&#x20;ends** | Two, not one, not three. Unterminated buses give intermittent faults. |
| **Ground the shield at one point only**               | Preferably the CU end. Grounding both ends creates a loop.            |
| **Same baud, parity and stop bits on every device**   | One mismatched device can disturb the whole bus                       |

```
  [CU3-10M/Modbus] ──── A/B twisted pair ──── [device] ──── [device] ──── [device]
        │                                                                     │
      120 Ω                                                                 120 Ω
```

Default serial settings on most equipment: **9600 bps, 8N1** (8 data bits, no parity, 1 stop bit). Change it only if you need the speed and every device supports it.

> **Intermittent Modbus faults are almost always physical.** Before touching the project, check termination, polarity and shield grounding. A bus that works with two devices and fails with five is a wiring problem, not a configuration one.

***

## 32.5 Tutorial A — iNELS as serial Modbus master (CU3-10M only)

> **Requires a CU3-10M.** `Internal-Modbus-Master` is only available under a CU3-10M, because it is the only central unit with an RS-485 port. On a CU3-07M, CU3-08M or CU3-09M the module will not be offered in the **New slave** list — that is expected, not a fault. Use [§32.6](#326-tutorial-b--inels-as-modbus-ip-master) instead, with a gateway if the equipment is RTU-only.
>
> **The running example in this manual uses a CU3-08M**, so this tutorial is the one place that departs from it.

Reading and controlling a third-party device. The example is generic; §32.8 walks a real one.

### Step 1 — Get the register map

**You cannot do anything without the third-party device's Modbus documentation.** You need, for every value you care about:

* the **register number**
* the **data type** (INT16, UINT16, INT32, FLOAT…)
* whether it is **read-only or read/write**
* any **scaling factor**

Register numbering follows the Modbus convention:

| Range   | Type              | Access                 |
| ------- | ----------------- | ---------------------- |
| `0xxxx` | Coils             | read/write, single bit |
| `1xxxx` | Discrete inputs   | read-only, single bit  |
| `3xxxx` | Input registers   | read-only, 16-bit      |
| `4xxxx` | Holding registers | read/write, 16-bit     |

> **Watch the off-by-one.** Documentation often lists register `40001` while the value actually on the wire is offset `0x0000`. Some manufacturers document the offset, some the register number. If everything you read is one register out, this is why.

> **Scaling is the other common trap.** A temperature of 21.5 °C is usually transmitted as `215` with a note "scaled ×10". iDM3 supports a **multiplication** setting on Modbus values to undo this — see the note in §32.7.

### Step 2 — Add the serial Modbus module

1. **Project** ribbon tab → **Device manager**.
2. Select the **central unit**.
3. **New slave** → **`Internal-Modbus-Master`** → **OK**.
4. Select it, set **Description** — `Modbus RTU bus`.
5. In **Parameters**, set the five serial settings to match the third-party device **exactly**:

| Parameter        | Options                                             | Default |
| ---------------- | --------------------------------------------------- | ------- |
| **Modbus type:** | `RTU` · `ASCII`                                     | `RTU`   |
| **Boudrate:**    | 2400 · 4800 · 9600 · 19200 · 38400 · 57600 · 115200 | `19200` |
| **Data bits:**   | 8                                                   | `8`     |
| **Parity:**      | `NONE` · `ODD` · `EVEN`                             | `NONE`  |
| **Stop bits:**   | 1 · 2                                               | `1`     |

> **The default is 19200, but most equipment ships at 9600.** This mismatch is the single most common reason a new Modbus bus stays silent. Check the third-party device's actual setting before you assume.

> **"Boudrate" is spelled that way in the software.** A typo in iDM3, like *"Prefernces"* on the main menu. You are looking at the right field.

> **Data bits offers only 8.** Modbus RTU is 8-bit by definition; the field exists for symmetry. `8N1` — the near-universal default — means Data bits `8`, Parity `NONE`, Stop bits `1`.

### Step 3 — Add the Modbus unit and its devices

The structure is three levels deep, and this is where people get lost:

```
  Internal-Modbus-Master          ← the bus: baud, parity, stop bits
  └── Modbus-Unit                 ← one physical slave device
      ├── Modbus-Device1          ← ONE REGISTER
      ├── Modbus-Device2          ← another register
      └── Modbus-Device3          ← another register
```

> **A "Modbus-Device" is a register, not a device.** The naming is misleading. One physical piece of equipment is a **`Modbus-Unit`**; each value you want to read or write from it is a **`Modbus-Device`** underneath. An energy meter exposing voltage, current and power is one `Modbus-Unit` with three `Modbus-Device`s.

1. **Select the `Internal-Modbus-Master`** module.
2. **New unit** → **`Modbus-Unit`** → **OK**. Describe it — `Heat pump`.
3. It arrives with a single **`Modbus-Device1`**. Add one more for each additional register.
4. Set the **`Modbus-Unit`'s own Address** to the physical slave address of the equipment.

> **Addresses come from the hardware, not from you.** They are set by DIP switches or the device's own menu. Read them off the equipment. iDM3 accepts them in **decimal as well as hex**, which matters because Modbus documentation is almost always decimal.

### Step 4 — Map each register

Select a `Modbus-Device` and fill in its three parameters. This is the heart of the whole chapter.

| Parameter                | Range                                                     | What it means                                        |
| ------------------------ | --------------------------------------------------------- | ---------------------------------------------------- |
| **Register address:**    | `0–65535`                                                 | The register **offset** — see the warning below      |
| **Data type:**           | see table                                                 | Which Modbus function and how to interpret the bytes |
| **Value specification:** | `Not-Used` · `Multiplication 100x` · `Multiplication 10x` | Undo the device's scaling                            |

#### Data type — all twelve options

The **Data type** field does two jobs at once: it picks the Modbus function code *and* the way the bytes are decoded. Read/write ability is implied by the choice.

| Data type                                   | Access     | Width                      |
| ------------------------------------------- | ---------- | -------------------------- |
| `Read-Discrete-Input`                       | read-only  | 1 bit                      |
| `Read-Write-Coil`                           | read/write | 1 bit                      |
| `Read-Input-Register-UInt16`                | read-only  | 16-bit                     |
| `Read-Write-Holding-Register-UInt16`        | read/write | 16-bit                     |
| `Read-Input-Register-UInt32`                | read-only  | 32-bit                     |
| `Read-Write-Holding-Register-UInt32`        | read/write | 32-bit                     |
| `Read-Input-Register-UInt32-Invert`         | read-only  | 32-bit, word-swapped       |
| `Read-Write-Holding-Register-UInt32-Invert` | read/write | 32-bit, word-swapped       |
| `Read-Input-Register-Float`                 | read-only  | 32-bit float               |
| `Read-Write-Holding-Register-Float`         | read/write | 32-bit float               |
| `Read-Input-Register-Float-Invert`          | read-only  | 32-bit float, word-swapped |
| `Read-Write-Holding-Register-Float-Invert`  | read/write | 32-bit float, word-swapped |

The default is **`Read-Write-Holding-Register-UInt16`**, which is the right choice surprisingly often.

> **The `-Invert` variants exist for word order.** Modbus never standardised how the two halves of a 32-bit value are ordered, so manufacturers differ. If a 32-bit value reads as nonsense — wildly large, or jumping erratically — switch to the `-Invert` version of the same type. That single change fixes it more often than anything else.

> **Match the type to the documentation, not to what you want.** If the manual says the register is read-only (`3xxxx`, an input register), choosing a `Read-Write-Holding-Register` type will not make it writable — it will read the wrong register entirely.

#### Register address — the off-by-one that catches everyone

**Register address** takes the **offset**, not the register number printed in most documentation.

| Documentation says | Type             | Enter as **Register address** |
| ------------------ | ---------------- | ----------------------------- |
| `40001`            | holding register | `0`                           |
| `40002`            | holding register | `1`                           |
| `30001`            | input register   | `0`                           |
| `30002`            | input register   | `1`                           |

The leading digit (`3` or `4`) is not part of the address — it tells you the register *type*, which you have already expressed in **Data type**. Subtract it and the `1`.

> **If every value you read is one register out, this is why.** It is the most common Modbus configuration error in any system, not just iNELS.

#### Value specification — scaling

Modbus carries integers, so a temperature of 21.5 °C is usually transmitted as `215` with a note saying "scaled ×10". **Value specification** undoes that:

| Documentation says         | Set Value specification to |
| -------------------------- | -------------------------- |
| scaled ×10 (215 = 21.5)    | `Multiplication 10x`       |
| scaled ×100 (2150 = 21.50) | `Multiplication 100x`      |
| raw value, no scaling      | `Not-Used`                 |

### Step 5 — Use it in your project

This is the part that makes Modbus useful, and it needs no new concepts. A mapped Modbus value behaves like any other device:

**As an actor** — react to a third-party value:

| Actor                       | Action                   | Function       | Consumer          |
| --------------------------- | ------------------------ | -------------- | ----------------- |
| Modbus temperature register | `Analog in value change` | `DIGITAL_ON`   | ventilation relay |
| Modbus alarm coil           | `Digital IN switch ON`   | `GSM send SMS` | SMS output        |

**As a consumer** — control the third-party device:

| Actor        | Action                    | Function           | Consumer                 |
| ------------ | ------------------------- | ------------------ | ------------------------ |
| wall button  | `Short down`              | `Analog set level` | Modbus setpoint register |
| time program | `Program value switch ON` | `Analog set level` | Modbus mode register     |

> **Register objects are analog, coil objects are digital.** A 16-bit register — whatever it carries — raises `Analog in value change` and is written with **analog** functions such as `Analog set level`. A coil behaves like a digital input or output. Match the function type to the **Data type** you chose, not to what the value means.

**In conditions** — gate a rule on a third-party value:

> **Restriction value** — Modbus outside-temperature register `<` `5`

That is the whole point: once mapped, the third-party equipment is just another set of actors and consumers in the model from [Chapter 2](/inels-bus/inels-design-manager-idm3/how-programming-works-in-idm3.md).

### Step 6 — Test

**Managers → Monitor** shows live Modbus values from the CU. Watch a register you know the value of — a room temperature — and confirm it reads sensibly. If it reads `215` instead of `21.5`, your scaling is not applied. If it reads garbage, check data type and byte order. If it reads nothing, it is the bus or the address.

***

## 32.6 Tutorial B — iNELS as Modbus IP master (all central units)

> **This works on every central unit** — CU3-07M, CU3-08M, CU3-09M and CU3-10M. If you are not sure which CU a site has, this is the safe route.

The same job over Ethernet, and considerably less to go wrong.

1. **Device manager** → select the central unit → **New slave** → **`Modbus-IP-Master`** → **OK**.

   **This module has no parameters of its own.** There is no baud rate, parity or port to set at bus level — every setting lives on the individual devices. If you open its Parameters panel and find it empty, nothing is wrong.
2. **Select it** → **New unit** → **`Modbus-IP-Master-Unit`** → **OK**. Describe it — `Energy meter`.
3. On the **unit**, set the two connection parameters:

| Unit parameter  | Range     | Notes                                |
| --------------- | --------- | ------------------------------------ |
| **IP Address:** | —         | The remote device's address          |
| **Port:**       | `0–65535` | Modbus TCP is conventionally **502** |

4. Add one **`Modbus-Device`** under it per register, each with the same three parameters as §32.5: **Register address:**, **Data type:**, **Value specification:**.

**The split matters:** one **unit** = one remote device (its IP and port); one **device** = one register on it. So a meter exposing four values is one `Modbus-IP-Master-Unit` with four `Modbus-Device`s — you enter the IP once, not four times.

One `Modbus-IP-Master` module can hold many units, so a single module polls equipment scattered across as many IP addresses as you like.

No termination resistors, no polarity, no baud rate. If the device is reachable and the port is open, it works.

> **Check the network path before you debug the project.** A Modbus TCP device on another VLAN, or behind a firewall blocking port 502, looks exactly like a configuration error. Ping it first.

***

## 32.7 Tutorial C — iNELS as a Modbus slave

Now the other direction: a **building management system, SCADA or PLC** reads and controls the iNELS installation.

### Set it up

**Serial (RTU/ASCII)** — *CU3-10M only:*

1. **Device manager** → central unit → **New slave** → **`Internal-Modbus-Slave`** → **OK**.
2. Set the same five serial parameters as the master module — **Modbus type:**, **Boudrate:**, **Data bits:**, **Parity:**, **Stop bits:** — matching whatever the polling system uses.

**Over Ethernet** — *any central unit, and the usual choice for a BMS:*

1. **Device manager** → central unit → **New slave** → **`Modbus-IP-Slave`** → **OK**.
2. Set its one parameter, **Port:** (`0–65535`). Use **502** unless the BMS integrator asks for something else.
3. **Select it** → **New unit** → **`Modbus-IP-Slave-Unit`** → **OK**.
4. Add a **`Modbus-Device`** for each value you want to expose, setting **Register address:**, **Data type:** and **Value specification:** on each.

> **On the slave side you are choosing the register numbers**, not discovering them. Whatever **Register address** you set is where the external system will find that value. Pick a tidy, documented layout — the BMS integrator has to work from it.

### Choose what to expose

**Nothing is visible to the outside until you deliberately expose it.** This uses the same mechanism as every other integration route — see [Chapter 24 §24.2](/inels-bus/inels-design-manager-idm3/idm3-external-systems-mqtt-modbus-cloud.md#242-exposing-devices):

| Setting                    | Effect                                             |
| -------------------------- | -------------------------------------------------- |
| **Add to iNELS 3 export:** | Makes the object visible externally                |
| **Read only:**             | The external system may read but not write         |
| **Alias:**                 | A stable name for the external system to reference |

In the **Device manager**, the bulk tools help: **Select all for export**, **Select all for export and use description**, **Unselect all for export**.

**System bits and system integers are the natural things to expose.** They are the installation's own state, they have names you control, and they are not tied to a physical device that might be replaced. Rather than exposing a relay directly, set a system bit from your logic and expose that.

> **Expose the minimum, and use Read only.** Every exposed object is something an external system can read — and, without **Read only**, write. A BMS that only displays temperatures does not need write access to your heating outputs.

> **Fix your aliases before handover and never change them.** The BMS references objects by name. Renaming an exposed object silently breaks whatever was reading it, and the failure shows up at the BMS end, not yours.

### The register map the BMS needs

**You define this map yourself.** There is no fixed CU3 register layout to look up — each `Modbus-Device` you add under the slave unit has a **Register address:** that you choose, and that is where the external system will find the value.

So the map is a design decision, and a deliverable. Plan it before you build it:

| Register | Object               | Data type                            | Access | Meaning            |
| -------- | -------------------- | ------------------------------------ | ------ | ------------------ |
| 0        | `SB_HOLIDAY_MODE`    | `Read-Write-Coil`                    | R/W    | Holiday mode       |
| 1        | `SB_ALARM_ACTIVE`    | `Read-Discrete-Input`                | R      | Alarm state        |
| 100      | `SI_LIVING_TEMP`     | `Read-Input-Register-UInt16`         | R      | Living room °C ×10 |
| 101      | `SI_LIVING_SETPOINT` | `Read-Write-Holding-Register-UInt16` | R/W    | Setpoint °C ×10    |

A layout that survives contact with a real building:

* **Group by purpose, and leave gaps.** Statuses at 0–99, temperatures at 100–199, setpoints at 200–299. Adding a room later then does not renumber anything.
* **Read-only unless there is a reason.** Use the `Read-Discrete-Input` and `Read-Input-Register` types for anything the BMS only displays.
* **Be consistent about scaling.** Pick `Multiplication 10x` for every temperature rather than mixing raw and scaled values across the map.
* **Write it down and hand it over.** The BMS integrator cannot discover your choices; a spreadsheet of register, object, type, scaling and access is the contract between you.

> **Agree who owns the map before work starts.** On most jobs the iNELS integrator defines it and the BMS integrator consumes it — but if both sides assume the other is deciding, commissioning stalls. Settle it at the design stage.

***

## 32.8 Worked example — Carrier ducted split

A real integration, published by ELKO EP. It shows the whole shape end to end.

**Goal:** control Carrier ducted split units (38KSM outdoor + 42KSM indoor) from iNELS.

**The problem:** Carrier speaks its own **CCN** protocol, not Modbus.

**The solution:** a **Carrier Translator 33CNTRAN485-01-R**, which converts CCN to Modbus RTU.

```
[CU3-10M/Modbus] ←── RS-485 / Modbus RTU ──→ [33CNTRAN485-01-R] ←── CCN ──→ [Carrier units]
     master                                      slave / CCN master
```

### What you need

* **CU3-10M/Modbus** — the Modbus-master variant
* Carrier Translator **33CNTRAN485-01-R** (ordered separately from Carrier)
* Shielded RS-485 twisted pair, daisy-chained
* 24 VAC / 24 VDC supply for the translator

### Wiring

* RS-485 from CU to translator, **A/B polarity matched**
* **120 Ω terminators at both ends**
* **Shield grounded at one point only** — preferably the CU side
* Translator **DIP switches**: Modbus RTU mode, slave address, baud rate (default **9600 bps, 8N1**)

### In iDM3

1. Add a **Modbus bus** to the CU3-10M in the Device manager.
2. Create a device with the **translator's slave address**.
3. Map registers per the Carrier translator's Modbus table.
4. Assign iNELS objects — bits and integers — for control and monitoring.

### The register map

| Function                  | Register (hex) | Type  | Notes                                      |
| ------------------------- | -------------- | ----- | ------------------------------------------ |
| Room temperature (°C)     | 30001 (0x0000) | INT16 | scaled ×10                                 |
| Setpoint temperature (°C) | 40001 (0x0000) | INT16 | R/W, scaled ×10                            |
| Operating mode            | 40002 (0x0001) | INT16 | R/W — 0 Auto, 1 Cool, 2 Heat, 3 Fan, 4 Dry |
| Fan speed                 | 40003 (0x0002) | INT16 | R/W — 0 Auto, 1 Low, 2 Med, 3 High         |
| On/Off command            | 40004 (0x0003) | Coil  | 0 Off, 1 On                                |
| Alarm status              | 30002 (0x0001) | Coil  | 1 = fault present                          |

*Registers vary with translator firmware — always verify against the translator's own manual.*

### Commissioning

1. Power everything; confirm the translator's LED shows CCN ↔ Modbus traffic.
2. In iDM3, **Monitor** the values — room temperature, setpoint, on/off.
3. Change the setpoint from iNELS and confirm the Carrier unit follows.
4. Switch mode and fan speed; confirm the indoor unit responds.
5. Turn the unit on and off.
6. Check the alarm register.

### What it buys you

* Central HVAC control from the iNELS app
* Energy management — shut the AC down when a guest card is removed
* Scenes — a "welcome" scene that sets the AC to a comfort temperature
* Room temperature and faults on the dashboard

> **Up to \~16 Carrier indoor units per translator** — check the translator datasheet. For a Modbus **TCP** connection to this particular translator you would need an RS-485 → TCP converter, because the translator itself is RTU only. That is a limitation of the translator, not of iNELS — the CU supports Modbus IP natively.

***

## 32.9 Modbus and MQTT together

Modbus units can be published over **MQTT in JSON format**, so a Modbus device the CU polls can be republished to a home-automation platform without that platform speaking Modbus at all.

That makes the CU a **protocol gateway**: RS-485 on one side, MQTT on the other.

Requires recent CU firmware — see [Chapter 24 §24.4](/inels-bus/inels-design-manager-idm3/idm3-external-systems-mqtt-modbus-cloud.md#244-mqtt) and `Advance/Documentation/BUS unit to MQTT.txt`.

***

## 32.10 Troubleshooting

| Symptom                                                | Cause                                                                    | Fix                                                           |
| ------------------------------------------------------ | ------------------------------------------------------------------------ | ------------------------------------------------------------- |
| Nothing at all on a new serial bus                     | **Boudrate:** left at the `19200` default while the device ships at 9600 | Match all five serial parameters                              |
| No communication (serial)                              | A/B swapped; wrong **Modbus Address:**                                   | Check polarity, read the address off the hardware             |
| Works with 2 devices, fails with 5                     | Missing or extra terminators; star topology                              | Two 120 Ω, daisy-chain only                                   |
| Intermittent, worse when plant runs                    | Shield grounded at both ends                                             | Ground at the CU end only                                     |
| Every value one register out                           | **Register address:** given the documented number, not the offset        | `40001` → `0`                                                 |
| Reads `215` instead of `21.5`                          | **Value specification:** is `Not-Used`                                   | Set `Multiplication 10x`                                      |
| 32-bit values nonsense or erratic                      | Word order                                                               | Switch to the `-Invert` variant of the same **Data type:**    |
| Reads fine, writes ignored                             | An input-register or discrete-input **Data type:**                       | Use a `Read-Write-Holding-Register` or `Read-Write-Coil` type |
| Writes ignored on an exposed object                    | **Read only:** ticked                                                    | Untick it, if the BMS genuinely needs write access            |
| No communication (IP)                                  | Wrong **IP Address:** / **Port:**; firewall; different VLAN              | Ping the device; confirm port 502                             |
| `Modbus-IP-Master` has no settings                     | Correct — it has no parameters                                           | Settings are per device                                       |
| `Internal-Modbus-Master` not in the **New slave** list | The CU is not a CU3-10M                                                  | Use Modbus IP, with a gateway if needed                       |
| BMS sees nothing                                       | Objects not marked **Add to iNELS 3 export**                             | See §32.7                                                     |
| BMS suddenly broke                                     | An exposed object was renamed                                            | Restore the alias                                             |

**Use Monitor first, always.** It shows what the CU actually holds, which separates "the CU is not getting the value" from "the value is wrong" — two completely different problems.

### The five-minute diagnosis

Work in this order; each step rules out a whole class of fault:

1. **Monitor shows nothing at all** → transport. Serial parameters, polarity, address, or network.
2. **Monitor shows a value, but wrong by a factor of 10 or 100** → **Value specification:**.
3. **Wrong by exactly one register** → **Register address:** offset.
4. **Wildly wrong or erratic on 32-bit values** → `-Invert` variant.
5. **Right value, writes ignored** → **Data type:** is a read-only variant.

***

## 32.11 Parameter quick reference

**Serial module** — `Internal-Modbus-Master` / `Internal-Modbus-Slave`

| Parameter        | Options                                             | Default |
| ---------------- | --------------------------------------------------- | ------- |
| **Modbus type:** | `RTU` · `ASCII`                                     | `RTU`   |
| **Boudrate:**    | 2400 · 4800 · 9600 · 19200 · 38400 · 57600 · 115200 | `19200` |
| **Data bits:**   | 8                                                   | `8`     |
| **Parity:**      | `NONE` · `ODD` · `EVEN`                             | `NONE`  |
| **Stop bits:**   | 1 · 2                                               | `1`     |

**IP modules**

| Module             | Parameters                         |
| ------------------ | ---------------------------------- |
| `Modbus-IP-Master` | none — all settings are per device |
| `Modbus-IP-Slave`  | **Port:** `0–65535`                |

**Every `Modbus-Device`**

| Parameter                | Range                                                     |
| ------------------------ | --------------------------------------------------------- |
| **Register address:**    | `0–65535` (offset)                                        |
| **Data type:**           | 12 options — §32.5 step 4                                 |
| **Value specification:** | `Not-Used` · `Multiplication 100x` · `Multiplication 10x` |

**Additional, by unit type**

| Unit                     | Unit-level parameters                                                                |
| ------------------------ | ------------------------------------------------------------------------------------ |
| `Modbus-Unit` (serial)   | none — the slave address is the unit's own **Address**                               |
| `Modbus-IP-Master-Unit`  | **IP Address:** · **Port:** `0–65535`                                                |
| `Modbus-IP-Slave-Unit`   | none — the port is on the `Modbus-IP-Slave` module                                   |
| `GRT3-100-MODBUS-MASTER` | **Modbus Address:** `0–254` · **Modbus response timeout:** `0–254` · 24 device slots |

**Every `Modbus-Device`, under any of the above, carries exactly three parameters** — **Register address:**, **Data type:**, **Value specification:**. One device = one register.

***

## What you learned

* **Serial Modbus needs a CU3-10M** — it is the only central unit with an RS-485 port
* **Modbus IP works on every central unit**, and is the safe default
* RTU-only equipment on another CU means a **gateway**, a CU swap, or a GRT3-100 master
* **Master** = the CU polls; **slave** = the CU is polled. The CU can be both at once.
* A **`Modbus-Device` is a register**, not a device — one physical slave is a `Modbus-Unit`
* **Register address is the offset**: documented `40001` is `0`
* **Data type** picks the function code *and* the decoding; `-Invert` fixes 32-bit word order
* **Value specification** undoes ×10 / ×100 scaling
* The serial default is **19200**, but most equipment ships at **9600**
* `Modbus-IP-Master` has no bus-level settings — IP and port live on each device
* On the **slave** side you **define** the register map; write it down and hand it over
* Mapped Modbus values are ordinary actors and consumers in wires and conditions

***

## Before you promise a customer Modbus

* [ ] You have the third-party device's **Modbus register documentation**
* [ ] You know whether it is **RTU or IP**
* [ ] You know whether iNELS needs to be **master or slave** — or both
* [ ] **Which central unit is on site** — RTU needs a CU3-10M; IP works on all of them
* [ ] If RTU equipment meets a non-CU3-10M: gateway, CU swap, or GRT3-100 master
* [ ] For RTU: cable type, topology, termination and grounding are planned
* [ ] For a BMS: you have **designed the register map** and agreed who owns it (§32.7)
* [ ] You have confirmed the device's **baud rate, parity and stop bits** — not assumed the defaults
* [ ] You know each register's **offset**, **data type** and **scaling factor**

***

**Next:** [Chapter 33 — Tutorial 11: linking two central units over Modbus IP](/inels-bus/inels-design-manager-idm3/linking-two-inels-central-units-over-modbus-ip.md)

**See also:** [Chapter 24 — External systems](/inels-bus/inels-design-manager-idm3/idm3-external-systems-mqtt-modbus-cloud.md) · [Chapter 26 — Monitor](/inels-bus/inels-design-manager-idm3/idm3-simulation-and-monitor.md) · [Chapter 20 — System manager](/inels-bus/inels-design-manager-idm3/idm3-system-manager-reference.md)
