Hello everyone,
I finally found my problem, about the floating point data string conversion...
My PLC provider (WAGO) tell me this: Our PLC is only a 32 bit PLC. The HMI may give the same result unless its got a new processor that has 64 bit capabilities. We are releasing a new version of PLC later this year. I will be interested to see if it will have the LREAL variable for 64 bit real vars.
That's why the String To Real give me crap data!
So I created a personalised funtion block to make the decimal floating point conversion possible.
Fist I took all the data seperately and concatenate it into one Integer string value.
Then I converted the Integer value into a Word value.
Yes I still don't have my floating point value that's why I created a devisor value to divide the integer value by the divisor when I'll read the data into my HMI (Human Machine Interface).
The devisor value is automatically refresh with the quanties of number after the dot.
See what my funtion block programmation look like!:***************************************************
FUNCTION_BLOCK GPS_DECIMAL_STRING_TO_INTERGER_WORD
VAR_INPUT
sSTRING_IN:STRING;
END_VAR
VAR_OUTPUT
wINTEGER_WORD:WORD;
wDIVISOR:WORD;
END_VAR
VAR
DOT_POS: WORD;
STR_LEN:WORD;
BEFORE_DOT:STRING;
AFTER_DOT:STRING;
INTEGER_STRING:STRING;
INTEGER_WORD:WORD;
VARIABLE:WORD;
END_VAR
***************************************************
STR_LEN:= LEN(sSTRING_IN);
(* Store the lenght of the string into STR_LEN variable*)
DOT_POS:= FIND(sSTRING_IN, '.');
(* Search the position of the ' x ' x character from left to right and send the numeric position into DOT_POS variable *)
BEFORE_DOT:=LEFT(sSTRING_IN, (DOT_POS-1));
(* Store all the digits before the dot, into the BEFORE_DOT variable*)
AFTER_DOT:=RIGHT(sSTRING_IN, (STR_LEN - DOT_POS));
(* Store all the digits after the dot, into the AFTER_DOT variable*)
INTEGER_STRING := CONCAT (BEFORE_DOT, AFTER_DOT);
(* Take the before and after dot value and put them together into one integer string*)
wINTEGER_WORD:= STRING_TO_WORD(INTEGER_STRING);
(* Convert the integer string into WORD *)
VARIABLE:=(STR_LEN - DOT_POS); (*The VARIABLE store the number of zero necessary to create the wDIVISOR output.*)
IF VARIABLE=1 (* The divisor output is use by the HMI user to take the interger data from the register and do a *)
THEN wDIVISOR:=(10); (* mathematical operation to recover the original decimal data. *)
ELSIF VARIABLE=2 (* Here in this case if the VARIABLE = 2 it means the integer number gets 2 number after the dot*)
THEN wDIVISOR:=(100); (* then the user will do the math with the 100 divisor to recover 2 number after the dot. *)
ELSIF VARIABLE=3 (* If the floating point number isn't always the same, the output divisor adjuste automatically*)
THEN wDIVISOR:=(1000); (* until 6 number after the dot. *)
ELSIF VARIABLE=4
THEN wDIVISOR:=(10000);
ELSIF VARIABLE=5
THEN wDIVISOR:=(10000);
ELSIF VARIABLE=6
THEN wDIVISOR:=(10000);
END_IF
***************************************************
Summary example:
sSTRING_IN:STRING = 589.251
DOT_POS: WORD; = 4
STR_LEN:WORD; = 7
BEFORE_DOT:STRING; = 589
AFTER_DOT:STRING; = 251
INTEGER_STRING:STRING; = 589251
INTEGER_WORD:WORD; = 589251
VARIABLE:WORD; = 3
wINTEGER_WORD:WORD; = 589251
wDIVISOR:WORD; = 1000
HMI script: [ wINTEGER_WORD / wDIVISOR ] = [ 589251 / 1000 ] = 589.251
I send those data to my HMI with modbus so i've put each data into a modbus register like this:
wINTEGER_WORD:=GLL_LAT_DEG;
GLL_LAT_DEG AT %MW0:WORD;
(* This uses %MW0 because it is a WORD value (16bits), MODBUS Holding Reg 12289 or 412289 *)
///////////////////////////
So that's it for the convertion hope it help!
I also found the utilities of string manipulation with function LEN, LEFT, RIGHT, MID, CONCAT, INSERT
see Codesys Help for more info on this function.
Thanks everybody to tried help me!