Search code examples
floating-pointdecimalieee-754plccodesys

PLC Structured text, convert decimal to real(float). Not getting the value I expect. (IEEE-754)


I have a hardware that is communicating with the PLC over Profibus DP, that sends me 4 bytes of data in hex that is "44 79 FF FF" and in the PLC program I have declared a BYTE array for this input data. The problem is in the PLC the data I receive in my BYTE array is "66 121 255 255" which is the decimal value of the hexdecimal, but my goal is to convert that value to a REAL and when I do that I'm not getting the value I expected.

I have created a DWORD(4bytesData) that i insert all the BYTES into. So before I insert the 4 bytes into 4bytesData the bytes are: in1 = 68 , in2 = 121, in3 = 255 & in4 = 255

4bytesData := (SHL(SHL(SHL(BYTE_TO_DWORD(in1), 8) OR BYTE_TO_DWORD(in2), 8) OR     BYTE_TO_DWORD(in3), 8) OR in4);

realValue := DWORD_TO_REAL(4bytesData);

Where in1, in2, in3 & in4 is byte 0-3.

The value I'm getting is; 4bytesData = 1148846079 & realValue = 1.148846e+009

The value I'm expecting to get from realValue is = 9.9999993896484375E2

If i use this website ( IEEE754 Analyzer/Converter ) and converting the hex value (4479FFFF) I'm getting the value I want to, and if i insert the decimal value (1148846079) I'm getting the same value I receive in the PLC.

I hope you understand my problem, Many thanks in Advance.


Solution

  • You've already figured it out, it seems that you just don't realize it. The conversion DWORD_TO_REAL is taking the integer (hex) value stored in 4bytesData and converting it to IEEE754 REAL format.

    This is not what you want to do. 4479FFFF is already in IEEE754 REAL format - you're taking that value, interpreting the REAL as a DWORD, and then converting the DWORD value to a REAL. The short answer is that you don't need the conversion - 4bytesData is already in the correct format.

    edit

    follow up on comments :

    enter image description here

    here FunctionBlock2 delclares rIn(REAL), rOut(REAL) and sets rOut:=rIn;. This gets around the forced typecasting of ST. Nothing is changing about the data stored in D2000 here - it's the same binary data. The top function block is storing it into memory and the bottom one is reading it from memory. The only difference is that the top rung is interpreting it as a DWORD (for display purposes) and the bottom rung is interpreting it as REAL.

    edit

    I've been reading the Beckhoff manual. It seems you may have other options. Try perhaps declaring a DWORD and REAL at the same memory location. If not, perhaps pointers would let you do it (not sure if type restrictions also apply to pointers with Beckhoff?)