I'm using AcuCD 240 with PLC measuring voltage, current and power with codesys. Communication via modbus. I have difficulties with data type conversion. I can't get right values after conversion. Conversion is hex to float. Internet calculation programs give right values, but code give following:
Internet:
hex value is 43cba825 and result is : 407,313629. this is correct.
on code same conversion
2 word to 1 dword -> dword to string -> float to real
result is 1137420325, this is wrong value.
Can you give good tips to this?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
If you solved it in codesys please send it here or at oscat, they will put it in their standard library if you like to publish it.
If you like i can revise the program, did not have time to have a good look at your problem.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
This can easily be done be using fixed mapping to your variables. Most CoDeSys controllers have fixed memory address. If you map a REAL and a DWORD to the same memory location it will CAST it to a REAL. This method will work in all versions of CoDeSys. Below is an example how:
VAR
myReal AT %MD0 : REAL;
myDword AT %MD0 : DWORD;
myByteArary AT %MB0 : ARRAY[0..3] OF BYTE;
END_VAR
myDword:=16#43CBA825; (THIS WILL EQUAL myReal=407.313629)
To give you a better understanding how the memory map works refer to my other post for an excel sheet.
Not sure do you mean you are trying to convert IEEE754 to REAL? Yes I used my FB and I calculated the correct number from your example. You need to use an algorithm it's IEEE754. You can find it on the internet. Funny a forum for CoDeSys and they don't let you post export file . But I will give it to you here there are catches when the number is not accurate you can adjust to anything you want:
FUNCTIONMATH_IEEE754_TO_REAL : REAL(*
 ThisisaconversionofsingleprecisionIEEE754toreal. Theequationisasfollows:
 (-1)^s*2^(E-127)*(1.M)
 s=signbit     =bit31
 E=singedexponent =bits-30to23
 M=Fraction     =bits0-22
 Therearesomerestrictions
Â
 E=255andM<>0NaN
 E=255andM=0(-1)Soo(Infinity)
 E=0andM<>0(-1)S2-126(0.M)
 E=0andM=0(-1)S0*)VAR_INPUT
  i_lInput :DINT;END_VARVAR
 ssign  :INT;
 exponent :INT;
 rexponent :REAL;
 rfraction :REAL;
 radder  :REAL;
 dwTemp: DWORD;END_VARdwTemp :=DINT_TO_DWORD(SHR(i_lInput,31));          (* S *)IF(dwTemp=0)THEN
  ssign :=1;ELSE
  ssign :=-1;END_IFradder  :=1;                       (* Standard adder for 1.M *)dwTemp  :=DINT_TO_DWORD(i_lInput)AND16#007FFFFF;rfraction :=DWORD_TO_REAL(dwTemp)/8388608;         (* E *)dwTemp  :=DINT_TO_DWORD(SHR(i_lInput,23))AND16#000000FF;exponent :=DWORD_TO_INT(dwTemp);               (* M *)IF(exponent=255)AND(rfraction<>0)THEN (*NotaNumber*)
  MATH_IEEE754_TO_REAL :=0;ELSIF(exponent=255)AND(rfraction=0)THEN(*-1^soo(Infinity)*)
  MATH_IEEE754_TO_REAL :=0;ELSIF(exponent=0)AND(rfraction<>0)THEN
  radder  :=  0;
  exponent :=-126;ELSIF(exponent=0)AND(rfraction=0)THEN
  MATH_IEEE754_TO_REAL :=0;ELSE
  rexponent :=EXPT(2,(exponent-127));
  MATH_IEEE754_TO_REAL :=INT_TO_REAL(ssign)*rexponent*(radder+rfraction);END_IF
Do you want to know another crazy thing? I had the variable "xesponent" (Turn the xes around since the editor will not display it) and the forum editor changed the variable name to "-". The reason is it scanned it and must have found "xes" and cut the word. I removed the s and everything worked. What type of forum is this? I thought Germans were very liberal ?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
It worked on my platforms. Maybe the reason it does not work on your platform is a little endian and big endian problem. Since I am simulating on CoDeSys runtime my the computer it is little endian. Can you verify the byte order is the same on your platform? If they are different there is no need for special function block you just need to arrange the bytes then cast it to the right variable type. It is bad that CoDeSys does not have the ability to cast like in C/C++. The function DINT_TO_FLOAT only take the current number in the DINT then converts to the equivalent REAL number. For example if you have 1137420325 it it will convert it to 1137420325.0 or 1.13742E+09.
P.S. We did previous business together. I used to work for Schneider Electric.
jzhvymetal
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I'm using AcuCD 240 with PLC measuring voltage, current and power with codesys. Communication via modbus. I have difficulties with data type conversion. I can't get right values after conversion. Conversion is hex to float. Internet calculation programs give right values, but code give following:
Internet:
hex value is 43cba825 and result is : 407,313629. this is correct.
on code same conversion
2 word to 1 dword -> dword to string -> float to real
result is 1137420325, this is wrong value.
Can you give good tips to this?
go to w www.oscat.de w
get the basic library and try some functions.
i do know how to do it, but cant remeber it anymore.
Hi,
Thank you for your reply. Oscat didn't offer this kind of function. We solved the problem and write custom function to this.
We did it this way:
http://www.tfinley.net/notes/cps104/floating.html m
i do know the notes of finley
If you solved it in codesys please send it here or at oscat, they will put it in their standard library if you like to publish it.
If you like i can revise the program, did not have time to have a good look at your problem.
This can easily be done be using fixed mapping to your variables. Most CoDeSys controllers have fixed memory address. If you map a REAL and a DWORD to the same memory location it will CAST it to a REAL. This method will work in all versions of CoDeSys. Below is an example how:
VAR
myReal AT %MD0 : REAL;
myDword AT %MD0 : DWORD;
myByteArary AT %MB0 : ARRAY[0..3] OF BYTE;
END_VAR
myDword:=16#43CBA825; (THIS WILL EQUAL myReal=407.313629)
To give you a better understanding how the memory map works refer to my other post for an excel sheet.
l viewtopic.php?f=2&t=5045#p8228 l
Not sure do you mean you are trying to convert IEEE754 to REAL? Yes I used my FB and I calculated the correct number from your example. You need to use an algorithm it's IEEE754. You can find it on the internet. Funny a forum for CoDeSys and they don't let you post export file . But I will give it to you here there are catches when the number is not accurate you can adjust to anything you want:
Do you want to know another crazy thing? I had the variable "xesponent" (Turn the xes around since the editor will not display it) and the forum editor changed the variable name to "-". The reason is it scanned it and must have found "xes" and cut the word. I removed the s and everything worked. What type of forum is this? I thought Germans were very liberal ?
jzhvymetal love that icon. I too work with SoMachine. But not sure your example works see image? What Tim_P is referring to is something different.
Steve,
It worked on my platforms. Maybe the reason it does not work on your platform is a little endian and big endian problem. Since I am simulating on CoDeSys runtime my the computer it is little endian. Can you verify the byte order is the same on your platform? If they are different there is no need for special function block you just need to arrange the bytes then cast it to the right variable type. It is bad that CoDeSys does not have the ability to cast like in C/C++. The function DINT_TO_FLOAT only take the current number in the DINT then converts to the equivalent REAL number. For example if you have 1137420325 it it will convert it to 1137420325.0 or 1.13742E+09.
P.S. We did previous business together. I used to work for Schneider Electric.
jzhvymetal