LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Conversion of 16 bit unsigned to 32 bit float

Solved!
Go to solution

Hi, i am new to labview and the data types in electronics. Due to a shortage of manpower in my company, i am required to do this myself. I've gone through several basic labview tutorials and examples but i am unable to do what i want correctly with labview. Any help is much appreciated.

 

I am using labview 8.6.1 and i've downloaded the modbus drivers. Currently, i am required to read data off a sensor and write the data into a file. Using the "MB Serial Master Query Read Input Registers (poly).vi", i am able to read the data in the registers. However, the data in the registers are 16 bit unsigned and does not give the "real"values. I am not sure about this, but i've tried using Simply Modbus 6.3.6 and changing the 16 bit unsigned type to 32 bit float does the job of showing the actual value.

 

So, my question is, how do i obtain the real values out of the VI ? I apologize if this is a simple question but i am new to this and do not have the time to study more about it. Also, i apologize in advance if insufficient information is given. Attached is the modified VI from "MB Serial Master Query Read Input Registers (poly).vi" which i used to write data to file, as well as 1 of the text files i obtained.

 

Thank you for your help and sorry for any trouble.

0 Kudos
Message 1 of 19
(11,724 Views)
Using the vi above, how do i read 32-bit registers?
0 Kudos
Message 2 of 19
(11,678 Views)

It is not very clear looking at your VI because I don't have the subVI.

 

 Can you show a real data example of what you get and what you think you should get.

 

(Maybe you need to typecast the U16 array to an SGL array but it is not entirely clear from your question.)

Message Edited by altenbach on 05-31-2010 09:34 PM
0 Kudos
Message 3 of 19
(11,667 Views)

Hi JR,

 May be you need to mutliply with some factor like the ((max value -min value)/2^16 ) which is the value of 1bit.

 

 

 

Thanks and regards,

srikrishnaNF

Regards,
Srikrishna


0 Kudos
Message 4 of 19
(11,660 Views)

I think srikrishnaNF may be right.  Its been a long time since I've been in the Modbus world, so correct me if I'm wrong.  Modbus cannot handle floating point numbers, so they are converted to integers which represent a certain quantum level.  Is your floating point data between 4 and 20 mA?  The U16 represents a value from 4 to 20 mA.  So use srikrishnaNF's formula to get the value of one bit, then multiply by the U16, then add that value to the min value (4mA).  This should give the floating point you are looking for.  I think. Smiley Indifferent

 

- tbob

Inventor of the WORM Global
0 Kudos
Message 5 of 19
(11,617 Views)

Modbus can handle 32 bit floating point numbers.  It is usually a matter of taking 2 consecutive 16 bit registers, joining the words, then typecasting to a single precision floating point number.

 

Attached is a subVI that takes an array of registers to do that.

0 Kudos
Message 6 of 19
(11,600 Views)

Ravens Fan, thanx for correcting me.  It has been a while since I've worked with Modbus.  However, the OP was asking for converting one 16-bit register data to a float.  The float must be represented as an integer to be held in a register.  If using 4 to 20mA, a U16 of 0 represents 4mA and a U16 of 65535 represents 20mA.  Again this is speculation.  The original OP must answer here.

 

- tbob

Inventor of the WORM Global
0 Kudos
Message 7 of 19
(11,596 Views)

Hi all, thanks for your replies. Basically what i needed was to read adjacent 16 bit registers from labview and convert them to a 32 bit single precision to get the "real" values out. I've managed to acheive it by reading some of your replies and working out this vi.

 

The register addresses for my sensor range from 200 to 384. I am not sure why, but i can only read a maximum of 125 registers at a time. Is there a reason for this?

 

Also, i would like to ask if there is a way to read specific registers instead of reading from the starting address to the quantity specified. If i write the data to file, i would be writing 62 values per second when i only need 12 of the values.

 

Thank you for your time and understanding.

 

I cannot see the vi posted by ravens fan as the version of my labview is older.

Message 8 of 19
(11,577 Views)
Solution
Accepted by topic author J.R

Here is my VI saved as LV8.6.

 

 

You've got some pretty wiring going on in your VI, but it is ridiculously unwieldy, not easily scalable, and uses some Rube Goldberg constructs.

 

Your Rubes:

1.  Converty from Array to cluster to unbundle.  Then bundling to go to a cluster then back to an array.  No need to go through the cluster song and dance.  You could have used Index Array and Build Array and not had to convert anything to a cluster or back,

2.  Using a Dbl constant, than changing that to a Single by way of the Numeric conversion function in order to establish the data type for the type cast.  Eliminate the conversion, and just set the representation of the constant to single precision instead of double precision.

3.  Duplicating code dozens of times when it should have been handled in a loop.

 

If you use mine as a subVI, your screen real estate will be less than a 1/4 of what it is now.

 

Are you saying you need to read a bunch of registers that aren't adjacent to each other?  You can do multiple read requests.  Write a request command, then read the response.  Then write another request command for different registers and read that response.  It depends on how many different reads you need to do, or how far apart registers of interest are as to whether it makes sense.  If you need to read a two pairs of registers that are some distance apart, it might be quicker to do a single read of multiple registers if they are close together and just throw away the registers you don't care about.  It will be more bytes to read back, but it might be quicker since it can be done in only a single read.  Or you could do two reads targeting your specific registers.  It might be less bytes to read in each message, but it will take longer to do two read requests and wait for the responses in between.

 

I don't know if the limit of 125 registers is something do to your device, the modbus library, or modbus protocol in general.  I want to say it might be the modbus protocol in general as 125 registers means 250 bytes of data.  Factor in a few bytes for the response command and checksum, you'll be at 256 bytes.  Modbus packets are designed to take less than 256 bytes so that only a single byte is needed to tell how many data bytes are going to be coming up in the message response.

 

With selective targeting of your registers to read, and using Index Array to read out the specific float32 values of interest, than you can write the desired 12 values to the file instead of all the ones you don't need.

Message 9 of 19
(11,564 Views)

Thank you for your reply. I'm sorry i really do not have much knowledge about this. Its my 3rd day using LabVIEW so i was quite happy just to be able to read the real values. It was more of a trial and error and brute force when i did the vi.

 

If i use your attached vi, how do i implement it in my vi?

 

What i meant in my previous post was that, for example i only require the values from register 202-205, 260-267 and 274-275, but using my vi i would need to read from register 202-275 with alot of unwanted values inbetween.

 

I will continue improving on my vi in the mean time with the advice you've given. Thanks alot!

0 Kudos
Message 10 of 19
(11,556 Views)