Is it possible to convert numeric data string into floating point data?Is it possible to convert ASCII data string into binary, decimal or hexadecimal?
What I tried but doesn't work:
1-
Put my value data string variable at the input of STRING_TO_REAL function block converter.
And then, I get an output variable that I applied to the modbus holding register AT %MW0 : REAL;
But even the output variable of the funtion block don’t give the same output data as the string number?
The converter is not appropriate.
See the results for some of my test:
STRING TO REAL = Crap data (4649.0304 =to real= 3.459821e-05)
STRING TO LREAL = Unconfigurable function block
STRING TO WORD = Data without the decimal value (4649.0304 =to word= 4649)
STRING TO INT = Data without the decimal value (4649.0304 =to int= 4649)
For ASCII character = 0 or a none significant number data like 5, 8 …
2-
I put my value data string variable directly at the modbus holding register AT %MW0 : REAL;
But the build program didn’t take it. It ask for variable declaration or wrong syntax errors.
3-
Also tried the STRING_TO_ASCIIBYTE function block. The output data isn’t recognizable.
Tell me at least if it is possible to make any type of data string conversion...
Thank you very much!
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Anonymous
-
2010-07-13
Originally created by: Bernhard Werner
Hello aljack,
I don't understand your problem:
realvar := STRING_TO_REAL('4649.0304');
this works fine on my targets. Only the number of digits is a little bit higher than
REAL-resolution. So the result is 4649.03.
What plc do you use?
What exactly is your test code?
Bernhard
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hello.
J think you can't write this : ;
%MW0 is a word format (16 bits), and it can be declare AS INT, Word, but not as a REAL.
To store a REAL you must use a double word (32 bits), %MDxx.
To convert ASCII, you must have a look to OSCAT library (http://www.oscat.de/). Oscat lbrairies are a real gold mine !
JAPIB
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Now for all the others. this was a verry sepcial service to my french friend Joel. But ist is also the request for all those who are able to translate the Oscat-Library-documentation to your own language please do it and send it to OSCAT. The world really needs this library.
Regards Ralph
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Bernhard Werner hat geschrieben:
Hello aljack,
I don't understand your problem:
realvar := STRING_TO_REAL('4649.0304');
this works fine on my targets. Only the number of digits is a little bit higher than
REAL-resolution. So the result is 4649.03.
What plc do you use?
What exactly is your test code?
Bernhard
Hello Bernhard,
My PLC: WAGO 750-843
My test code is in function block: See my attached program
So I use specials functions blocks from Wago online library to read the data from my external device (GPS over NMEA183 protocol).
I'm able to receive, read and see the data from this device and I apply it to the input of a STRING_TO_REAL converter.
The data is a string 200% sure.
Everything goes right until the output convertion of the STRING_TO_REAL don't show what it supposed to.
The data from the device meaning: 46 Degree 49 Minutes 0304 Secondes
The data string form look like this: 4649.0304
The input of converter look like: 4649.0304
The output of the converter: weird blinking and changing none stable data range like this 3.459821e-05 to 529846
Strangely I apply the same input string to a STRING_TO_WORD converter for test purpose and the ouput data convert correctly all the integer value (4649.0304 --> 4649).
Could you tell me if it is possible to seperate data from the string sample (4649.0304).
Then I could make lots of separate conversion in a WORD var!
Else I must find the trouble into the REAL conversion.
Nitrozin hat geschrieben:
hi,
for Modbus communication you have to declare variables
VAR_GLOBAL
RealVar1 AT %MW0 : REAL;
RealVar2 AT %MW2 : REAL;
END_VAR
Nitro
Hello Nitrozin,
Yess you are totally right!
I have already done this kind of link for my Modbus variable.
But even if this configuration is ok, the output of the converter don't seems to do his job.
Thank you!
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
JAPIB hat geschrieben:
Hello.
J think you can't write this : ;
%MW0 is a word format (16 bits), and it can be declare AS INT, Word, but not as a REAL.
To store a REAL you must use a double word (32 bits), %MDxx.
To convert ASCII, you must have a look to OSCAT library (http://www.oscat.de/). Oscat lbrairies are a real gold mine !
JAPIB
Hello JAPIB,
I'm agree with you for the memory location data lenght, but even if I change the %MW0 for a %MD0 it change anything. The STRING input data is still convert into a weird REAL output.
Example :
One of my input STRING data is very simple: 2.0
The STRING_TO_REAL convertion give an REAL output of: 52 and then 3276852 and then 1.052508e+009
The output oscillate between these three values?
Why I don't know?
About the ASCII convert I will take a look on OSCAT if I want to learn some German even if I'm a french Canadian. Actually I'm ok, I found yesterday a function block call STRING_TO_ASCIIBYTE, this block convert an ASCII character into decimal value.
Example: W => => => 87 in decimal (see ASCII table on the web)
You could find this function block in the library of CoDeSys. At Standard.lib/String_Function/STRING_TO_ASCIIBYTE
Thanks!
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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!:
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
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!
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
My CoDeSys Version: 2.3.9.19
Is it possible to convert numeric data string into floating point data?Is it possible to convert ASCII data string into binary, decimal or hexadecimal?
What I tried but doesn't work:
1-
Put my value data string variable at the input of STRING_TO_REAL function block converter.
And then, I get an output variable that I applied to the modbus holding register AT %MW0 : REAL;
But even the output variable of the funtion block don’t give the same output data as the string number?
The converter is not appropriate.
See the results for some of my test:
STRING TO REAL = Crap data (4649.0304 =to real= 3.459821e-05)
STRING TO LREAL = Unconfigurable function block
STRING TO WORD = Data without the decimal value (4649.0304 =to word= 4649)
STRING TO INT = Data without the decimal value (4649.0304 =to int= 4649)
For ASCII character = 0 or a none significant number data like 5, 8 …
2-
I put my value data string variable directly at the modbus holding register AT %MW0 : REAL;
But the build program didn’t take it. It ask for variable declaration or wrong syntax errors.
3-
Also tried the STRING_TO_ASCIIBYTE function block. The output data isn’t recognizable.
Tell me at least if it is possible to make any type of data string conversion...
Thank you very much!
Originally created by: Bernhard Werner
Hello aljack,
I don't understand your problem:
realvar := STRING_TO_REAL('4649.0304');
this works fine on my targets. Only the number of digits is a little bit higher than
REAL-resolution. So the result is 4649.03.
What plc do you use?
What exactly is your test code?
Bernhard
Hello.
J think you can't write this : ;
%MW0 is a word format (16 bits), and it can be declare AS INT, Word, but not as a REAL.
To store a REAL you must use a double word (32 bits), %MDxx.
To convert ASCII, you must have a look to OSCAT library (http://www.oscat.de/). Oscat lbrairies are a real gold mine !
JAPIB
hi,
for Modbus communication you have to declare global variables
VAR_GLOBAL
RealVar1 AT %MW0 : REAL;
RealVar2 AT %MW2 : REAL;
END_VAR
Nitro
Joel Salut,
c'est intéressant, vous utilisez OSCAT, vous êtes un fan de cette. Bien que la documentation est disponible uniquement en allemand. Je pense qu'il est temps que cette bibliothèque est utile de document dans d'autres langues. Si donc la confiance dans sa langue à se traduire mais s'il vous plaît vous inscrire à OSCAT. Le monde a besoin de cette bibliothèque.
Salut
Ralph
Now for all the others. this was a verry sepcial service to my french friend Joel. But ist is also the request for all those who are able to translate the Oscat-Library-documentation to your own language please do it and send it to OSCAT. The world really needs this library.
Regards Ralph
Hello Bernhard,
My PLC: WAGO 750-843
My test code is in function block: See my attached program
So I use specials functions blocks from Wago online library to read the data from my external device (GPS over NMEA183 protocol).
I'm able to receive, read and see the data from this device and I apply it to the input of a STRING_TO_REAL converter.
The data is a string 200% sure.
Everything goes right until the output convertion of the STRING_TO_REAL don't show what it supposed to.
The data from the device meaning: 46 Degree 49 Minutes 0304 Secondes
The data string form look like this: 4649.0304
The input of converter look like: 4649.0304
The output of the converter: weird blinking and changing none stable data range like this 3.459821e-05 to 529846
Strangely I apply the same input string to a STRING_TO_WORD converter for test purpose and the ouput data convert correctly all the integer value (4649.0304 --> 4649).
Could you tell me if it is possible to seperate data from the string sample (4649.0304).
Then I could make lots of separate conversion in a WORD var!
Else I must find the trouble into the REAL conversion.
thank you very much!
Network_Project_10 07 14 AJ 09h16.pro [57.64 KiB]
Hello Nitrozin,
Yess you are totally right!
I have already done this kind of link for my Modbus variable.
But even if this configuration is ok, the output of the converter don't seems to do his job.
Thank you!
Hello JAPIB,
I'm agree with you for the memory location data lenght, but even if I change the %MW0 for a %MD0 it change anything. The STRING input data is still convert into a weird REAL output.
Example :
One of my input STRING data is very simple: 2.0
The STRING_TO_REAL convertion give an REAL output of: 52 and then 3276852 and then 1.052508e+009
The output oscillate between these three values?
Why I don't know?
About the ASCII convert I will take a look on OSCAT if I want to learn some German even if I'm a french Canadian. Actually I'm ok, I found yesterday a function block call STRING_TO_ASCIIBYTE, this block convert an ASCII character into decimal value.
Example: W => => => 87 in decimal (see ASCII table on the web)
You could find this function block in the library of CoDeSys. At Standard.lib/String_Function/STRING_TO_ASCIIBYTE
Thanks!
Hello aljack,
i think your problem is a bug inside the firmware of the 843.
I hope this bug will be solved with the next firmware release.
Until the next firmware release please try to use the follow workaround
Try to replace the call of the functionblock NMEA_RECEIVE
to the last network inside your PLC_PRG and please
don't ask me why ...
but i think it works
Uwe
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;
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!
i would stay in string or in dword why all this real is needed?
cut it and put a dot in between. with real conversion you are losing the fine data.
we have written a code to convert the scientific real to normal real with constant number of digits
If you want the code you can send me email to the below id
e balajimct@gmail.com e
this post is two years old, however if you like to give it to the group i would like it.