RTC v Compensated Timer1 on Nano. Which is best?

Hi guys. This is really an addition to a previous post about using the timers in Nanos. I got some ridiculously good support from a couple of you here, (can't find the original thread now to name you, how do I find my own past posts?), for which I am extremely grateful. Your patience was rewarded and I am now using Timer1 and its interrupts very comfortably.

I have a sketch working extremely well which simply takes in a preprogrammed time period in the range 1us-1sec and fires an output pulse on a pin on completion in response to an initiating pulse on an input pin. I am using Timer1 with no prescaler and the method is pretty simple.

The program starts by taking the delay period, converting it into ticks, and then splitting the overall tick count into 3 parts, (the 3 parts is explained later). It then sets up an opening loop which is an overflow starting at a preset count for a shortened loop. Then there are a number of full overflow loops. Then there is a final compare loop which automatically toggles the output. The relevant interrupts are setup up and activated/deactivated on completion of the phase before. Firstly only the Capture interrupt is activated. When its ISR is hit it toggles a boolean for the loop() where Capture is turned off and the Overflow interrupt is activated. When the loops of the overflow phase are completed another boolean is toggled which deactivates the Overflow and activates the Compare interrupt. That loops once and toggles the output.

All calculation of the counts is performed once before the delay process is initiated. No calculation or controlling of any kind is done while the loop is running other than the interrupt switching. The only process which is extra to looping is serial reporting which is a diagnostic aspect only and should not interfere as each of the three loops is ensured to be over a minimum count of 16,384, 1/4x 16 bit buffer. Hence the 3 "short overflow, full overflow, compare" loops and not the simple "full overflows, compare" method which could be done. Every period between interrupts is ensured to be at least 16354 ticks long. Perhaps it may be overkill but it seems to work perfectly and there is really no need to post code for this unless you really want to go over it. It isn't actually the question.

I know that the timer is inaccurate due to its hardware limitations so I wrote a sketch which would test this. It's a mixture of manual processes with their own inherent inaccuracies added in and is just to get a feel for the idea. It acts like the main delay program except it is set over a much longer period, I used 250mins purely for reasons of the limitation on unsigned longs and the internal counts involved.

I use an online timer based on the atomic clock for comparison. I have to manually synchronise the switching on and matching of my Arduino delay and the online timer which is an inaccuracy I was worried about, until I saw the results! My sketch reports back the state of the loop counter every loop so I see a fast running countdown to completion. It does this in the loop() function not in the ISR. Remember, each interrupt loop of any type is set up to have a minimum tick count of 16,384. With the 3 loop method, no matter what the delay requested, any external processing (Serial.println) should have plenty of ticks to complete before the next iteration comes through. I reckon that should not interfere with the timing in any way unless I am missing something fundamental.

My results were not impressive. Over 250mins the errors in timing of 4 different Nanos were as follows: 18.95s, 24.3s, 28.5s, 40.1s. I use these timings to create a correction factor for the clock based on 250mins + error : 250mins. I can take the required delay, convert it to ticks, correct the tick count to compensate for each Nano, Bob's your uncle! With another 250mins (4hrs 10 mins!) test this took the delay over 250mins of the first 18.95s down to 0.1s, allow for the manual processing of course. That manual error really should not be more than a tenth or two and proves the method I think. How hard is it to press a push button and a mouse button at the same time, then to press a mouse button in response to a fast action countdown to 0? It is definitely a big improvement and seems to be accurate.

This can be approached in a different way when the units are in use. They are being triggered by a pulse from a much more advanced unit which has GPS timing capabilities and can display an accurate reading of the delay when it receives the return pulse. This can be used to generate a much more reliable version of the correction factor against a 1s delay which can be input to each box as it needs.

So, finally :confused: , to the question. The other alternative is to install a RTC which seems to be a simple solution to this and accurate to about 1us in 1s. This would certainly be accurate enough for my needs, (<50ppm in usec timing overall). However, the work is done on the existing method and it is fairly easy to set up and manage. Is the existing method likely to suffer from greater errors than the RTC would over time? I am sure the immediate use would be ok. The error is easily investigated and compensated for. There are variations due to environmental factors of course but these average out. Would it be likely to change permanently overtime or is the basic Arduino clock reasonably stable over its lifetime? And, if so, would the TRC suffer from the same long term drift?

bordonbert:
how do I find my own past posts?

Here's how you can find your previous posts:

  • Hover the mouse pointer over your avatar in the top right corner of any arduino.cc page.
  • Click "Profile".
  • Click "Forum Settings > Edit".
  • Click "Show Posts".

Duuurhhh! Thanks Pert. That was the first place I looked but I plain old dumb missed the Settings side of it. Gotcha.

My original thanks were owed to Gfvalvo who took me from zip to having a basic ability to use the timers. :wink: