Sign in to follow this  
Followers 0
BJR

RTOS in CompactLogix

15 posts in this topic

I am converting a real that will always be x.xx (so 0.00 to 9.99 bascially). When I use the RTOS command to convert it to a string I am getting lots of extra decimal places. real 1.02 (REAL) put through the RTOS command destination is 1.01999998 (STRING) where is this coming from and what is the easiest way to make sure the string ends up with 1.02? Don't care what else I have to do even if it is another command. Just remember the destination is a STRING so the main problem is you can't really do any math on the string to round or truncate I don't think. I'm stumped for today

Share this post


Link to post
Share on other sites
The wonders of floating point math :) The easiest fix would be to set your string's length to 4 after doing the RTOS. This will truncate all but two decimal places (as long as your whole value is less than 10), which could be a problem because you aren't rounding.

Share this post


Link to post
Share on other sites
Don't know if this would work or not, but might be worth trying. Multiply (MUL) your float by 100 with a DINT as the destination, then divide (DIV) by 100 with float as destination. Then convert to string. I think the first operation will round it off to 102, then when you divide you will get 1.02, two extra steps, but easier than manipulating strings.

Share this post


Link to post
Share on other sites
I thought this would help but it did not. I thought it would give me some other ideas too, but it did not.

Share this post


Link to post
Share on other sites
it might be best to store the DINT, after you multiply by 100, in the string. Then use string commands to put the decimal point where it should be.

Share this post


Link to post
Share on other sites
Works great if it is greater than or equal to 1.00. I'll keep working with it. I did the MUL then DTOS and then used INSERT to put in the decimal point. Probably can do a quick test to do a separate INSERT if the value is less than 1.00. Pretty close!

Share this post


Link to post
Share on other sites
Well, it sure is ugly but here is one working solution. Thanks for the ideas. Edited by BJR

Share this post


Link to post
Share on other sites
Bad news. There are certain numbers that cannot be represented exactly in the IEEE754 floating point format that your PLC uses (and almost every other computer as well). 1.02 just so happens to be one of those numbers along with a bunch of other numbers between .01 and .99. So, you may ask why can 1.02 be displayed on my computer monitor when I set an application to display only two decimal places? Thats because there is a routine that makes the change in the characters that are displayed for you. However, in the computer memory, the value of the variable is still 1.0199999999999 because that is the closest it is going to ever get. In the downloads section of the forum is a program that I wrote that will truncate a float (removing the fraction). It also shows how to perform rounding to a whole number. http://forums.mrplc.com/index.php?autocom=downloads&showfile=761 I think this could be manipulated to provide rounding to two deimal places by first adding .005, multiplying by 100, then truncating. Be advised that dividing by 100 after you truncate will just get you back where you started because of the inability to store certain exact values. It will be necessary to manually adjust the decimal point location in the string. It shows how to perform rounding as well as truncation. It was written for a SLC500 but can be easily adapted to the ControlLogix. edit: D' oh! , I just rememberd that the ControlLogix has a truncate function. So try this: 1) Add .005 to the float to accomodate rounding. 1) Truncate the float - this is the whole number value. 2) Subtract the truncated value from the original to obtain the fraction. Multiply fraction by 100. 3) Tuncate the fractionx100. 4) Convert both values to string, then concat whole number string, "." and fraction string. Edited by Alaric

Share this post


Link to post
Share on other sites
Simple solution: Create a string data type that has a length of four characters. Create a tag of that type. Use that tag as the destination in the RTOS.

Share this post


Link to post
Share on other sites
Wouldn't that still cause 1.01999998 to be 1.01 instead of 1.02?

Share this post


Link to post
Share on other sites
No. tried, tested & proven on L61 ver 16

Share this post


Link to post
Share on other sites
Interesting. Easy enough

Share this post


Link to post
Share on other sites
WOW. I like this a LOT better than the mess I created. Very nice. It does round like I needed.

Share this post


Link to post
Share on other sites
Nice. Edited by Alaric

Share this post


Link to post
Share on other sites
What an elegant solution. Makes me wonder why I even try. One of the reasons I like the 5000 series is the ability to create your own datatypes. And here I miss a prime opportunity to do so. tsk, tsk :)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0