Atmel clock/timer projects

98 views
Skip to first unread message

NeonJohn

unread,
Nov 4, 2013, 5:16:01 PM11/4/13
to neoni...@googlegroups.com
I'm working on a simple count-down timer that will time from 0.1 to 999
seconds with 0.1 second resolution. I'm using an Atmel ATmega8515,
probably not the best chip but I have a ton of 'em from another project.

My problem is, it's not behaving anything like I expect. Up to about 10
seconds, the time interval is about a tenth of a second too long.
Between 11 and about 60 seconds, it's spot on. At 999 seconds, it has
lost 3 seconds.

I'm doing things rather conventionally. Timer 0 is set up in CTC mode
to count down the 16MHz clock at 1ms intervals. There's a state machine
that stores what the timer is doing (idling, being set, counting,
finished, etc) but the actual assertion and de-assertion of the output
pin is done in the ISR. It should therefore have millisecond accuracy.

The erroroneous time is repeatable from one run to the next down to the
millisecond so I know that I'm not missing interrupts. I've also
verified that by toggling an unused pin inside the ISR and timed it with
a high precision HP counter/timer.

So my first question to the list is, can you point me to some Atmel
clock code in C that I can study to see what I might be doing wrong?

Later I may post the code and ask for someone to look at it but I really
want to solve this problem for myself.

This is a timer for our (Fluxeon's) Roy induction heater but I plan on
open sourcing the thing - hardware and software - once I get it working.
So it needs to work right AND the code has to look good :-)

Thanks.
John

--
John DeArmond
Tellico Plains, Occupied TN
http://www.fluxeon.com <-- THE source for induction heaters
http://www.neon-john.com <-- email from here
http://www.johndearmond.com <-- Best damned Blog on the net
PGP key: wwwkeys.pgp.net: BCB68D77

Matthew Smith

unread,
Nov 4, 2013, 5:24:21 PM11/4/13
to neoni...@googlegroups.com
Quoth NeonJohn at 2013-11-05 08:46 ...
> I'm working on a simple count-down timer that will time from 0.1 to 999
> seconds with 0.1 second resolution. I'm using an Atmel ATmega8515,
> probably not the best chip but I have a ton of 'em from another project.

I've been away from AVR for a good while now (defected to Freescale)
but, if you don't get any joy, I'd suggest you try www.avrfreaks.net.

Cheers

M


--
Matthew Smith

Business: http://www.smiffytech.com
Blog: http://www.smiffysplace.com
Linkedin: http://www.linkedin.com/in/smiffy
Flickr: http://www.flickr.com/photos/msmiffy
Twitter: http://twitter.com/smiffy

ABN 16 391 203 815

Grahame Marsh

unread,
Nov 4, 2013, 5:37:00 PM11/4/13
to neoni...@googlegroups.com

John,

If you would email the source file(s) to me I'll look 'em over. I'm ok
with AVRs and use AVR-LibC a lot (not that you've said your using that
compiler).

Grahame

Adam Jacobs

unread,
Nov 4, 2013, 6:14:59 PM11/4/13
to neoni...@googlegroups.com
Hi John,
I haven't done anything with AVR chips in a couple of years now, but
I can only add that I've felt your pain. I built a lot of clocks using
AVR parts, in a variety of designs and with a variety of AVR chips...
and they all had strange repeatable timer issues. I do think that the
AVR parts might miss interrupts on occasion... are you disabling the
timer interrupts at any point in your code? I think that you usually
need to disable interrupts when interacting with i2c parts, etc...
-disable interrupt
-dump command to peripheral part
-enable interrupt

Like that... and that sort of thing is what I always assumed was the
culprit. Eventually, I decided that it simply wasn't worth it for me to
implement solid clock code in AVR and switched to using standalone clock
chips. I like the Maxim DS1307, since it comes in 8-pin DIP package and
is i2c. That way, I can worry about the fun functionality in my AVR code
and leave the dreary clock accuracy optimization to the birds.

FYI, I did find that my clock accuracy increased if I lowered the
frequency of the AVR. 12mhz ATTiny2313 was much less accurate than the
same part with the DIV8 fuse set. I assume because a 1.5mhz clock AVR
would need to interrupt far less often in order to generate the desired
0.1 second resolution.

-Adam

Frank Bemelman

unread,
Nov 4, 2013, 7:00:24 PM11/4/13
to neoni...@googlegroups.com
Hi John,

Difficult to say something about it, without any code and hands on.
I never liked CTC timer modes. Perhaps it is easier to have an
interrupt generated only by a prescaler. Of cource that gives you
weird time values, depending on your crystal, and may give an
interrupt at every 57uS or whatever. But that is not a problem, to
have 'master' clock that ticks at such weird (but steady) interval.
Assume you have an interrupt every 57 uS.


[untested code]

int timervalue = 0;
int msektimer = 0;
.
.
.

timer_int()
{ timervalue += 57; // add the uS that have passed since previous interrupt
if(timervalue>1000) // a millisecond + some extra uS have past
{ timervalue -= 1000; // keep the remaining uS
msektimer++; // keep track of total milliseconds
}
}

Keeping track of seconds can be done in a similar way, just expand code.
Sure there is some jitter on the timervalues, but a jitter of 57uS
is usually not a problem for household purposes.

Frank


-----Oorspronkelijk bericht-----
From: NeonJohn
Sent: Monday, November 04, 2013 11:16 PM
To: neoni...@googlegroups.com
Subject: [neonixie-l] Atmel clock/timer projects
--
You received this message because you are subscribed to the Google Groups
"neonixie-l" group.
To unsubscribe from this group and stop receiving emails from it, send an
email to neonixie-l+...@googlegroups.com.
To post to this group, send an email to neoni...@googlegroups.com.
To view this discussion on the web, visit
https://groups.google.com/d/msgid/neonixie-l/52781CA1.2060803%40neon-john.com.
For more options, visit https://groups.google.com/groups/opt_out.

NeonJohn

unread,
Nov 4, 2013, 7:31:09 PM11/4/13
to neoni...@googlegroups.com


On 11/04/2013 06:14 PM, Adam Jacobs wrote:
> Hi John,
> I haven't done anything with AVR chips in a couple of years now, but I
> can only add that I've felt your pain. I built a lot of clocks using AVR
> parts, in a variety of designs and with a variety of AVR chips... and
> they all had strange repeatable timer issues. I do think that the AVR
> parts might miss interrupts on occasion... are you disabling the timer
> interrupts at any point in your code? I think that you usually need to
> disable interrupts when interacting with i2c parts, etc...
> -disable interrupt
> -dump command to peripheral part
> -enable interrupt

Ahhhh, I'm glad it's not just me and that I'm not going crazy :-)

The only time I disable interrupts is to write to EEPROM and that's only
to store the last value for retrieval during the next power-up.

The only problem I have with the idea of random missed interrupts is
that my code will repeat, say, a 100 second interval down to fractions
of a microsecond. May be off by a whole second but it sure repeats.

The next thing I'm going to do is to re-connect the output pin to the
CTC match interrupt and measure that with my counter. See how much
jitter there is in that.

Grahame and others, the code as it exists right now is here:

https://dl.dropboxusercontent.com/u/81715047/jgd_timer_code_11_04_2013.zip
>
> Like that... and that sort of thing is what I always assumed was the
> culprit. Eventually, I decided that it simply wasn't worth it for me to
> implement solid clock code in AVR and switched to using standalone clock
> chips. I like the Maxim DS1307, since it comes in 8-pin DIP package and
> is i2c. That way, I can worry about the fun functionality in my AVR code
> and leave the dreary clock accuracy optimization to the birds.

I would have put an RTC on the board but there is absolutely no space
left. This is a retrofit to an existing product and the board is having
to use otherwise unused space on the back side of the front panel. I
already have my board house a little miffed. :-)

>
> FYI, I did find that my clock accuracy increased if I lowered the
> frequency of the AVR. 12mhz ATTiny2313 was much less accurate than the
> same part with the DIV8 fuse set. I assume because a 1.5mhz clock AVR
> would need to interrupt far less often in order to generate the desired
> 0.1 second resolution.

Interesting. I had intended on running this chip at 8MHz but I couldn't
find a crystal nor an oscillator physically small enough to fit the
space available so I'm running at 16MHz. Maybe I'll try an 8MHz part
and let it just dangle for the prototype.

Thanks to everyone who has commented so far. You've certainly given me
some stuff to think about.

NeonJohn

unread,
Nov 4, 2013, 7:57:50 PM11/4/13
to neoni...@googlegroups.com


On 11/04/2013 07:00 PM, Frank Bemelman wrote:

> Assume you have an interrupt every 57 uS.
>
>
> [untested code]
>
> int timervalue = 0;
> int msektimer = 0;
> .
> .
> .
>
> timer_int()
> { timervalue += 57; // add the uS that have passed since previous interrupt
> if(timervalue>1000) // a millisecond + some extra uS have past
> { timervalue -= 1000; // keep the remaining uS
> msektimer++; // keep track of total milliseconds
> }
> }
>
> Keeping track of seconds can be done in a similar way, just expand code.
> Sure there is some jitter on the timervalues, but a jitter of 57uS
> is usually not a problem for household purposes.

Clever. I have been thinking about slowing the interrupts down
dramatically but I can't generate a precise decimal time interval that
way. I'd been thinking about an algorithm but yours just solved it for
me. Thanks much

Adam Jacobs

unread,
Nov 4, 2013, 8:05:31 PM11/4/13
to neoni...@googlegroups.com
Yep, this is the way that I ended up doing it in my ATTiny2313 clocks.
It works better than CTC timer, but it still had the same kinds of
problems for me. (to a lesser severity)

-Adam

NeonJohn

unread,
Nov 5, 2013, 2:26:17 AM11/5/13
to neoni...@googlegroups.com
Thanks to TVB who gave me a gentle nudge in the direction of measuring
instead of relying on the data sheet, my timer is working perfectly.
The data sheet formula for calculating the output compare register value
is simply wrong.

What I did was program the output compare pin back on and then let the
processor do nothing but generate that 1ms interval. I set the pin to
toggle on interrupt so that produced a 500.0000 Hz signal. Or at least
it should have.

I then adjusted the output compare register value until I got 499.9999
Hz. I already knew the quartz oscillator was a touch low in frequency
so that was perfect.

I just finished a 999 second run. Accurate to a millisecond.

Here's the code that works. I need to prune out a bunch of
commented-out stuff and make it pretty but it does work. I'll put it
and a schematic on my website shortly.

https://dl.dropboxusercontent.com/u/81715047/jgd_fixed_timer_code_11_05_2013.zip

Thanks, guys, for the help,

Adam Jacobs

unread,
Nov 5, 2013, 1:55:59 PM11/5/13
to neoni...@googlegroups.com
Awesome work! I'll look at your code and see about patching some of my
built clocks...

-Adam
Reply all
Reply to author
Forward
0 new messages