Converting Float to 2 Integers for Modbus?

FNC

Member
Join Date
May 2010
Location
NJ
Posts
84
Hi,

I am using a Phoenix Contact PLC and trying to use it to write a Floating point over Modbus. To do this I need to convert it to two 16 bit integers. Phoenix Contact does NOT have a function for this.

Does anyone know the code?

If so I can create a function to use.
 
Phoenix Contact

LReal is 64 bit real which does not help.

Hard to believe that Phoenix Contact does not have functions for easily converting TO and FROM IEEE 754 format.
 
LReal is 64 bit real which does not help.

Hard to believe that Phoenix Contact does not have functions for easily converting TO and FROM IEEE 754 format.

You can convert LREAL to DINT. Then DINT to INT, then the same DINT but "bit shifted" (IEC61131 has a bit shift instruction) to the second INT.

Is it the same problem as in this thread?
http://www.plctalk.net/qanda/showthread.php?t=110784

In that case you have to multiply your LREAL by 10 if you want to keep 1 decimal point.
 
If you're using the real on both ends (receiving and transmitting) just send the real as two words. A real is just a double word, send the low word and high word of the real in sequential Modbus registers. Be careful of the word order. Direct addressing of the words or Hiword & loword functions would be what's needed to split the real
Cheers

Ken
 
kvogel is correct. This is less about "converting" and more about "cutting up". You need to maintain the bit pattern you have and re-assemble it on the other side. In your case, re-assembly probably happens automatically.

I'm not familiar with Phoenix Contact plcs so I don't know what their addressing/tag naming scheme is. But ultimately what you want to do is either look at the same address space in two different ways or be able to move a bit pattern directly from one address space to the other.

I will use an example from a Siemens S7 classic plc. In Step 7 the native data size is a byte. What you make of that byte is defined by how you address it and how you operate on it. So if I put my real value in DB10.DBD0 (double word access starting at data block DB10 byte address 0, I can then send this bit pattern across Modbus using DB10.DBW0 and DB10.DBW2. this is what i mean by looking at the same address space in two different ways.

AB Logix processors don't let you do this. However, those plcs have the COPy command, which takes the contents of one address area and moves them to another address area byte for byte with no conversion. This accomplishes a similar result. We are moving to bit pattern from a tag typecast as one data type into the address space of a tag typecast as another data type.

See if you can find examples in the Phoenix plc manual that would do something similar to either of these concepts.

Keith
 
As others already said you should transmit the high and low 16bit words as two contiguous registers.

What happens is that Modbus, when transmiting a 32bit type, does not define in which order the words are transmitted, that is why some equipment transmits the high word first and others do the opposite.

But in the receiving side any decent Modbus driver has to have the option to reverse the order of words to solve this.
 
If its within the range and depending on decimal places, just times by 10 / 100 and send as an INT, divide by 10 / 100 on the other side.
 
Last edited:
Add a UNION

AsINTs: ARRAY[0..1] OF INT;
AsREAL: REAL;

Make a VAR of this type.

Map the Modbus WORDs to AsINTs[0] and AsINTs[1]
and read the REAL in AsREAL
 
This is a similar problem a recent problem we had with GE plc and with big and little endian problem a few posts back.

You guys don't understand the depth of hatred I have for these companies that can't keep their protocols documented and those that can't follow the protocols.

A Modicon PLC will only accept two words as float in a certain way but it is not in the specification. Why not! My hate is extended to Modicon.

Every other company feels they can do what they want. Our stance is that if you can't send two words that a Modicon PLC will accept as a valid float then the sender is at fault.

Because we are the small company is it seems it is always our fault. This is pure BS.

What we recommend is that those that don't comply with our standards, the real standards, should be ***** canned.

My hate is not limited.
 
Modbus

I contacted Phoenix Contact and they eventually found a function for converting 2 INTs to IEEE754 Floating point. this allows me to read 2 words (16 bits each) and then convert them to a Real.

They do NOT seem to have the reverse function for turning a Real to 2 words. This means as of right now I cannot change a floating point to words (or Integers) to write to Modbus floating point registers.

Does someone know the code for doing this? If so then I could possibly try to write a function block myself.
 
I assume paraffin power knows that a general Phoenix Contact plc is capable of defining unions as is shown in post 9. If not that was just teasing because that would be the cleanest way of doing it.

Exactly which Phoenix Contact model are you working with? I might be able to see an instruction combination that will do what you want.

Again, this isn't really a conversion. It is more of a move. If you start thinking of it that way you might see some instructions that will help you.

Keith
 
Brute force might be needed if there truly isn't a function to separate a 2 word variable into it's component words. A real is already 2 words. You will need to use the appropriate means for your PLC system to find the address for the real and point to the word at that address for one of the words and the second word will be offset by one word. For codesys ADR operator will find the address of a variable name and POINTER TO will return the value contained at that address.

Cheers
Ken
 
Modbus

Hi,

I am using an ILC-191 PLC. I need to convert a IEEE754 real to 2 integers.

The format would be different from turning a DINT (also 2 words) to 2 integers.

I need to write a Real via Modbus is the reason for all this.

Thanks!
 
Let's backup a bit,

You say you need to convert a IEEE754 real to 2 integers and need to write a Real via Modbus is the reason for all this.

A real is a number that is two words long (32 bits) and formatted to accommodate a decimal point. If you only need to transfer a number that is less than 65535 or 32767 you can do the math needed to rid yourself of the decimal point (multiply by 10,100,1000 ,ect) and convert to a UINT or INT and transfer through Modbus as one UINT or INT (16bits), you can divide on the other side to return the decimal place as needed. Of course this method limits the size of the number you can transfer depending on the digits needed.

If you need to use a larger real on the receiving end. You will have to look at how memory space is allocated. An INT, UINT and WORD are all just 16 bits of memory space. The INT, UINT, etc comes into play when that 16 bits of memory space is converted between data types or presented to the "real world" as a displayed value. Converting a real to an INT gets messy. Due the need to round to an integer value and the limitation of number size you will potentially lose some of the precision of the real. Your trying to fit 32 bits of data into 16 bits of space with the accompanying limitations of the INT or DINT data type. A real isn't two integers, it's two words or one simplified integer. Taking each of the words of the real and placing them AS-IS (no conversion) into Modbus to be transferred is the easiest way to go if you can't transfer as a real directly. Even if the Modbus register says it is transferring INTs it doesn't matter as it's really just moving 16 bits of memory space. An INT is a word too. In other words, Modbus is transferring words, what's contained in the word is not relevant at least as far as Modbus is concerned (somewhat simplified).

As has been mentioned before, a real is just address space of 2 consecutive words (32 bits) that is two 16 bit spaces put together and interpreted.

Hope this helps

Ken
 
Last edited:

Similar Topics

I need help converting from a floating register to two integer words. I'm using a SLC 5/05 and need to be able to write 32 bit data to a servo...
Replies
2
Views
4,706
How do I convert a float to an integer? I've got a floating-point number D606, value 3999.863. I need to convert it to an integer (4000), then I...
Replies
14
Views
4,129
Dear Experts, I need to send Boolean array from PLC (1769-L19ER) to device which recieve only float data. So, How can I convert Bool array to...
Replies
4
Views
2,234
I have a 3-axis sensor that I'm working on integrating with a Micrologic PLC. The sensor has a RS-422 output and I'm using an RTA Automation PLC...
Replies
5
Views
3,232
Can someone help...? In Logix5000, I am trying to convert float/real numbers to bcd. I used a TOD function to convert a binary to bcd. So if I...
Replies
3
Views
2,928
Back
Top Bottom