Modbus Decode

TheWaterboy

Lifetime Supporting Member + Moderator
Join Date
May 2006
Location
-27.9679796,153.419016
Posts
1,931
I can't seem to sort out how to decode this into useful numbers. Maybe I'm tired and this will be obvious tomorrow but it hasn't been all day.
The register table is as shown.
Modbus registers.jpg

1. How do I create a 32 bit unsigned long in a 5380? DINTs are signed and LONG is 64 bits.
2. How to I apply a specific number of decimal places to it?

Assume that is even the correct direction to go and I can swap bytes around to get a reasonable number... what am I to do with the next register with number of decimal places? I assume it is used against the unsigned long to get a REAL value.
I have worked with swapping bytes and words to respect Endian, but I have not had a set of registers like this before with a third one for consideration.
 
Can you post an example of the actual values that arrive via Modbus ?

Are they in a SINT, INT, or DINT array ?

What interface/mechanism gets that data into the CompactLogix ? Is it a 5069-SERIAL ?

EDIT: there is a UDINT datatype in Logix 5000 now, I think since v32 or so. You can COP or CPS into it just like a DINT.

The maximum value it can hold is 16#FFFFFFFF = 4,294,967,295

What range do you expect on the totalizers ?

My guess is that the number of decimal places indicates that the decimal is implied in the large totalizer number, so you divide by 10 or 100 or 1000.

Modbus Integer Value: 8675309
Number of Decimal Places: 2
Totalizer Value: 86753.09
 
Last edited:
Everything you get should be byte-ordered correctly in the 5380*, and so it is all just a matter of extracting the bits as needed.

For the two-byte register 10 (Overflow and decimals in T):

  • Request <ID> 04 00 0A 00 01 [checksum, if RTU]
    • This is handled by the AOI, of course
  • Response written to INT tag RegT*
    • Extract MSByte to INT tag OverflowT:
      • AND RegT 7F00h OverflowT DIV OverflowT 256 OverflowT XIC RegT.15 OverflowT.7
      • Alternate: AND RegT FF00h OverflowT DIV OverflowT 256 OverflowT AND Overflow10 255 OverflowT
    • Extract LSByte to INT tag OFDecimalT
      • AND RegT 00FFh OFDecimalT
* Modbus specifies 16-bit words i.e. integers in MSB-first order on the wire, so assuming both client and server obey that convention, any conversion to local byte order is taken care of under the hood e.g. of the Modbus AOI.
 
Last edited:
Wait a minute, isn't there a BTD (BiT Distribute) instruction in Logix? Even simpler.

And yes, as Ken said, outside of Logix, for 32-bit processors, "LONG" means 32-bit integer i.e. "LONG" in that manual = Logix DINT.
 
I can't tell, it is an assumption; good point.

@TheWaterboy: is this for a McCrometer ProComm Converter?
 
Last edited:
I believe you are correct w/ McCrometer. I am undecided between modbus AOI or serial.

Elon need a few good men like you. Any thoughts?
 
I believe you are correct w/ McCrometer. I am undecided between modbus AOI or serial.

Elon need a few good men like you. Any thoughts?


The McCrometer "guess" was easy and more or less certain. I am pretty sure that means Modbus RTU only. Does the AOI do serial, or is it Modbus TCP only?
 
Hi Folks

Yes McCrometer Procomm and I am using the 5069-serial and Modbus RTU. Your powers of deduction are not to be trifled with :)

In hindsight this was not a great choice because unlike the TCP modbus in the 5380, changes to Serial modbus settings require interrupting the process with a download. But I digress..

This is what the modbus config looks like in the 5069-serial
Settings.jpg

And these are the registers starting at Command 4 of the config.
registers.jpg

While not shown above, Commands highlighted work as expected, first 2 bring in a word swapped REAL and are directly readable and the last one is just bits. Command 4 reading Register 8+ is where things start bothering me.

Command 7 has a wrong offset (I see that just now), but I haven't made it that far yet. This register resets these totalizers with FF00.
 
Command 4 reading Register 8+ is where things start bothering me.

  • addresses [0008,0009]
    • 16-bit Words = [MSW,LSW] = [0,16384] = [0x0000,0x4000] is 32-bit UDINT 0x00004000 = 16384 decimal
  • address 0010
    • 16-bit Word 0x0000 = 8-bit SINTs [MSByte,LSByte] 8-bit SINTS [0x00,0x00] = 0 overflows, 0 decimal places (so 16384 above is interpreted as 16384.0)
  • addresses [0011,0012]
    • 16-bit words [25,-19311] = [0x0019, 0xb491] = 32-bit DINT 0x0019b491 = 1684625 decimal (= [65536 * 25] + [65536 - 19311]; the subtraction from 65536 is necessary because -19311 is negative)
  • address 0013
    • 16-bit Word 0x0000 ..., so value at address [0011,0012] is 1684625.0
 
Well, Ok, That's pretty straightforward. You had me going with the 16384 when the register was 1684. But I realize now you were just testing me.

Extra credit exercise:
Assuming for a minute that address 0010 and/or 0013 would change the number of decimal places occasionally ... How would one code that as a multiplier without a "lookup table" arrangement?

I don't believe that will happen here, but I am curious how that could be done.
 

Similar Topics

Where am I going wrong here? I'm trying to turn a modbus register into the expected value of around 375 as displayed on the instrument. According...
Replies
21
Views
5,710
Hi folks, I have a Controllogix in communication with a zigbee coordinator using Logix AIO for modbus tcp. This zigbee coordinator have 3 slaves...
Replies
2
Views
100
Hi, I'm setting up a modbus master on an S7-300. It seems to work in OB1 but not when I use it in OB35. Does anyone have any ideas why? Could...
Replies
10
Views
111
Hi Everyone, i was hoping for a little help with this module. i have data that needs to be read from a different plc through the Modbus plus...
Replies
11
Views
265
I have a PH meter that I am trying to bring its data into 1756-L81. I have downloaded the Rockwell MODBUS AOI kit, but I am not sure if I need to...
Replies
5
Views
193
Back
Top Bottom