The the thing is the accuracy will always be a -% not +-%. There are 86,400 one-tenth-minutes in a day. A consistent -2% error from a 6 second timer would add up to 2.88 minutes/day...pretty significant cumulative error. Roll the thing over once a day and you lose at worst, a single scan time. All this assumes that timer overall accuracy is 100%.
Could you clarify how to do the timer in effective way.
Very nice: clean; easy to understand; also provides the raw information for display as HH:MM:SS without any extra ugly arithmetic, which is something missing from my approach.
That said, I think it could be simpler:
Thank you for posting your code: it is always interesting to learn from the approaches and design choices of others; and please be assured that none of my comments are meant either as destructive criticism or to say it works anything other than perfectly.
- the one-shot instructions (HM_ONS1; HM_ONS2 on rungs 1 and 2) might be unnecessary:
- The [RES HM_mSec_Timer], on the lower output branch of Rung 1, will reset the HM_mSec_Timer.DN bit to 0 on the same scan that the latter is set to 1
- So HM_mSec_Timer.DN is already, in effect, a one-shot
- Even it that were not the case, CTUs have their own internal rising edge detector (i.e. one-shot)
- The same reasoning applies to Rung 2 and the reset of the minute counter
- I see the hour CTU preset is 1000001, but the accumulator will never reach that preset because the GEQ branch on Rung 3 will trigger a reset on hour 1,000,000.
- Why do it this way, when a preset of 1000000 and using [XIC HM_Hour_Counter.DN] instead of the GEQ, would accomplish the same thing, as well as keep the logic in line with the previous two rungs for clarity?
- Also, I notice there is not a one-shot here, event though this implements resets similar to Rung 1 and 2, which suggests the previous one-shots were put there for the CTUs.
- Finally, 1e6h is over 114y: is that GEQ branch even necessary, or has your company found a source of very durable motors?
Allen Bradley doesn’t have an Hour meter block? Wow!
Why do you all make it so complicated...
OneSecondPulse
NEQ----------------------OTE
RTC_Second
RTC_Second_LastScan
-------------------------MOV
RTC_Second
RTC_Second_LastScan
OneSecondPulseFromPeriodicTask
-------------------------(Latch)
OneSecondPulseFromPeriodicTask OneSecondPulse
-----| |--------------------------------( )
|
| OneSecondPulseFromPeriodicTask
--------(Unlatch)
What he said...Because the best way to get the right answer ...
to generate an accurate one scan, 1-second pulse.
In an A-B MicroLogix 1400, we use the STI function file to trigger a program file every 1000 msec. In a Logix 5000 processor, we have a periodic task with a 1000 msec period. Both have just one rung:
OneSecondPulseFromPeriodicTask
-------------------------(Latch)
In either case, the main program, which executes at the start of each scan, has this as the first rung:
OneSecondPulseFromPeriodicTask OneSecondPulse
-----| |--------------------------------( )
|
| OneSecondPulseFromPeriodicTask
--------(Unlatch)