Can't read coils with Modbus TCP/IP connection to ABB RTU 540

ABB's RTU 540 doesn't allow FC1 to read coils from Ignition!

I recently went to a FAT to connect an Ignition edge device to an ABB RTU 540. The RTU's Modbus interface seems to exhibit some behavior I haven't seen before.

For example, after writing to holding registers with function code (FC) 16, reading those registers back with FC3 always returns 0. The FC16 returns a successful write, but the RTU does not return the written value on subsequent reads. This is annoying, but I can deal with it.

The biggest problem is that Ignition cannot read coils at all! OPC tags in Ignition with Modbus addresses like C1, C2, etc. show up as bad. Clicking on the value field in Designer does actually send an FC5 to the RTU which returns a successful write. However, Wireshark indicates that all the FC1 Modbus messages sent to the device to read the coils back result in Modbus exceptions.

I can never check the value of the Modbus command in Ignition because it is always bad :frowning: I ams lso concerned that some of my scripting to write to those tags might fail because Igniion might need to read the value back to confirm a good tag write.

The integrator responsible for the RTU programming said "That's just how the RTU is designed". Very frustrating!

Is this non-compliant Modbus behavior? Has anyone seen this before? Is there any workaround possible from Ignition?


It can't be non-compliant because the Modbus specification doesn't require any specific behavior for these function codes beyond the bare formatting and responses they use.

It is extremely unusual, though, and breaks the common expectation that memory areas 0 and 4 are read/write. You won't be able to use tags effectively with these units, since read doesn't mean anything even when it works. You will need to use "fire-and-forget" system.opc.write*() for everything.

I would forbid use of this RTU in future work, and replace it now with something rational if you still can.

So... you basically can't read any data at all from this thing? Can other software like Modpoll? Do you have Wireshark captures?

Ooooo! Just thought of something.

If this device is following the Modbus standard for slave devices on serial connections, then writes to unit zero (the default for IA driver) will work as a broadcast, and other function codes should yield silence, but might yield errors.

Examine the device's documentation to see if it has a non-zero unit number, and ensure that your OPC item paths use that unit number. An item path on unit #1 would look like [deviceName]1.HR50.

Slaves don't respond to broadcast commands, so if that's the case this device is extra broken.

1 Like

Correct. "should yield silence"

But Modbus TCP's adoption of unit zero as non-broadcast has muddied the waters for hasty implementers. :man_shrugging:

We are already knew the device is broken. We're just trying to understand how broken.

You will need to use "fire-and-forget" system.opc.write*() for everything.

I was not aware of system.opc.write*() ! Thanks. I will give this a go.

So... you basically can't read any data at all from this thing? Can other software like Modpoll? Do you have Wireshark captures?

I can read most registers, just not the ones I write to. Holding registers that I am supposed to write to go back to zero after a successful write, and coils that I am supposed to write to return a successful write according to Wireshark (no capture apologies) but reads on those coils using FC1 return Modbus exception x02 (Illegal Address) according to Wireshark.

As a side note, Ignition's gateway error messages were not very useful for identifying the problem :frowning:

I have been using slave 1. I was told by the integrator it shouldn't matter. I am struggling to find documentation on this RTU specifically. I might cross my fingers and email ABB.

What error messages are you seeing?

It turns out, querying one coil per Modbus message returns successful reads. The RTU mustn't support reading multiple coils at once. Changing the settings in the device connection to allow max one register per coil read fixed the issue.

1 Like

There are infinite monkeys out there producing infinite broken Modbus implementations.