Write To Modbustcp Yields Only Two Values


jclarkson

Recommended Posts

Good evening all,

I have a bit of an interesting setup and I am having some issues. I have a LabJack U6 connected to DAQFactory via USB and a PLC connected through ModbusTCP.

I can read values from the LabJack and the PLC, however, I cannot seem to write data to the PLC. I am attempting to read the RMS voltage from my powerline and send it over ModbusTCP to the PLC. I thought the PLC might be struggling with the many decimal places DAQFactory was sending out, so multipled the rms voltage by 1000 and rounded the number so there are no decimal places.

I am using the "Set Register Float (16)" I/O Type to send the values from DAQFactory to the PLC, and it kind of works, however, it only sends two numbers over the network, 122368.0 and 122880.0 (it changes randomly, there is no pattern as to when it changed). The PLC is a Schneider Momentum 171CCC96030 and doesn't seem to have any issues with other programs writing to it.

I have attached my the ctl file so that if I'm doing something silly, someone can point it out to me. I have attempted changing the I/O Types all together for setting a register, and nothing seems to work.

Thanks.

60Hz Stream.ctl

Link to comment
Share on other sites

Is the PLC register you are trying to write to actually supposed to be a float? The I/O type you select has to match what the PLC expects, not what your data might look like. It almost sounds like the register is actually an S16 instead. You might start by trying to read the register. If you can read it, then you need to use the same same data type for the write (i.e. S16, or S32 or U32, or float, etc). As for the 122368 and 122880, these are what you get when you take a 32 bit floating point number and split it into two 2 byte words. The appear random, but really the randomness is just noise in your signal.

Link to comment
Share on other sites

The PLC register that I am writing to is a "REAL" value in the PLC. I can read other "REAL" values in from the PLC using the "Read Holding Float (3)" I/O Type. Is there another option that may work better?

The two numbers that show up in the PLC (122368 and 122880) are close to the values I'm trying to send out to the PLC, but not 100% accurate. The range of values I'm sending is 121774 to 124889. I'm not cetain this is a noise issue, but a "writing almost the correct value but not quite" issue. The next step in my plan is to decode the packets and see exactly what DAQFactory is sending, then go from there.

Link to comment
Share on other sites

Ok, so I took a look at the value DAQFactory is sending, how it is transmitting over modbus and what the unit on the other end is receiving:

Value: 122565

From DAQFactory:

Tx (09:57:07.545): \x00\x00\x00\x00\x00\x0B\x01\x10\x00\x05\x00\x02\x04\x47\xEF\x62\x80

Rx (09:57:07.602): \x00\x00\x00\x00\x00\x06\x01\x10\x00\x05\x00\x02

Received at other end:

06 09:57:12.523 G RX 01 10 00 05 00 02 04 47 EF 62 80 3E 11

06 09:57:12.578 G TX 01 10 00 05 00 02 51 C9

I'm not sure why there is this issue, but do you happen to have any idea why the receiving end is adding 4 values to the end and not receiving the proper string?

Link to comment
Share on other sites

First: the DAQFactory output is correct for setting a single floating point value (which means setting TWO modbus registers). The modbus function used is 16 (0x10) Write Multiple Registers. The first 6 bytes are the TCP header, the last of those (x0B) is the the length of the rest of the packet. The next byte (x01) is the modbus ID of your device. Next (0x10) is the function. The next two (x00, x05) are the starting address. Next two (x00 x02) is the number of registers to change. Next (x04) is the byte count for the data (redundant in my opinion, but that's a different story...). Finally, we have the actual data: x47, xEF, x62, x80, which corresponds to 122565 in float.

Your PLC is for some reason saying its receiving two extra bytes at the end. Presumably this is somewhere in the PLC processing since its also not showing the Modbus TCP header. I should add that the response from the PLC to DAQFactory is the correct response.

Personally I think you have one of two things going on:

1) you have an off by one situation. You are trying to set address 5, when you should actually be setting 4 (or perhaps 6, but most likely 4). If you are off by one, you'll probably need to switch to the reverse words float version of the Set Register function, since now your registers are flipped in the order. This is most likely what's happening, and usually comes from hardware guys doing Modbus implementations and not providing proper documentation. If you (meaning the hardware guy) want to use one indexed notation for your holding registers, you should always have 40,000 in front of it. If you specify just 5, then its going to be expected that you are using 0 indexed notation.

2) your PLC has a bug in its implementation somewhere. For example, in the Galil motion control PLC, at least in the version released a year ago, if you created floating point registers, and tried to read them, they were properly spaced by 2. So, you would read, say, 2000, 2002, 2004, etc. However, if you wanted to set those same registers, you had to increment by one: 2000, 2001, 2002, etc. where setting register 2001 would change register 2002. It was pretty messed up. We have found other errors like this, for example a new Unitronics PLC under certain situations would drop a byte from the packet. They have fixed this.

Link to comment
Share on other sites

Without decoding the packet, here's a quick thought on something to check.

I've seen that behavior (float values close but not quite right) before when I had a one-offset problem at the same time as an endian-ness reversal, especially when consecutive floats are close in magnitude on the source end. You end up getting values that are proper endian but with the low word from one value and the high word from the other value, so it's in the right range, but doesn't match either value exactly.

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.