LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

modbus: float to two words

Solved!
Go to solution

I am writing values to my flowmeter with modbus/TCP and the setpoint is a float over 2 registers.

Documentation says this:

 

  Floating point parameters have a length of 4 bytes and are mapped on two consecutive Modbus
registers. Floats are in single precision IEEE format (1 sign bit, 8 bits exponent and 23 bits fraction). The
first register contains bit 32-16, the second register contains bit 15-0.

 

The modbus library sends unsigned words, so how do I break a float up into two words, matching the requirements stated above.

 

Thanks!

0 Kudos
Message 1 of 12
(13,443 Views)

Use the functions Split Numbers and Join Numbers that are on the Numeric >> Data Manipulation palette.

Message 2 of 12
(13,432 Views)

thanks for that!

 

I see it only takes integers, how about single precision floats?

 

Last, some of the registers also take unsigned characters or signed words.

 

How do I send a character and how do I send a signed word, since the modbus library sends unsigned words only.

 

Thanks!

 

 

0 Kudos
Message 3 of 12
(13,427 Views)

You use the typecast function to convert the integers to floats, or the floats to integers as the case may be.

 

Likewise if you are using signed integers, you can use typecast to change it to an unsigned integer.  It doesn't change the bytes, it just changes what the bytes mean to the LabVIEW program.

 

Attached is a VI I use (in LV 2009) to do the conversions from U16 registers to singles.

 

PS, actually in the end, the modbus library always converts the data to strings to that it can transmit a series of bytes whether it is serial or TCP/IP communication.

Message 4 of 12
(13,418 Views)

thanks so much for the clarifying answer.

It now works, but if I cast for instance 12.33 to  unsigned word, split it into two words and join it and typecast back to single precision I am left with a small discrepancy: 12.3125 is the result. this is normal?

 

If I'm typecasting a signed word (lets say -3000) to an unsigned word and send it through the modbus library, it is also received as a signed integer at the other side?

 

 

0 Kudos
Message 5 of 12
(13,410 Views)

I'm not sure why you'd be getting 12.3125 instead of 12.33.

 

Here is an example of my code working.

 

One thing to watch out for is the order of the words, whether the most significant word or the least significant word comes first.

 

I may have even made a mistake in my VI where the input I called Little Endian perhaps should have been called Big Endian.

 

 

If you send the data through the modbus library, the only thing that the other side gets is some bytes (2 bytes per register, and 2 registers.)  It is up to the device to intepret those 2 registers however it wants.

Message 6 of 12
(13,404 Views)

must be me being noob, but check the attached code. Im on labview 2010

0 Kudos
Message 7 of 12
(13,397 Views)

as you told in your first post, floats are 32 bit...but you used in your typecast a unsigned word (16 bit), hope CodeSnippets work right... If you use 32 bit (U32), everything works fine...

 

hope this helps

 

christian


THINK G!! 😉
------------------------------------------------------------------------------------------------
Using LabView 2010 and 2011 on Mac and Win
Programming in Microsoft Visual C++ (Win), XCode (Mac)
Message 8 of 12
(13,382 Views)

Yes that did the trick, but why isnt the 16 bit type cast enough to accurately transform the number? Its only 4 digits long.

 

I used the word typecast because the modbus library takes words, but that isnt necessary?

 

0 Kudos
Message 9 of 12
(13,373 Views)

A single precision float uses 4 bytes or 32 bits.  Some of those bits are designated at mantissa, some as the exponent, and some as sign.  The boundaries of those different sections don't necessarily fall on byte boundaries.  All of this is determined by an IEEE standard.  It has nothing to do with number of digits as that only means something in the decimal world to you and me.  It means nothing in the binary world to the PC.  Typecasting it to a U16 means somehow you threw away 2 bytes of data.  I'm actually suprised the end result of converting back got to as close as it was.  I guess most of those bits (but not all) that got thrown away were zero.

 

You do need to typecast, but you need to typecast from a 32 bit bit float to a 32 bit integer (otherwise you'd lose bits), thay way you can split the 32 bit integer into two 16 bit integer words (U16) for the modbus library.

Message 10 of 12
(13,365 Views)