I believe I may have stumbled with a bug on the Modbus Integration Kit.
I am a bit unsure as I would expect people to have come across this issue before, but the lack of hits in the forum says otherwise.
- I am integrating a Modbus gateway from another manufacturer. The gateway collects a bunch of I/O and makes them available as Modbus TCP. I connect to the gateway using a SNAPPAC R1 via Ethernet2, single wire, no switch.
- The gateway has its own UI where one can configure the IO mappings to the Modbus registers.
- The gateway does not create coils as single bits (what some programming languages call “bool”). Instead, a coil is represented with a byte (uint8). The first bit of the byte defines the behavior of the coil (0: off, 1: on).
- The gateway does not support FC05 (Force single coil). Instead one has to use FC15 (Force multiple coils).
- Using QModMaster, I can connect to the gateway an issue FC15 to open/close a valve (located in coil 1, address 0):
- Note that because the coil is stored as unit8 in the gateway, I have to actually “control” 8 coils rather than just one (see the 8 boxes without “x”).
- The value on coil 1 (address 0) is what defines the valve On/Off status (see box highlighted in blue). All other bits must be set to zero.
- The next valve is located on Coil 9 (address 0) and NOT on coil 2 (since Coil 1 to 8 are assigned to the first valve).
- This is the Modbus command captured with Wireshark:
- Of interest are Length: 8, Bit count: 8, Byte count:1, and Data (which is a single byte).
Based on the above, what I have to do in PAC Control is write Coils 1 to 8 with 1,0,0,0,0,0,0,0 using FC15. For that I use the command:
statusFC15Sub = O22Modbus15ForceMultipleCoils(commHandleModbus, commParametersModbus, 1, FC15ForceMultiCoilsValues, 8, statusFC15Modbus);
where 1 indicates the StartCoilNumber and 8 indicates the NumValues to write. FC15ForceMultiCoilsValues is a I32 table with 8 elements. Element  is the value to set in coil1. Elements 1 to 7 are full of zeroes.
The above configuration results in a Modbus message where:
- Length equals 9 (not 8 as expected).
- Bit count equals 8 (as expected).
- Byte count equals 2 (not 1 as expected).
- Data with 2 bytes (not 1 as expected).
The gateway returns error 3 (Illegal data value).
I believe the culprit is line 15 of O22Modbus15ForceMultipleCoils - Build TCP - Block 22:
nTemp2 =1 + (nNumValues / 8);
This variable defines the Length in bytes. Note that for NumValues=8, this results in nTemp2=2. I believe this is wrong since 8 coil values can be represented with a single byte, not two.
The same variable is later used to define the Byte Count and cycle through the numeric table. Consequently, the above error just garbles everything.
Replace the above with:
nTemp2 = 1 + ((nNumValues - 1) / 8);
This brings Length, Byte count and Data to the expected ranges.
The gateway processes the command and the valve opens/closes as expected.
Has somebody else come across with this? Does somebody have another system where they can try to replicate this issue? The kit has been around since 2015 (from what I can tell) so I fell uneasy that nobody seems to be affected so far. Maybe I am misunderstanding the whole thing?
Thanks for any tips/pointers.