Dear all,
I want to turn my ATtiny85 into a little clock. I connected it to a 16MHz quartz crystal oscillator (with two 22 pF caps to ground). I connected an LED (with resistor) to PB1. I wrote AVR-C code that makes an LED turn on for 1 sec, every 60 seconds. I'll put the code below.
#define F_CPU 16000000
#include <avr/io.h>
#include <avr/interrupt.h>
uint8_t tickCounter = 0;
volatile uint16_t seconds = 0;
int main(void)
{
uint8_t ledPin = ( 1 << 1);
DDRB |= ledPin; // Set PB1 to OUTPUT
TCCR0A = (1 << WGM01); // Set CTC (Clear Timer on Compare)
OCR0A = 125; // Set No. of Ticks.
TIMSK = (1 << OCIE0A); // Enable comparing with OCIE0A
sei();
TCCR0B = (1 << CS02) | (1 << CS00); // start at 1024 Prescaler
while(1)
{
if( seconds == 60 ) // After a minute
{
seconds = 0;
PORTB |= ledPin; // Turn on ledPin
}
if( seconds == 1 && (PORTB & ledPin)) // if still on, one second later
{
PORTB &= ~ledPin; // turn ledPin off again
}
}
}
ISR(TIMER0_COMPA_vect)
{
tickCounter++;
if( tickCounter == 125)
{
seconds++;
tickCounter = 0;
}
}
I used a stopwatch to check the device. The LED should blink exactly once a minute. However, after some time, the LED was visibly lagging behind. I connected PB1 of the ATtiny85 to an arduino nano, and using a python script, I measured the time between the led blinks.
22:30:50.238706
22:31:50.723718
22:32:51.208745
22:33:51.693768
22:34:52.178787
22:35:52.663817
22:36:53.148838
22:37:53.632866
22:38:54.117888
22:39:54.602911
22:40:55.087935
22:41:55.572962
22:42:56.057985
22:43:56.543009
22:44:57.027030
22:45:57.512055
22:46:57.997080
22:47:58.482100
22:48:58.967125
22:49:59.452150
22:50:59.936176
22:52:00.421197
22:53:00.906221
22:54:01.391246
22:55:01.876270
22:56:02.361294
22:57:02.846319
22:58:03.330341
22:59:03.815367
23:00:04.300389
23:01:04.785417
Power source: 5V, Arduino nano
Temperature: 25.7 *C
The timer appears to be approximately 0.8% off. Interestingly, the internal oscillator of the ATtiny85 was also off with a similar percentage.
Of course, I could edit the code (eg: change the number of ticks) to make the clock more accurate. But I'm really curious why the timing appears to be off. Is there an error in the code? Is the hardware inaccurate? Do you guys have a hypothesis?