How to convert modbus reading

Aimin Ariff

Member
Join Date
Mar 2023
Location
Selangor
Posts
28
Hello guys, I used modscan32 before to read data using TCPIP based on given IP Address, Device ID and etc. The data I used to read in modscan32 are just in integer. So it is fine and I can read it based on address 40001 until 40020 for all the data.

But then, when the data change to float, the reading value in modscan32 changed completely like 168392 for address 40001. And when I did floating point or swap, it combined both 40002 and 40001 with a value but the value is still not the same as the real value extract.. How can I convert the data to real numbers of float? For example, temperature of 32.67 instead of having random number in the integer in modscan32?
 
Hi,

The floating point number consists of 2 words and you need somehow to manipulate these words in order to get a floating point.

You get a large number, that is not a floating point, therefore if the words you read were swapped you would be getting a weird floating point number. Perhaps you should check if the registers you read form a floating point number.

Best Regards
Konstantin Kolev
 
But then, when the data change to float, the reading value in modscan32 changed completely like 168392[??] for address 40001. And when I did floating point or swap, it combined both 40002 and 40001 with a value but the value is still not the same as the real value extract.. How can I convert the data to real numbers of float? For example, temperature of 32.67 instead of having random number in the integer in modscan32?
It's all in the bookkeeping of the bits.

Without knowing the details of what model Modbus device and what model PLC are in use here, we can offer little more help than that, other than the TL;DR background information below.

TL;DR

The range of values for Modbus registers is [0:65535] ([0x0000:0xFFFF] hexadecimal; [-32768:+32767] signed).

That value from Post #1, 168392, is out of range for any Modbus register. What are the actual values you are seeing from Modbus registers 4:0001 and 4:0002 (i.e. Holding Registers 1 and 2)?

The 32-bits of a single-precision, IEEE-754, floating-point value (see here) will span two adjacent 16-bit Holding Registers.

For a value of 32.67, which is between 32 (=25) and 64 (=26), the "higher" 16-bit register will be at least 16896 (decimal), and less than 17204:
Code:
(Python using the struct module:)
>>> import struct

>>> struct.unpack('>HH',struct.pack('>f',32.0))

([COLOR=#0000ff][B]16896[/B][/COLOR], [COLOR=#ff00ff][B]0[/B][/COLOR])

>>> struct.unpack('>HH',struct.pack('>f',64.0))

([COLOR=#0000ff][B]17024[/B][/COLOR], [B][COLOR=#ff00ff]0[/COLOR][/B])
An actual value such as 32.67, would usually have a non-zero value in the "lower" 16-bit register:
Code:
>>> struct.unpack('>HH',struct.pack('>f',[COLOR=#a0522d][B]32.67[/B][/COLOR]))

([COLOR=#0000ff][B]16898[/B][/COLOR], [COLOR=#ff00ff][B]44564[/B][/COLOR])
Whether the higher or lower 16-bit value is at 4:0001, and the other at 4:0002, is dependent on the byte ordering architecture of the Modbus device. But that will usually be easy to determine by inspection once the values are read into the PLC.

How those 16-bit values in the PLC are combined into the single 32-bit floating-point value in the PLC is dependent on the byte ordering architecture of the PLC.
 
For a floating point value of 32.67 40001 should be -20972 & 40002 should be 16898 however, these could be word or byte reversed there could be slightly different values but that depends on how each system handles the floting point data for example your 40001 being 168392 is somewhere close to 40002 being 16898 in mine
so it does sound like there is some word swapping could you post the values in both registers as what you have shown seems to be the float displayed as a 32 bit integer. but that does not quite make sense as it should be 1107471892
 
I have always found that the best way to figure out modbus is to view the data in binary format, view the expected data in binary format, and then to compare the two values and look for the matching patterns. To convert two raw modbus registers to binary you can use the Windows calculator, set to programmer mode, or this online converter:
https://www.rapidtables.com/convert/number/decimal-to-binary.html
To convert the expected float value to binary you can use this online converter:
https://www.h-schmidt.net/FloatConverter/IEEE754.html
Then you can compare the two binary numbers and look for patterns that match, then you can know what conversion you have to do.

Or you can just use the float to binary as a binary to float converter and see what the binary value you have represents as a float value.

The device receiving the modbus data generally has some method of conversion between data types.
 
As @parky requested, the best thing @Aimin Ariff could do is post the actual 16-bit values transferred from the Modbus device (hexadecimal is most useful), as well as details of the make and model of the devices involved.

Usually two 16-bit values in consecutive memory locations can be bit-copied into, or interpreted as, a memory location containing a float-pointing value. If not, there are also arithmetic approaches that can mung the 16-bit integers to the correct floating point value.

TL;DR

Once we have the 16-bit value pair, it will be trivial to see how the floating-point value is encoded. Some Modbus device put a fixed and known floating point value into a pair of holding registers, to make it easier to decode this sort of issue.

Byte swapping should not* be an issue. The Modbus protocol specifically passes almost all 16-bits words MSByte-first, so if the internal architecture at either end of the protocol, whether the Modbus device (typically slave) or PLC (typically master), is LSByte-first, then that end should be handling the byte swap when converting to or from the protocol stream, and such necessary byte swapping should be invisible to the user.

OTOH, when combining 16-bit register values into 32-bit** quantities, such as single-precision floating-point values, word swapping may be an issue.

* N.B. I specifically wrote "should not," I specifically did not write "is never;" as @cardoscea notes, despite the clear and simple Modbus protocol documents available, there are no Modbus Police enforcing the implementation details of any devices.

** or larger
 
It sounds like by using modscan that this is only being used as a test the see the data, I have never used modscan but it seems to be a sort of modbus capture or simulator so probably cannot do any programming within it apart from register or byte swap etc.
 
See the image below from the ModScan help file. The second and third image demonstrate what I was referring to. I don't see a way to tell ModScan the order of the most- and least-significant 16-bit registers; maybe ModScan sorts it out heuristically.

If it assumes 4:0001 contains the most-significant 16 bits and 4:0002 the least-significant 16 bits, but the device sends the opposite order (most-significant last), then reading the registers starting at 4:0002 would put 4:0003, i.e. garbage, into the least significant bits of ModScan's floating-point value and still return a value to an accuracy better that 1%.
Untitled.png
 
Recently a user of my HMI asked me about the possibility of reading 64-bit float through Modbus, because on his Car Chargepoint, in the Modbus address table, some values were integers and others 64-bit float, that is, double precision.

Maybe your floats are 64-bit ?
 
Guyssss, you guys were really helping me and made my day, and thank you very much for that. I have read all of your solutions.. I tried it one by one.. I figured out that @KonstantinKolev is right, a floating point use two registers or two words.. I ask the tech guy in the factory and it turns out, the change the modbus data type to float, but does not change some of the address to the interval of 2 which means, 40002,40004,.... Previously they use integer, thats why it has no problem with address of interval of 1.. So that is why the values fluctuate so much as some of the data are fighting each other to be displayed on the same address.


@drbitboy and @Parky, yeah thats why it made me so confused, I tried to use the conversion as well and yes, the value doesnt make sense. Now I know why haha


@BryanG I used that website also for the conversion, it was really helpful but I still need to understand the calculations better, especially Mantissa.

@lfe At first I thought about this also, but when I asked the them, they still used 32 bit..

By the way guys, Thank you very much for helping me, A LOT!!
 
I still need to understand the calculations better, especially Mantissa.
Untitled.png
The mantissa bits are the salmon color. In their basic form in the 32-bit float, the 23 mantissa bits represent a 24-bit binary integer, with the high bit b23 missing but inferred to be 1, and that 24-bit integer is scaled by 2-23.
 
Thankssss!!! Btw now I am having other problem because the tech guy set an address for temperature for float, start from 0, but modbus dont have 40000 address register.. Do you have any idea on how to do it?
 
Thankssss!!! Btw now I am having other problem because the tech guy set an address for temperature for float, start from 0, but modbus dont have 40000 address register.. Do you have any idea on how to do it?

Some manuals instead of using the address 40001 for the first holding register indicate an offset with respect to 40001, therefore 0 refers to 40001, 1 to 40002 etc.
 

Similar Topics

Hello, First, please excuse my question I am new to Modbus. I have a CX-5140 control unit from Beckhoff and an instrumentation device that...
Replies
3
Views
3,127
Found an awesome point of sale for $500. It sends an ascii string when a product is sold. Need to convert this into a number between 0 and 255 or...
Replies
1
Views
2,276
I need a good idea to solve a small task. My customer bought a measuring device where the measurement is collected by a controller from a...
Replies
6
Views
3,245
Need a little help here, I need to poll a radio/modem over Allen-Bradley Ehernet/IP. The existing radio/modem is geared up Modbus. Anybody know...
Replies
3
Views
1,922
Hi All Using RSlogix 5k v.15 modbus master sample code. plc(master) is connected to modbus device(slave). If i use function code 1 to read...
Replies
2
Views
3,036
Back
Top Bottom