Here is one of several possible approaches, good for ~1s accuracy.
The guts of the logic are fairly straightforward and concise, and are in the two rungs of the center subroutine [LAD4 24H_STARTS] i.e. the rungs driving the FFU/FFL instructions.
- When a start event occurs
- the FFL (Rung 0001) pushes a time* that is 24h in the future** from the current scan time*** onto a FIFO****
- and increments R6:0.POS by 1
- So the times in the FIFO are ordered by increasing time, and
- the value of the element at the start of the FIFO (L9:3) is the oldest time in the FIFO
- i.e. the time of the earliest start event in the FIFO
- When the current time's value (NOW L9:0) eventually increments to a value greater than the oldest time in the FIFO (L9:3),
- the FFU (Rung 0000) pops that oldest time (L9:3) off the FIFO,
- shifts the rest of the FIFO down 1,
- and decrements R6:0.POS
- R6:0.POS is the number of start times (Rung 0002 of pLAD 2 MAIN]) over the previous 24h, which are time values between NOW and (24h before NOW)
- Btw, the logic as written can also handle multiple start events during a single second of time.
I split out the calculation of NOW and 24H_HENCE into a separate subroutine [LAD 3 GET_NOW], which implements a somewhat accurate poor-man's 1Hz clock that should not overflow during any likely contiguous period while the PLC is in RUN mode. In Studio 5000, the GSV WALLCLOCKTIM/CurrentValue might be a better approach, if the chosen PLC can do math and comparisons on LINTs/DTs/LDTs, but the actual implementation is the coder's choice as far as I am concerned.
I did this for a MicroLogix 1100, but it should port to Studio 5000 without too much effort*****. It needs more logic to handle PLC restarts properly (clear FIFO .POS to 0) in the MicroLogix ecosystem, but with Studio 5000 that problem goes away if the GSV WALLCLOCKTIME/CurrentValue is used for time.
* time is counted in Long (≡ DINT) seconds past relative to an epoch 68y+ after the PLC enters run mode (see Rung 0000 of [LAD 3 GET_NOW]).
** L9:1 a.k.a. 24H_HENCE (Rung 0003 of [LAD 3 GET_NOW]; 24h ≡ 86,400s)
*** L9:0 a.k.a. NOW; initialized to -2G (80000000H) so it's good for 136y+.
**** The FIFO is an array from L9:3 through L9:66; on the MicroLogix, the FIFO is limited to 2048 bits ≡ 64 Longs; Studio 5000 would greatly increase that limitation.
***** Porting to Studio 5000:
- Use tags and arrays instead of RSLogix 500 file elements
- Use DINTs, or even LINTs or DTs or LDTs, for time instead of LONGs
- Possibly use GSV to get the NOW time, and 86.4E9 (µs per 24h) as the increment from NOW to 24H_HENCE
- Etc.