Accurate Timing for ATTiny85 - Internal Oscillator at 1MHz
by hausofpayne17 in Circuits > Arduino
41 Views, 0 Favorites, 0 Comments
Accurate Timing for ATTiny85 - Internal Oscillator at 1MHz

I'm building an electronic hourglass timer for fun (Instructable to come) for games like Boggle, charades, Pictionary etc.
I'm a maker, not an engineer. I know just enough to get me into trouble. (At least nobody's died yet.)
I'd like the hourglass timer to be as accurate to the second as possible, for countdown times between 1 and 15 minutes.
After much research online as to how to make the ATTiny85 keep accurate time, with discussions between the merits of internal versus external timers, I decided for my purposes, that using an internal RC oscillator was the most appropriate strategy. It reduced size and component complexity as I didn't have to make space for an external 16MHz crystal (which I couldn't get to work anyway).
This instructable is mostly an explanation of a very helpful Arduino forum posting by "Erni" with some minimal additional code for my timing experimentation.
The conditions for this experiment are:
- ATTiny85 running at the default 1 Megahertz
- 22 degrees Celsius (71.6F) room temperture.
- 62% relative humidity in the room.
- The controller is running at 5 volts.
My experiments showed that the ATTiny85 can generate minute timing to within 0.61% of the desired minute value.
(Heads up - if you're using a MAX7219 LED controller in your project, it uses Timer0 and Timer1 so you may find this instructable of limited use if you're trying to get accurate timing AND use an LED controller.)
Supplies
- Attiny85 microcontroller and programmer with Arduino IDE.
- 2 LEDs
Wiring
Set up your ATTiny85 in your programmer.
Wire one LED to gpio 4 and the other LED goes to gpio 3
Code Overview
Download the attached .ino file and load into your IDE.
All credit for the accuracy is due to "Erni" from post number 4 on the arduino.cc forum. The orignal link is here.
The code is based on using an Interrupt Service Routine with some Output Compare Register adjustment for the timing.
The key part of the oscillator calibration is the Output Compare Register OCR0A. By default this value is set to 127. At this value, the ATTiny85 was running about 6 seconds too long on a 1 minute timing cycle.
As I adjusted the OCR0A value downwards I converged to a value of 116.
Inside the ISR function, the LED blinks approximately every 0.5 seconds.
The variable endTime is the amount of minutes wanted for testing the oscillator's accuracy.
The variable sCount is a counter of the number of ISR cycles that happen.
In the loop() block the value 133 is a counter limit that I experimentally determined approximately relates to 1 minute of elapsed time based on the original OCR0A value of 127. When this value is exceeded, the other LED is set HIGH to indicated the end time has been reached.
Downloads
Experimental Results

I tested the OCR0A value of 116 for all the minute times between 1 and 15 minutes. The Desmos-plotted data of Observed Seconds versus Desired Minutes in the table and graph with the linear regression line is attached here. The variation from pure linear relation is down to the accuracy with which I pressed the STOP button on my phone stopwatch for each trial.
Based on my downward adjustment of OCR0A from 127 down to 116, I got an overall r-squared value of 1.0. In other words, 100% of the value the observed time directly relates to the desired (endTime) value. It's not exactly 100% accurate but pretty amazing nonetheless!
As a percentage accuracy of the absolute difference between generated time and desired time, the average generated elapsed minute result is within 0.61% of the desired minute value. That's over 16 times better than the expected 10% accuracy.
I plan to run the hourglass timer on 4.5Volts. Since the internal RC oscillator has some variation based on voltage, I'll need to adjust the OCR0A value again to account for the new operating voltage (as well as controller/circuit temperature etc.)
Thanks to "Erni" for his very helpful posting to the arduino.cc forum for helping me understand how to calibrate my timer.
I look forward to incorporating this code into my other ATTiny85 projects that require timing.