# How to map floating point values in MODBUS?

A

#### A N Muralidhara

We are designing a instrument to measure voltage and current. We have floating point values like 123.4567 volts and 654.23456 Amps. These are to be presented on MODBUS. I like to know which is the best method, function code to do this. Some of you have must have had some experience on handling this king of values. Can some one help us on this?

M

#### MAX POWER

Will your instrument be able to acutally measure that accurately? The number of significant digits you show is almost ridiculous. But if you truly are getting that precise (I doubt it) then you probably want to send your data in 32 bit long integer format, scaled by a scale factor. Make another register for the scale or just fix the scale.
OR
The IEEE754 32 bit floating point format is borderline for your "precision" so you may want to go with 64 bit "double precision" format.

Now: in Modbus(R) it is common to send HI first then LO. Therefore do not word-swap, or byte-swap. Setup your registers in consecutive order so that 400001 is the upper 16 bits, 400002 is the next 16 bits, etc...

Make it so that Master will get an address error if it queries 400001 without the proper number of registers to read it entirely! Do the same for writes. This ensures that the registers do not change partially during a read, or when writing, it ensures that partial data is not treated as data.

M

#### Mark Tracy

The best way is to encode the floating point value in IEEE 754 format. This will allow you to tranfer the 2 16-bit words of data via the Modbus protocol.

S

#### Santhosh

Hi,

Normally in SCADA packages, these floating point values were read using function code 3 and 4 and written using function 6 and 16. Its better to give the commonly available method in packages. Otherwise for each package, you may have to change the implementation.

Sunlux Technologies provides MODBUS master and slave protocol stacks that is ANSI C compliant and can be ported to any hardware with OS and also to any hardware without OS with the help of a cross compiler. We have successfully ported to many controller boards with 8051, 68K, x86 etc. For more info contact either me or check our website http://www.sunlux-india.com.

Cheers,
Santhosh
[email protected]

J

#### Jeff Ruszler

You can transmit (as a "master") floating point values using modbus command #16 which sends (writes) a group of 16 bit registers. A "master" can read groups of 16 bit registers from a "slave" device using command #3. Two sequential registers can then be interpeted as a 32 bit IEEE 754 std floating point value. The Modicon standard is to send the low order word (register) first and the high order word second. But be careful, some vendors reverse these words.

If you have floating point values to "present" to a Modbus master I presume you intend your instrument to be a Slave. In this case you would have to respond to a command #3 with a properly formatted response with your floating point values properly encoded in sequential words in the "data" portion of the response.

The above presumes you are familiar with Modbus Protocol and IEEE floating point numbers. If not, you might want to download the Modicon modbus reference guide PI-MBUS-300. A good reference on IEEE floating point numbers can be found at http://www.math.grin.edu/~stone/courses/fundamentals/IEEE-reals.html

A

#### Anonymous

There are two methods of doing this.
1. Scale a number with a range (most simple method). Descale the number at the host (receiving) end

2. Use an internationally accepted representation as mentioned below...
Floating point numbers are represented best in the IEEE Floating point representation. The formula to do this is available from a variety of sources. There are two versions (actually more than 2 but most commonly used are these). a. Single precision floating point: which is 32 bits in length
b. Double precision floating point: which is 64 bits in length.

For your application, you can use 32 bits. Of course, when we talk of Modbus, as a default, all registers will be 16 bits long only (some variants like Enron, Daniel Modbus do exist, but are non standard). To accomodate 32 bits, use two consequetive registers of 16 bits each and follow the formula to present the data.

One website I know of which helps in conversion of Decimal OR HEX or Binary numbers into IEEE float is http://www.markworld.com/showfloat.html. This helps in verifying the program also.

Look up google.com to check for the exact formula for this. Search for "IEEE Floating Point".
Hope this helps.

R

#### Ramakrishnan, Raja $$GE Energy$$

Hi,

Use function = 3, to send the request and use IEEE format to covert. I have used Modbus to read current, voltage and power values from power meter. Send your mailID to [email protected]. I will give the source code.

M

#### Max Power

Actually, you have it backwards.
The modicon spec "PDI-MBUS-300 REV J" is for 16 bit registers. High byte first, then low byte, within the register. THAT IS ALL. THERE IS NO SPEC FOR 32 BIT so do what you wish.
HOWEVER, to keep with the modicon spec's trend, you should always send the higher (most significant) bytes first. (And I mean most significant, and not particularly their location in memory."

So, for a 32 bit IEEE754 register pair, you should send (MSB of the MSW|LSB of the MSW) first and (MSB of the LSW|LSB of the LSW) second.
That keeps with the trend. (MSB = most significatn byte, LSB = least, MSW = most significant 16 bit word, LSW = least)
The reason some mfgrs swapped the bytes, or words in some cases, is because they did not understand how the x86 processor stores data. So when they fetched the data from memory as bytes, it was flipped, but if they read it into a register first and then sent it, it would have been fine....

Now to make it compatible with all other byte orders (ABCD, CDAB, DCAB, BADC) without having to set a configuration parameter - you could make register offsets to read/write the various data formats.

R

#### Richard Mahn

In the Modicon "Open Modbus/TCP Specification", Relase 1.0 March 29, 1999 (openbus.doc) section B.2.2 states that on a 984 for a 32 bit floating point value the first register will be bits 15 - 0 of the 32 bit number and the second register contains bits 31-16 of the 32 bit number. The low word/high word ordering is also indicated for 32 bit signed and unsigned quanities.

R

#### Rishi

Could you please provide the source code for the same.

<b>Moderator&#8217;s Note</b> This is an old thread from 2004. I suggest you use the email the poster provided and see if you can contact him.

> Send your mailID to [email protected]. I will give the source code.