1. How do I convert floating point values (say 2.05 bar) to an integer that my PLC can use? The PLC does not have floating point maths functions.
2. I have a requirement to interface my PLC to some other PLC/DCS that only wants to use floating point values via MODBUS. They dont want to convert them in their PLC/DCS!
I know there is an IEEE standard for representing 32 bit floating point values. Can this conversion be done in a PLC?
Since all but a very few of the low-end PLCs have floating point capabilities my recommendation is to upgrade your PLC. However, one technique I've employed using only integer math is to work in units of tenths, hundreds, thousandths, etc. For example:
One half, 0.5, or 1/2 becomes . . .
In tenths: 5 or 10/2 (each unit represents 0.1, 5 * 0.1 or five tenths)
In hundredths: 50 or 100/2 (each unit represents 0.01)
In thousandths: 500 or 1000 /2 (each unit represents 0.001)
You can convert your arguments to tenths or hundreds, carry out your math, and then convert your result back into the units with which you began.
I have represented floating point values like 2.05 as 205 in PLCs that don't support floating point. Most operator interface/HMI/DCS software will allow you to apply scaling to convert the value back to a floating point value (i.e., raw
values 0-999 = 0-9.99).
The second question you asked is a little trickier. In theory, you could write a routine to convert the integer value to a IEEE representation of a floating point value in contiguous PLC registers. However that would not be trivial and I'm not sure you would be able to get the converted value out anyway. The software you use to read the registers would have to know how to interpret the four contiguous registers as a floating point value.
I guess I would need to know a little more about what you're trying to accomplish, what make of PLC you're using, and why the DCS system couldn't
and/or can't read integer values before I could make a better recommendation.
The IEEE format 32-bit floating point number repesentation has:
1 sign bit (1 = negative)
8 bits representing the exponent + 127
23 bits (+an assumed "1." that does not appear in the stored value) for the mantissa. So
1011 0111 1010 1011 0011 0111 1110 0010
has a negative sign
Exponent representation is 011 0111 1 = 111 decimal. So the exponent is 111 - 127 = -16.
The mantissa is (1.)010 1011 0111 1110 0010 and the value is
1.010 1011 0111 1110 0010 x 2^(-16)
You can decode the format by shifting - details will depend on the particular PLC available.
1 shift left moves the sign bit out and in most PLCs this can be tested.
8 shifts left will move the exponent out. Subtract 127 from this to get the actual exponent.
Rotate the remaining bits right by 1 bit (I'm assuming this is done in a Modicion-like system where multiple words can be rotated in one instruction) and set the MSB to 1. This value is equal to the value of the mantissa x 2^-1, so subtract 1 from the exponent value
Now rotate the result as required by the exponent - left if positive, right if negative, by a number of bits equal to the exponent, and voila!.
> 1. How do I convert floating point values (say 2.05 bar) to an integer
> that my PLC can use? The PLC does not have floating point maths
What are the values coming from? The easiest way would be to apply scaling until it's an integer (eg, make it 205 centibars or 2050 millibars) and
give it to the PLC directly like that. Otherwise, see below.
> 2. I have a requirement to interface my PLC to some other PLC/DCS that
> only wants to use floating point values via MODBUS. They dont want to
> convert them in their PLC/DCS!
> I know there is an IEEE standard for representing 32 bit floating point
> values. Can this conversion be done in a PLC?
Yes, it can, but it'll be a bit painful.
I'll assume below that you're converting it to and from a scaled integer, with a power-of-two scaling (increments of 1/128 or 1/4096 or something).
- break the floating-point number bit-wise into three parts:
- 1 bit - s (msb end of number)
- 8 bits - e
- 23 bits - m (lsb end of number)
- s is the sign (+ or -)
- if e is 0 or 255, it's a special case.
- e==0 means that it's zero or a very small number
- e==255 means it's Infinite or Not a Number (check the standard)
- put a 1 on the front of the m, giving a 24-bit number I'll call "1.m"
- take 1.m and shift it left or right according to e; this depends on the scaling of the integer that you want. Each unit of e corresponds to one shift left or right --- e==127 means the original was between 1.0 and 2.0, 128 means it was 2.0-4.0, 129 means 4.0-8.0; 126 means 0.5-1.0; etc.
If you don't have shifts, you'll have to use doubling and halving.
The other way is the same, only backwards:
- if the integer is zero, the float is all zeroes.
- take the sign and put it into s; the rest of the calculation uses the absolute (positive) value. That's one bit.
- shift the number left or right until the highest-order 1 is in the 24th bit position, keeping track of the number of shifts. Throw away the 1 and put the following 23 bits into m.
- set e according to the desired scaling and the number of shifts you did (above). Again, e==127 means the number is 1.0-2.0 etc. 8 bits.
- put all the parts together bit-wise, <s,e,m>
Hope that makes sense...
Yes, you could seperate FP number into the mantissa and exponent and hack together some integer arithmetic to fix this. There were a
bunch of hits on google with "IEEE Floating Point Representation".
I think those who have the other PLC/DSC may not be looking after the best interest of the customer/owner in making you kludge this up in your PLC.
This is more of a contract problem than a technical one. It is a common and standard practice to leave process variable representations
within a PLC, especially older ones, in fixed point ( integer ) format. There is nothing unusual about your situation and I don't why, off
hand, the other party is making a fuss about it.
If you provided your PLC according to the specification or it was pre-existing, they should either accomodate you or pay you for the extra work that you have to do to accomodate them.
If you bought a new PLC that does not conform to the specification, you should provide a different one that does.
Anyway, only as a last resort, should you make a mess in your PLC by turning into something it was not designed to be.