Hex to Decimal Conversion

Hello All,

Not only am I new to Modbus but have never posted on a forum before so I hope this is ok.

I have a customer who needs to pull info from a Modbus slave into his wonderware SCADA. I am familiar with the registers formatted in the 30K, 40K format, but my current slave manual has all the registers in hex. I've got the registers that convert to three numbers figured out, but the majority of hex registers on my slave convert to four numbers.

An example is register 0x0E28 which is formatted as unit32 ro. I converted 0x0E28 to 3624. This is where I do not know what to do. I/ve tried polling register 43624 but receive invalid response. I am using CAS Modbus Scanner and a B&B 485-232 converter with a USB to serial.

Any assistance is greatly appreciated.

Thank you!
In my opinion there are 2 possible reasons.

1) Try command 3 (33624). Some slaves allow only "Read holding register (3)" for analog values while others allow "Read input registers (4)" and some allow both.

2) Modbus registers can be 0 or 1 based. This means an address in a slave can be offset by 1 in the command line in the master. The easiest way to test this is to read a 16-bit word (length 1 in the command line) and offset the register by 1 (33623, 33625, 43623 or 43625). Choose a 16-bit word with a known value.

The reason to use a 16-bit word is that if you read more words in one command (p.e. 32 bits or 2 words) you receive 2 words but then one word can be the Most significant word from a 32-bit word and the other word is the Least significant word from the next 32-bit word. This is very hard to troubleshoot.
Welcome to the wild west world of Modbus. Since Modbus is an open protocol (you can download the specs from the web and being truly open, you don't have to pay for the spec, unlike other 'open' protocols), but the downside is there are no Modbus police so Modbus depends on its implementation.

Documentation tends to be spotty and cryptic.

1. memory area and Function Code in the leading numeral

The leading numeral 3 in the (3)xxxx or leading numeral 4 in the (4)xxxx format is not part of the Modbus message. Those leading numerals are so that human beings can identify which memory area the register is associated with and which Modbus Function Code works with that area. Function Code 03 reads Holding registers (4)xxxxx; Function Code 04 reads Input Registers (3)xxxx.

Typically, the register addressing using the leading numeral is one based, and would start at (4)0001, or (3)0001.
Typically, register addressing using hex is zero based and would start at 0000
(4)0001 would be one offset from 0000
(4)0002 would be one offset from 0001
(3)0006 would be one offset from 0005

Hex register addressing typically has a separate Function code associated with the action, whereas some master setups associate Function Code 03 with a register (4)0242 with a leading numeral (4).

Early Modbus was 5 digit addressing: (4)xxxx due to memory costs, which tops out at 9999 registers. Most Modbus mastera nowadays can handle 6 digit addressing (4)xxxxx, which tops out at 65,535 registers.

hex 0x0E28 could be (3)3625 or (4)3625 or (3)03625 (6 digit) or (4)03625 or some master's 3624 (there's no Modbus police to clean up bad implementations). 0x0E28 could also be a DI or coil register.

2. format
Modbus registers are 16 bits in length.
Your example "unit32 ro" is confusing. 32 probably infers a 32 bit data word, requiring a read of 2 adjacent/contiguous registers. "uint" would be a typical abbreviation for unsigned integer. I have no idea what "ro" is (reverse osmosis in my world)

32 bit data can be a long integer or floating point. Either can have multiple word-byte order issues. There are four word-byte order formats used for IEEE754 floating point, but only two are typically used. Integers can be signed or unsigned.

3. Hard knocks
It boils down to making an educated guess and some trial-and-error to see what happens when you try read a register with a known value and then see what you actually get - the right value, another value, the right data but a misinterpretation of the value because of misinterpretation of the format (using the wrong word-byte order) or an error. Don't try to read a value of zero, because unused registers are frequently zeroed out on initialization, so you could be reading a zero value from an unused register which will never populate with real data and always be zero.

Some slaves are smart enough that if the master's query for a single register is for only half of a 32 bit word, the slave will reply with an exception error. Other slaves will not and reply with half the needed bits.

32 bit word-byte order misinterpretations can provide really out-of-this-world values, like 6.3292^-17.

Reading 16 bits of one floating point value and 16 bits of the next floating point value can provide a number that is close, but no bananas.

Many of the freebie Modbus masters programs do conversion to decimal for only one format (of the four) for 32 bit floating point format and some do not handle long integers at all. You'd have to read the bits and then try to figure out what the bits convert to. I can't recall what the CAS program does or doesn't do.

If "invalid response" means there's no working 485 communications, then check serial settings (lots of devices need to be power cycled to accept serial setting changes) and be prepared to swap the driver lines on one end because the labeling of the 485 driver lines is not consistent.
WOW!! Thank you so much for taking the time to provide such an in depth response, I truly appreciate it.

Looks like I've got some serious digging ahead of me this weekend with lots of options to pursue. On the "Unit32 ro" my assumption was ro being read only, but you know what they say about assuming. I've also contacted the slave manufacturer for additional support.

Thank you again
Thank you very much for your reply.

I will try all of the above suggestions this weekend. Looks like I'm in for a steep learning curve ahead.

Thank you again!