modbus floating point format


Thread Starter


Hello all:

I am a Modbus newbie. Our application (slave device) can fit all values from -32767 to 32676. So, I am thinking of using a 16 bit signed integer for everything. For floating point, I would like to use a simple rule of sending the data by multiplying by 100 by the slave, and master receiving the data divides by 100?

Example 1: Temperature value desired to be sent (26.75C). Slave sends 2675, and master divides by 100 and displays 26.75.

This keeps my code really simple. All my floating point values are inside the range -327.67 and +327.67.
All we would do is have the memory map clearly explain how floating point is calculated and parsed. Would this suffice?

We need to ship our device as a slave device to customers saying we support Modbus. I am worried that customers/ems already have in-built IEEE Float format inbuilt into their master-code, and their software will balk at parsing the floating point information sent by our slave.

Please share your thoughts.
It sounds as though you have the cability to implement IEEE Single Precision if pressured by your users. So, I would suggest you do so, and if you do, keep in mind to support all 4 byte orders. The easy way of supporting the 4 byte orders is to have 4 different Register Blocks mapped to your data.

For example:
0000 to 1999 BYTE ORDER A B C D
2000 to 2999 BYTE ORDER B A D C
3000 to 3999 BYTE ORDER C D A B
4000 to 4999 BYTE ORDER D C B A

Also, to support a request for 4 floats you would support a request for 8 Modbus Registers, not 4 otherwise you would be playing Enron games.

Good luck.

This is often done. Most of the masters have some scaling functionality so they should be able to convert this value.

Only disadvantage is the accuracy because you have consider the 16 bit data format but in most cases this is not a big issue.

Bruce Durdle

Nothing wrong - but don't call it floating point because it isn't.

What you are proposing is to send values in scaled format. You could also use a per unit format, with each value being expressed as a proportion -0.9999 to +0.9999 of a tabulated maximum. It would also be possible to include a maximum value in the system as ASCII Engineering Units or similar if this is likely to change - it would need to be read by the host only once.

But if you are claiming to use a standard format (such as IEEE floating point) make sure you do in fact adhere to the standard.
Thanks a lot for the response guys!

Seems like it is ok for me to use this scaled format; You raised a good point to NOT say it is floating point. I shall remember that.

Also, any examples of how customers typically word this in a memory map?

I love Banner Engineering's documentation because they explicitly provide the format and then give an example. Very wise.

The data below are from Banner's wireless node radio with four RTDs, document 155864, page 7.

Holding Register Representation:
Min. (Dec) -32768
Max. (Dec) 32767

In high resolution mode, the temperature = (Modbus register value) ÷ 20. In low resolution mode, the temperature is (Modbus register
value) ÷ 2.

Temperature values are stored as signed values in the Modbus register. A 0 in the register is interpreted as 0°; and -32767 (65535
unsigned) in the register (0xFFFF) is interpreted as −1 ÷ 20 = −0.05° in high resolution mode and −1 ÷ 2 = −0.5° in low resolution mode.

Lynn August Linse

I would add, support for floats also depends on your embedded micro - I've seen small 8-bit PIC running full floating point.

If IEEE floats are hard on your platform, then as many people have said, the Modbus world is very comfortable with 'scaled integers' - many vendors even bundle a couple registers in a row to include the scaled value followed by divisor and/or offset.

If you do support floats, you really only need two of the possible byte-swaps. Most 'modern' systems support float as true 32-bit bigendian (BE) split as 2 x 16-bits regs (NOT as 1 32-bit reg). Legacy Modicon has the odd B-A-D-C pattern, so 2 BE words, but first word is low because early Modicon used x386 hardware, so little-endian in RAM & they just did byte-swap word-by-word in register rd/wr.

Nothing stops you from doing both, so a collection of data with scaled ints, and another area with floats.