Prescaler causing a timing error? Why?

Go To Last Post
27 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I've been testing some time keeping code which uses timer1 to create an interrupt running at 200 Hz. When I select timer 1 prescale = 1 the code runs 100-percent accurate but if I use a different value in the prescaler it causes an error of around 0.8%

This doesn't seem logical because I wouldn't expect there to be an error where the timer misses clock pulses caused by some kind of synchronisation error. I assume the clock pulses are fed into a hardware divider, the prescaler, which would not cause any error.

Has anyone else ever come across a problem of this sort before?

Clock is derived from 8 MHz crystal. CPU is running at clock ÷ 32 giving CPU speed of 250 KHz. Chip is ATMega48.

The interrupt routine is simply a return which releases the CPU from idle state and then runs the time counting code which takes only a few instructions.

I can't think of any more details that would be helpful at the moment but please let me know if there's something else you need to know.

Thanks.

PS since the code works fine with the prescaler set at 1 I'm not stuck with this as a problem it just intrigues me as to why the error should only occur when the prescaler is not set to 1.

Last Edited: Sun. May 26, 2019 - 03:51 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well, are you using a freq counter to measure the output?  An old analog scope prob won't do.  Are you still generating 200Hz with the prescaler?   How are you measuring this 0.8%?  You are only prescaling the timer, correct?  Are you off by 1 count, which can be more significant if you change the timer OCR value.   If you slow down the processor itself, the IRQ latency becomes longer, though the latency itself should repeat at the same rate.  What happens if you don't put the processor in idle?

 

You aren't manipulating the prescaler at all are you (since it is a counter itself)? There are certain things that can be done to resync it (which you should not be doing)...If it runs free at all times, it should be an exact divider.

Post your code!

 

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

Last Edited: Sat. May 25, 2019 - 07:09 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

> How are you measuring this 0.8%?

The software counts the number of interrupts that have occurred. When using prescaler that is not set to 1 the error over time amounts to approximately 0.8%

> What happens if you don't put the processor in idle?

I can't really do this because that's how the software handles the counting.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If you are setting the counter match value to 1250

instead of 1249 (the off-by-one error mentioned by

avrcandies), then you can expect your timer to run

a bit slow:

 

    1250 / 1251 = 0.9992  (an 0.08% error)

 

Did you maybe measure 0.08% and not 0.8% ?

 

--Mike

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

When using prescaler that is not set to 1 the error over time amounts to approximately 0.8%

How much time? Also, since you have to read the count instead of outputting a wave, how do you know when you read the count?  Maybe it's counting perfectly, but your access to the number is not happening exactly when you think it is.  For example, if it took 1ms to access the count maybe you just missed some ticks.  You didn't say whether you are scaling down only the timer or the entire system.

 

0.8% is almost 1%, which is way way too much to be a prescaler issue.

 

Try toggling a pin in your IRQ & see if it toggles at exactly 200Hz.

 

Are you using an xtal?  

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Let's see the errant code. Like avr-mike I'm guessing the classic OCR off by 1 error that is magnified by prescaling.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for the suggestion that the error was caused by a 1 count difference in the compare register. I think this is it.

I was using a compare register count of 125 at the time.

125/124=1.008 and as I said I was measuring approximately 0.8% error.

So it wasn't a prescaler problem it was a compare register value problem.

This is a new one to me, so what this proves is that if you want to count to say 1000 you need to put 999 in the compare register. Why is that?

Thanks!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

'cause they start at zero.  S.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Scroungre wrote:

'cause they start at zero.  S.

Yes I understand they start at 0 but if you put 1 into the compare register then theoretically that would measure 1 period wouldn't it? If you put 0 into the compare register then wouldn't it go all the way around until it overflowed?

Is this anomaly because the hardware ignores the first pulse or something like that?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It's because 0 counts as one step so there are 125 steps in 0 .. 124

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So really as far as the timers are concerned the start value is always FF or FFFF. I must have missed that little gem in the manual somewhere!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

From the data sheet:

 

20.10. Output Compare Units
The 16-bit comparator continuously compares TCNT1 with the Output Compare Register (OCR1x). If
TCNT equals OCR1x the comparator signals a match. A match will set the Output Compare Flag
(TIFR1.OCFx) at the next timer clock cycle.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ahhhhh. Thank you. So it's a delay really. Should be a bit of a warning in the manual about how this can throw things out I would have thought?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It is in the data sheet.  What manual are you referring to?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If you set the prescaler = 1024, for example, and OCRx = 0, you will get an interrupt every 1024 clock cycles.  Check out the data sheet about the Output Compare Units.  It is something we have probably all scratched our heads about the first time we ran into it, like you just did. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Datasheet = manual. It's a big datasheet!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

one-off errors are fun for the unwary

 

The difference between 6 & 7 is staggering

That's why I like 16 bit timers & big numbers...if it is 23564 or 23565  ....I can hide my ineptitude in the noise or blame it on the crystal laugh

 

 

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You only look at one Special Function Register (SFR) at a time.

 

AVR datasheets are tiny.   Try looking at an ARM Cortex-M4.

 

The good news is that most AVRs work the same way.

 

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

"There are two really difficult concepts in programming.  Pointers, memory management, and off-by-one errors."

 

AVR datasheets are tiny.   Try looking at an ARM Cortex-M4.

I made that mistake once.  I downloaded one to print off and leaf through.  When I noticed it was 1600 pages I 'decided not to'.   indecision  S.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm still mystified about why the clock error is occuring. Since my previous posts the clock has been running at near to 100% accuracy as expected using a crystal. I'm not sure now that this is caused by the compare register value being off by 1.

Previously I noticed an error of 0.8% with a compare register setting of 125.

I calculated an error of 1 in 125 is 0.8% which explained why the problem was occurring, at least by the arithmetic anyway.

Since then I have set the prescaler to 1 and I'm now using a compare register account of 1250 which is exactly 10 times the previous value.

If there was always an error of 1 bit out of the compare register value then I would now expect an error of 0.08% but it seems to be running at 100-percent accuracy or so damn close I can't possibly tell.

Here are the numbers:

Crystal accuracy approx 50ppm
=0.005%

8 MHz crystal clock
÷32 = 250 kHz

I'm using 200 Hz interrupts so:

250k/200 Hz=compare register value of 1250

A 1 in 1250 count inaccuracy would be
1250/1249=1.0008
0.08%
which is 800 ppm

After 3 days (x 24 hrs x 60 mins x 60 secs)
=259200 secs
it would be 207 secs slow with an error of 0.08%...
but it's not even 1 sec slow...
maybe ½ sec slow at most

It would seem very odd if there was a problem with the compare register value being off by 1 if there is a prescale value on the timer clock input, but not when the prescaler is set to 1, but at the moment I can't think of any other explanation!

Last Edited: Sun. May 26, 2019 - 05:17 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I calculated an error of 1 in 25 is 0.8% which explained why the problem was occurring

WHAT?  1 in 25 is 4%...sound like you meant 1/125.  Did you set up a pin to toggle & measure the freq?

 

After 3 days (x 24 hrs x 60 mins x 60 secs)=259200 secs
it would be 207 secs slow with an error of 0.08%...but it's not even 1 sec slow...maybe ½ sec slow at most

HOW would you know 1/2sec?  Now you are talking about something completely different.   Now you have to know EXACT moment it was originally set & then know EXACTLY when 3 days has elapsed & EXACTLY read (without delays) & compare that to your 200Hz.  That's a lot to say something was within 1/2 sec 3 days later.   This is much different than measuring a continuously running signal & verifying it is exactly 200Hz, which only measures time between edges.   If you only want to know itt is more than 200 seconds off that is  much simpler than saying 1/2 sec, considering al of the error sources.

 

You just now posted settings when it works...where are the settings when it doesn't?  Are you saying you measured it was off by 200+ seconds in 3 days?

 

Try getting rid of the idle state..you can certainly update your counts in the timer irq.  Perhaps idle causes something funny in the timer prescaler (like just missing an edge).  At least then you'll know it is not associated with entering/leaving idle.

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

Last Edited: Sun. May 26, 2019 - 05:01 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I ran a similar experiment with a stepper motor that I wanted to do one complete revolution in 24 hours.  I think I used a 200 step/revolution stepper motor.  I set the time between steps appropriately using timer 1, and did a bunch of experiments where I started the thing at a particular time that I wrote down, and came back 24 hours later and watched for the last step of the motor, and it was right on at 24 hours.  I dont know how you are doing your measurements, but you should clearly get different results if you set OCRx = 1249 and 1250.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Use a scope or logic analyser or something that accurately measure period then toggle a pin at the start/end of the timing period.

 

Also confirm it is a CTC mode and not some programmatic adjustment of TCNT (which can be affected by lag/jitter).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

>WHAT? 1 in 25 is 4%...
Sorry, was a typo. Corrected now.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I know the error is less than half a second over 3 days because I've got it running next to a radio clock which of course is accurate to within thousandths of a second.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Post your code.   It takes about 4 lines to initialise a Timer.   And another 4 lines for the ISR()

 

Regular HF crystals are pretty good.

HF Resonators as used by official Arduinos are crap.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I know the error is less than half a second over 3 days because

While certainly you can tell if the output drifts by several seconds over 3 days, to say it is within 1/2 second can be a bit bold.  How do you know exactly when things start & what is the delay in readings (of your device & the stopwatch/clock)?   

 

next to a radio clock which of course is accurate to within thousandths of a second.

What if the radio clock only updates its display every 300ms?  The radio display probably has a resolution no finer than 1 sec.  Typically you want a 10x resolution factor in a measurement.   So to measure to 1/2 sec you should be able to resolve to 1/20 of a sec.  These are the kinds of factors that can make something that is slightly off seem good, or something that is actually good, seem to be off.

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!