Siemens S7/TIA v18: Instruction to round at say 2 decimal places?...

Mas01

Member
Join Date
Oct 2020
Location
Leicester, England
Posts
1,109
In S7/TIA Portal, is there a function to round a real to a specified number of decimal places?

e.g. If I have 22.519432 and I want to round it to 2dp, I get 22.52.

Thanks

I'm asking because the operator says that the data that gets recorded into the CSV file is shown as 7 d.p. and they only want it to be 2 d.p. to match the HMI-displayed value (which is true, it's shown to 2dp on-screen).

I thought it might be the ROUND instruction, but I think that rounds to the nearest integer.

Is there an instruction? Or do I need to use VAL_STRING to do this?

Thanks
 
I don't have access to TIA Portal anymore (and it's admittedly been a while since I've used it), could you not multiply your REAL number by 100 into a DINT or INT then divide by 100 back into another REAL?



That's how I would do it in Allen Bradley.
 
You have some script or logging that writes to a CSV file ?
You might have another problem, because the REAL representation in TIA does not match the floating point representation in Windows.
That is why a value that is 22.52 in the PLC or the HMI may display as 22.51999994 or to that effect in Windows.
If this is the actual problem, then I don't know a fix. Even if you round 22.519432 to 22.52 you may still see 22.51999994 in Windows.
One fix could be to use integers with an implied decimal point.
 
I'd use VAL_STRG and then log the string instead of the REAL, or the "implied decimal" that JesperMP mentioned.


A REAL in the PLC doesn't have any way of limiting itself to a certain number of decimals, and the way the data is stored in the background there aren't actually all that many numbers that get stored exactly as a float.
 
There are many ways to skin a cat, I assume you are using something like Excel to display the CSV file, you could produce a template that they use rather than the default excel format, set the cells to 2dp so when imported it only displays the value to 2 dp.
Other way is to do is as per hardaysknight but you can get a more true round up/down as per standard like this code, note: this is for 3 dp just change the 1000 to 100.

3 Dec Places.png
 
Part of the problem may be that a 32-bit IEEE Floating Point number is a structured binary representation of a fractional decimal. It's not just a straight binary conversion like integers are.

For whole numbers, there's always an exact decimal -> binary conversion, but for fractional numbers there often isn't. For example, the number 1.3, when represented as closely as possible in 32-bit float format is actually 1.2999999523162841796875. See also the attached screenshot where a simple addition operation gives a weird result. Well, weird if you aren't aware of what's really going on under the hood.

I would seriously consider storing the values as an integer with 2 implied decimal places by multiplying by 100, or do the rounding wherever you're displaying the value.

Float_Math.JPG
 
I don't have access to TIA Portal anymore (and it's admittedly been a while since I've used it), could you not multiply your REAL number by 100 into a DINT or INT then divide by 100 back into another REAL?



That's how I would do it in Allen Bradley.

This is how I have done it as far back as the Atari 400.

Another workaround might be to run a formatting script on the rows or columns in the software that they are using to view this data.
 
Last edited:
Multiple real first by 100.
convert then to Dint.

Convert back from Dint to real and divide by 100.

Then it is real with 2 decimals most of time.


AS it is showed on csv, you could do it also on excel afterwards.
 
Last edited:
Yes as I posted, if Excel is the program you use to display the data there are many things you can do.
Firstly create a template *.xlt (or what ever the current format is) set the cells that will be populated with the data to 2 decimal places, other things you can do using the VBA (visual basic for applications) create a file picker (dropdown list) that loads the filenames (example file names: "Test machine 13_10_23_10:36")
Populate the list, so the operator can select the required csv, load it into say sheet 2, then itterate through the cells & copy them to Sheet 1 by placing them into the relevant cells, so from the data you could also create & populate graphs or a bit of maths do some sort of analasis on the data.
Save it as a template, make it read only so when the operator opens the template. when the operator wants to save it it will request save as & not destroy the template, I did a number of these, mine interrogated an SQL Data Base, the operator could select a date range then a list appeared with the data for each day, i.e. perhaps 30 batches, they would select the batch number, & it would produce a report. this template was distributed to those people who required it along with a shortcut on their desktop. As you can see from the pic, however, cannot show you the full details as on this PC I only have excel in read only mode but you can see with a little bit of VBA you can format the CSV data into a nice report.
I did a number of these for different plants, the template resided on one of our servers, with shortcuts on desktops of the personel who required it, in our particular case all the data resided on an SQL server with the relevant databases, however, for my personal use I did have a few on HMI's with SD cards in csv format I would copy the csv's onto my laptop (these ones had no connection to the network). ran the template. In my case the filenames were based on the following:
"FillingLine1_20221830_001"
So the filename was formatted as the line number, date,time,batch.

Line Efficiency.png
 
I'm asking because the operator says that the data that gets recorded into the CSV file is shown as 7 d.p. and they only want it to be 2 d.p. to match the HMI-displayed value (which is true, it's shown to 2dp on-screen).


What are the operators using to read the CSV file?


What (device, application, software?) is writing the CSV file?
 
someInt := (22.519432 * 100);

When converted to int/dint the remaining decimals should be discarded, leaving only the digits you want.

someReal := (someInt * 0.01);

multiply the remaining 4 digits to reinsert the decimal point, and store it again in a real variable.

If it's a string then, there is a different way you can implement a format, if needed could break it into pieces and concat back into one string.
 
Last edited:
What are the operators using to read the CSV file?


What (device, application, software?) is writing the CSV file?

They are using a web browser and entering the IP address of the PLC.
This takes them to a Siemens homepage, then they can log in to retrieve the CSV file. This is with TIA Portal/S7.

A number of the replies above are suggesting the "multiply by 100"/convert method, so I might try this.
 
The CSV file is on the MC card of an S7-1200 CPU ?
I am guessing you are using the DataLogWrite function, and you pass REAL values to the function.
If you have already rounded the REAL value to 22.52 as described in the previous posts, but you are still seeing 22.51999994 in the file after upload and opening in Excel, then it is because of the phenomenon I have described before.
A fix could be to convert the REAL number to a STRING with VAL_STRG.
VAL_STRG allows you to specify the number of decimals after rounding.
Then send the STRING to DataLogWrite instead of the REAL value.
 
The CSV file is on the MC card of an S7-1200 CPU ?
I am guessing you are using the DataLogWrite function, and you pass REAL values to the function.
If you have already rounded the REAL value to 22.52 as described in the previous posts, but you are still seeing 22.51999994 in the file after upload and opening in Excel, then it is because of the phenomenon I have described before.
A fix could be to convert the REAL number to a STRING with VAL_STRG.
VAL_STRG allows you to specify the number of decimals after rounding.
Then send the STRING to DataLogWrite instead of the REAL value.

It's not memory on a card (the slot is empty).
I guess it must be the internal memory which I believe is about 2MB in size.

The VAL_STRG conversion is now working as expected - see pic.

VAL_STRG.png
 

Similar Topics

Context: PLC= S7-1212C, HMI=KTP1200 Basic. Hi again, When the "REPORT" button is pressed (on a different screen), it takes the operator to the...
Replies
7
Views
670
Context: PLC= S7-1212C, HMI=KTP1200 Basic. Hi, The operator has reported that, from time-to-time, when he presses the "Generate Report" button...
Replies
5
Views
466
General Question: The PLC and HMI that I've been working on (a laser measurement system) is soon to be transported to the site where it will be...
Replies
2
Views
701
Hi, I'm not sure how to do this... Basically, I want to restrict the user input values for this tag to be in the range 20.001 to 25.0. I...
Replies
17
Views
1,640
Can someone help me with this? I'm no good at SCL - virtually everything I've done so far has been ladder logic. The return value from the...
Replies
13
Views
1,110
Back
Top Bottom