Hi Phil,
I've been running some tests and have been able to read HR, IR, C, and Di without any problems.
Now I'm trying to write a single coil (C) and I see that the driver uses function 15 (0x0F) to execute it when it should normally use function 05 (0x05). Is there a driver setting to correct this?
There is a setting to disable the use of function 15 entirely. Then all coil writes are one-by-one with function 5. (Set the node write option "Max Coils" to zero.)
(The modbus spec seems pretty clear that function 15, if supported at all, needs to support writing single bits.)
This setting applies to the whole channel. It cannot be set per unit address.
Yeah, I know. I used the message handler you recommended a few years ago when you added the rawModbus function. In fact, I used it with ID:2 and it worked fine.
More. Hmmm. It should have worked. I see in the logs where you used rawModbus() to run function code 4, and the log message suggests you supplied an expected response length of 5 when that function returns 6 (16-bit bytes to follow, not 8).
Please test with something other than functions 3 and 4, or compute the response length for your tests using Lufkin expectations.
I don't see any reason the rawModbus function won't work with ELAM.
Oh, I see. I don't really understand how to calculate the expected response length. I used that size because I took it from an example where two HR were read, and I assumed it was the same for two IR. Is there a formula or function I can use to calculate the expected response length depending on the Modbus function and the number of registers to be read?
The modbus specification describes all of the packet formats, with examples.
The format of function code 4 is identical to function code 3, so your expected response length for reading two registers of either type is five. But not for ELAM.
You were right!
I computed the response length (6 for 2 registers or 4 for 1 register), and it works.
The only downside is that using this code, I can't extract the values from the read registers (I get "Bytes to follow=0"),
from java.io import ByteArrayInputStream, ByteArrayOutputStream, DataInputStream, DataOutputStream
from com.inductiveautomation.ignition.common.model.values import QualifiedValue
baos = ByteArrayOutputStream()
dos = DataOutputStream(baos)
#Read start address and quantity
dos.writeShort(1)
dos.writeShort(1)
#Ensure data is in the byte stream
dos.flush()
rpcPayload = {'devName': 'POFF-LABO', 'unit': 300, 'functionCode': 4, 'payload': baos.toByteArray(), 'responseLen': 4}
retv = system.util.sendRequest('Test', 'RawModbus', rpcPayload)
if isinstance(retv, QualifiedValue):
if retv.quality.good:
bais = ByteArrayInputStream(retv.value)
dis = DataInputStream(bais)
bCount = dis.readByte()
print "Bytes to follow=%d" % bCount
while bCount > 0:
bCount -= 2
register = dis.readShort()
print "Register = %d" % register
else:
print repr(retv)
else:
print retv
but I know it's working because I can see it in Wireshark.
Unfortunately, I don't have enough programming experience to debug this code.