Today is...
Thursday, November 27, 2014
Welcome to Control.com, the global online
community of automation professionals.
Advertisement
Featured Video...
Featured Video
Wiring and programming your servos and I/O just got a lot easier...
Advertisement
Our Advertisers
Help keep our servers running...
Patronize our advertisers!
Visit our Post Archive
Hour, Minute, Second from FLOAT
Rounding up is killing me.

OK... I want to take a "TotalSeconds" value (Integer) and convert it to HH:MM:SS format for display on a Panelview 600.

The 'formula' I use that appears to work great on paper is:

FloatHour = TotalSeconds/3600

DecimalHour = FLOOR(FloatHour) ('This is the HOUR to Display...)

FloatMinutes = (DecimalHour - FloatHour) x 60

DecimalMinutes = FLOOR(FloatMinutes) ('This is the MINUTES to Display...)

DecimalSeconds = (DecimalMinutes - FloatMinutes) x 60 ('This is the SECONDS to Display...)

so...On the Panelview, I have it set to display
DecimalHour:DecimalMinutes:DecimalSeconds

My problem is... the PLC rounds up. When I try to separate the integer from the fraction, it ain't happening.

An example:

TotalSeconds = 27381

FloatHour = 27381 / 3600 = 7.605

DecimalHour = *floor(7.605) - 7.605
(I cannot perform this function, because a SLC-500 does not have a floor function that I am aware of...)

Anyway, to continue:

.605 x 60 = 36.3

.3 x 60 = 18

So I would --love-- to display "07:36:18"...

I currently have no idea how to separate the integer.

Any Gurus got an idea?

Steve,
I generally use the mod instruction to get the remainder or left over integer value. Get the hours as per usual and then use the mod function to get minutes and seconds. If you have trouble, repost, and I'll dig up a code example for you.

Tra

Steve,

I am sorry about my previous reply, I assumed that the SLC has a mod function, my mistake - too much time on Contrologix lately I guess. I think you should be able to use the DDV (double divide function).

Good Luck.

By Rob Barrese on 7 June, 2007 - 12:44 am

To all,

Copied from the AB document 1747-rm001_-en-p.pdf

Updates to the Math Register, S:13 and S:14

Status word S:13 contains the least significant word of the 32-bit value of the MUL instruction. It contains the remainder for DIV and DDV instructions. It also contains the first four BCD digits for the Convert from BCD (FRD) and Convert to BCD (TOD) instructions. Status word S:14 contains the most significant word of the 32-bit value of the MUL instruction. It contains the unrounded quotient for DIV and DDV instructions. It also contains the most significant digit (digit 5) for TOD and FRD instructions.

Do the divide, store in a temporary address. S:14 now contains the unrounded quotient from the previous instruction. On the same rung, move S:14 to the address that will be the hour component of the string that you will assemble in the PanelView. Repeat for minutes and seconds. It is very important that the move from S:14 happens on the same rung as the contents of S:14 will always be changing and will hold the unrounded quotient while the rung is being actively scanned. If the rung is not being scanned, who knows what the contents of S:14 will be and where it came from.

Rob Barrese
Dofasco

By William Sturm on 6 June, 2007 - 12:31 am

In pseudo code:


int n1
float f1 = 7.605
n1 = f1 'convert to decimal
if (n1 > f1) 'check if it rounded up
f1 = f1-.500 'if so, force round down
n1 = f1 'convert to decimal again

It won't be so neat in ladder, but I think that the idea can be translated to SLC500

You may need to convert n1 back to float before comparing to the original number. Like this:


int n1
float f1 = 7.605
float f2
n1 = f1 'convert to decimal
f2 = n1 'convert back to float
if (f2 > f1) 'check if it rounded up
f1 = f1-.500 'if so, force round down
n1 = f1 'convert to decimal again