Azure / iot-edge-modbus

Modbus protocol module for use with the Azure IoT Edge
Other
90 stars 71 forks source link

Question: Would you consider supporting multiple register write? #67

Closed temelj closed 4 years ago

temelj commented 5 years ago

I understand that

Currently it supports writing back to a single register/cell in a Modbus slave.

However I've encountered a scenario where a device exposes two addresses for a single value representation. Address 13056 & 13057 correspond to a Counter 1 with a range of 0 - 999,999,999.

As a test I used QModMaster to write the value 4400 (to address 13056) and 1 (to address 13057). Perfect, the Modbus Module also reads this value fine!

However, since the modbus module only supports single register writes at a time Write to 13056 value 4400 Write to 13057 value 1

I actually end up with (0, 1) instead of the expected (4400, 1). I am not familiar with MODBUS and how the devices are designed but assuming that is NORMAL behavior for a device, I can't use this modbus module to write any values as single write operation overwrites the other register. I always end up with just the one value.

Write to 13056 value 4400 results in (4400, 0) Write to 13057 value 1 results in (0, 1)

Update No 1

The earlier "issue/question" may very well be device specific, however after talking to the manufacturer even they will have to do some investigation on their end to make sure they can re-produce my findings and provide feedback.

However: The actual device supports 32-bit reading/writing and a lot of addresses are treated by the device in 32-bit words.
This would raise a further question: Will iot-edge-modbus support the reading and writing of 32 bit addresses?

This would simplify a lot of the comms to/and from the device as the value that we intend to read/write is in 32 bit so any conversions would take place on the device itself rather than a custom hand-cranked iot-edge module. For example: If your Modbus driver does not support a 32-bit long integer format, you can read the two 16-bit registers separately, and then convert them into a 32-bit value as follows (using C notation): 32-bit value = (unsigned short) low order register + (signed short) high order register * 65536L

eg: Value[0] + ( Value[1] * 65536)

yphuangms commented 5 years ago

For holding registers, in current implementation, we support only function code 3 for read, and function code 6 for write. Function code 3 reads multiple (sequential) holding registers, while function code 6 writes only one holding register. There's no "32 bit" support (or assumption) in Modbus protocol spec. The problem could be at device side, which treats two single register write request (function code 6) differently from one multiple registers write request (function code 16). It looks like your test device will write to device memory in 32 bit while executing function code 6 (write to single holding register, which is 16 bit only). That's why you end up get an 32-bit value of 1 for your last write request is to write single holding register with value of 1. The last write quest (function code 6) is not supposed to overwrite the memory which is specified in the request.

yphuangms commented 4 years ago

Close for inactivity.