Schneider Real Variables

Andrisxd

Member
Join Date
Jul 2021
Location
Denmark
Posts
4
Hi all,

I am programming my PLC (TM251MESE), and my code is supposed to stream sensor REAL values to Modbus Device. However, I have to limit my decimal points to one. To do so I have made a function block, where I multiply the real value by 10, then use the "trunc" function to get rid of decimals, and finally multiply by 0.1 to have the desired value.

Most of the time this works fine, but sometimes I get a value with many decimals following the configured value. Any ideas how to overcome this problem? Thanks

1.PNG 2.PNG
 
Thats how floating point works, there isn't a representation of ALL the numbers.

What device is that that wont support the decimal part with non zero values?
 
Agree with above, floating point numbers are only perfect when they're base-2 fractions. "0.5" for example is the easiest to represent, as it's the fraction 1/2.



Have you considered using an INT scaled by a factor of 10? This would be much easier to work with over Modbus.


If the end device is an HMI, there should be a way to limit the decimal points on that end, and then you shouldn't have to do anything in the PLC. If the end device is another PLC, you should probably reconsider your logic because floating points will always have some wiggle room. If you're comparing the value to a setpoint for example, you'll want to give yourself a small deadband anyway.
 
What is the real problem here? What happens if the modbus device receives a value that cannot be represented in the form xxxxx.y
 
@tdoa is correct.


Query


Is it possible any of these values (the 10, the 0.1 or the value of interest itself) are double precision 64-bit values internally?


None of the following are clean and some might not work.



Suggestion 1


Instead of multiply, TRUNC, and divide, try converting the original value to a string and using ROUND(stringvalue,1) see here. It will be messy finding the correct value for OP3, but it should be doable e.g. by using LOG(ABS(...)) (base 10 logarithm and absolute value).



Suggestion 2


You could try dividing by 10.0 instead of multiplying by 0.1; it probably not would not work in all cases but it might reduce the frequency of the extra decimal places.


Suggestion 3


It would be a bit of a Rube Goldberg/Heath Robinson, but, assuming all the numbers are 99999 or less, you could

  • Add 8e5 to the number e.g. so 3.10000014 becomes 800003.1...
    • Or subtract 8e5 the the original number is negative
  • Write the result to a string
  • If the number is negative, then strip the first character ('-') from the string
  • Strip the first character (character '8' i.e. ASCII code 56 decimal = 0x38 hexadecimal) from the string
  • Continue stripping the first character from the string as long as it is '0'
 
Last edited:
Agree with above, floating point numbers are only perfect when they're base-2 fractions. "0.5" for example is the easiest to represent, as it's the fraction 1/2.



Have you considered using an INT scaled by a factor of 10? This would be much easier to work with over Modbus.


If the end device is an HMI, there should be a way to limit the decimal points on that end, and then you shouldn't have to do anything in the PLC. If the end device is another PLC, you should probably reconsider your logic because floating points will always have some wiggle room. If you're comparing the value to a setpoint for example, you'll want to give yourself a small deadband anyway.

I am not sure, what is in the other end, it is just the customers requirements to have real values on Modbus. And the most frustrating part is that most of the time this works just fine. I will see what I can accomplish with Modolo division first.
 
So where did the requirement for rounding to 1 decimal place come from? If the customer requires it, they should probably handle the formatting on their end.
 
transmitting a "real" number over Modbus always requires some coordination between the sender and receiver.

In your software, defining a tag as REAL most likely means that is stored as a 32 bit value following IEEE-754 format. See here for more information:
https://babbage.cs.qc.cuny.edu/IEEE-754.old/32bit.html

You have to know if the receiver is expecting this or something else.
As mentioned, because they have specified one decimal place, it may be that what they are calling "real" is actually a scaled integer as described above.

After getting the format settled on, you will have to deal with things such as are addresses 0 or 1 based, are values stored in Big Endian or Little Endian format.

Just to tell you to have a "REAL" value on Modbus is not enough.
 
@tdoa is correct.


Query


Is it possible any of these values (the 10, the 0.1 or the value of interest itself) are double precision 64-bit values internally?


None of the following are clean and some might not work.



Suggestion 1


Instead of multiply, TRUNC, and divide, try converting the original value to a string and using ROUND(stringvalue,1) see here. It will be messy finding the correct value for OP3, but it should be doable e.g. by using LOG(ABS(...)) (base 10 logarithm and absolute value).



Suggestion 2


You could try dividing by 10.0 instead of multiplying by 0.1; it probably not would not work in all cases but it might reduce the frequency of the extra decimal places.


Suggestion 3


It would be a bit of a Rube Goldberg/Heath Robinson, but, assuming all the numbers are 99999 or less, you could

  • Add 8e5 to the number e.g. so 3.10000014 becomes 800003.1...
    • Or subtract 8e5 the the original number is negative
  • Write the result to a string
  • If the number is negative, then strip the first character ('-') from the string
  • Strip the first character (character '8' i.e. ASCII code 56 decimal = 0x38 hexadecimal) from the string
  • Continue stripping the first character from the string as long as it is '0'

Thank you for your answer! Actually dividing by 10 did the job. I have had my program running for 2 days, and I have not experienced any issues.
 
transmitting a "real" number over Modbus always requires some coordination between the sender and receiver.

In your software, defining a tag as REAL most likely means that is stored as a 32 bit value following IEEE-754 format. See here for more information:
https://babbage.cs.qc.cuny.edu/IEEE-754.old/32bit.html

You have to know if the receiver is expecting this or something else.
As mentioned, because they have specified one decimal place, it may be that what they are calling "real" is actually a scaled integer as described above.

After getting the format settled on, you will have to deal with things such as are addresses 0 or 1 based, are values stored in Big Endian or Little Endian format.

Just to tell you to have a "REAL" value on Modbus is not enough.

Thank you for your inputs and information provided. I will take this things into account. And yes, I have 32bit float, little-endian bit swap on the other end.
 
Thank you for your inputs and information provided. I will take this things into account. And yes, I have 32bit float, little-endian bit swap on the other end.


Multiple real first with 10, then convert real to dint and back from dint to real. Lastly divide by 10. Now real number should only show one (1) decimal allways as it is converted from dint where extra decimals are cutted off.
 
It is not possible to represent 10.1 in floating point, so no amount of processing is going to fix it...
What binary number are you sending for a value of 10.1?

tenp1.jpg
 

Similar Topics

I have a system installed in my company which have M340 PLC and it has a program which is used toh turn lights on and off. I am attaching program...
Replies
5
Views
3,399
Hi, Is Control Expert V15.0 supposed to support multiple monitors? I'm running Control Expert V15.0 on my host Windows 11 PC, connected to two...
Replies
1
Views
59
Everything was working fine, but suddenly CPU went into error mode, and the ERR and TER LEDs lit up. Now I can't download or connect with the PLC...
Replies
0
Views
62
Hello all, I am wanting to update the system clock via NTP in the M580/M340. I'm aware that we are able to connect to a NTP in the controller...
Replies
4
Views
157
I am using Schneider elau pack drive servo motor ISH-100. I am facing the problem that On the ISH -100 red light is blinking and pack drive C-600...
Replies
0
Views
83
Back
Top Bottom