If the totalizer is embedded in a larger chart, especially if it involves Modbus communication, the loop rate of that chart might be slower. Let’s say it is 50 ms on average, and assume there is at least a few ms random variation in the loop time. Over long time periods, this conditional:
if (nSecondsSinceMidnight <> nLastSeconds) then
// Update total
fTotalMeasuredSoFarToday = fTotalMeasuredSoFarToday + (fCurrentReading / 60.0);
would be satisfied on average every 1.025 sec, introducing some inflation (2.5%) into the calculated total. If you have very predictable loop times you could compensate for this, but an alternative might be to use a timer instead.
In the powerup chart, or on just the first time through the loop, initialize a down timer.
Then, somewhere in the loop that needs the totalizer, include the following:
if (dtTotalizer_Timer <> 0) then
fTotalizer = fTotalizer + (fRateInXPerMin * (fTotalizer_Timeout - GetRestartTimer(dtTotalizer_Timer)) / 60.0);
//The timer is reset immediately to keep the elapsed time as accurate as possible.
// Deal with a totalizer timeout error
The timeout value should be sufficiently large to cover any possible loop time, but by using a down timer, you are protected against an overflow error if something happens that would cause an up timer to run until it maxes out, as mentioned here:
Since the timer resolution is 1 ms, the total accuracy should be around 0.1%, which most likely makes the Rate measurement itself become the least accurate portion of the calculation.
I don’t know if it is possible that a time slice could expire in the middle of the totalizer calculation, but a 1 ms delay ahead of it could protect against that possibility by making sure it was always the first command of a new time slice.