Introduction: Using Statistical Process Control to Test the Attiny85 Internal Clock

About: Jack passed away May 20, 2018 after a long battle with cancer. His Instructables site will be kept active and questions will be answered by our son-in-law, Terry Pilling. Most of Jack's instructables are tuto…

The datasheet for the Attiny85 states that the tolerance of the internal clock is +/- 10%. After my first test I found this hard to believe. So I applied Statistical Process Control to find out if this claim was really true.

Step 1: The USBtinyISP Programmer

I will be using the Sparkfun Tiny AVR Programmer available here:

Follow this link for instructions on how to add the Attiny85 definitions to the Arduino IDE:

If you want to use a different programmer, or build your own, that
is okay too. There many alternatives, just search instructables for "attiny".

You will also need:

  • A 5 volt power supply (I used an Arduino)
  • A breadboard
  • 2 LEDs (I used one red and one green)
  • 2 resistors 330-560 Ohm (my resistors are soldered onto the cathode lead of the LED)
  • A multimeter that can read frequency
  • Jumper wires
  • Attiny85s (The more the better)

Step 2: The First Test

For my first test I started this simple blink sketch running on two Attiny85s at the same time.

Load the Arduino IDE and put the chip in the programmer, the alignment dot on the chip goes on the end of the socket with the notch.

Go to Tools=>Board and select "Attiny85 (internal 1 MHz clock)".

Go to Tools=>Programmer and select "USBtinyISP".

Go to Tools again and select "Burn Bootloader"

This does not actually burn a boot loader, it only sets the fuse bits in the chip.

Now copy this code into the Arduino IDE and upload it to the chip.

 * Blink - for Attiny85
 * The anode of an LED connects to Digital pin one.
 * (That is physical pin 6, or PB1)
 * The cathode connects to ground through a 
 * 330-560 Ohm resistor.
int led = 1; 
int delaytime = 1000; 

void setup() 
  pinMode(led, OUTPUT);
void loop()
  digitalWrite(led, HIGH);
  digitalWrite(led, LOW);

Repeat the process for the second chip.

The result was that one ran considerably slower than the other. They were blinking totally out of sync with each other after 44 seconds. That sounds like a lot, something is wrong here. Did I just happen to pick the slowest and the fastest chip to run this test on my first try?

Actually when looked at from a different prospective this isn't so bad. The slower chip lost one second in 40. The difference is 39/40 which means the slow chip is running at 97.5% the speed of the faster one. Well within the stated tolerance.

Step 3: Testing the Frequency

Change this line in the original program:

int delaytime = 1000;

to read:

int delaytime = 1;

So one millisecond on then one millisecond off, the meter should read 500 Hz.

The first picture shows a frequency of 386.1 Hz at 1 MHz clock speed

Now go back into the Arduino IDE and set the board type to "Attiny85 (internal 8 MHz clock)", burn the boot loader, and reload the program. The second photo shows 488 Hz at a clock speed of 8 MHz.

It appears that some time is lost when it is turning the LED off and on. By programming it in assembly language I can be assured that it toggles in two clock cycles.

Step 4: The Assembly Language Program

This is the code for the assembly language program, the .hex file below is the program you will be loading onto the Attiny85:

; written by: JRV31
; date: 2-20-15
; version: 1.0
; file saved as: FreqTest.asm
; for AVR: attiny85
; clock frequency: 8MHz
; Program function:
; Test frequency of Attiny85 chips to see if they
; hold the +/- 10% specified in the data sheet.
.include "./"

.def  temp = r16
.def  counter1 = r17
.def  counter2 = r18
.def  counter3 = r19

.org 0x0000
   rjmp  Init

   ldi temp, 0b00000010
   out DDRB,temp ; Configure PB1 as output.
   sbi PORTB, 1  ; Set PB1 (Turn on LED in 2 clock cycles)
   rcall delay
   cbi PORTB,1   ; Clear PB1 (Turn off LED in 2 clock cycles) 
   rcall delay
   rjmp main

; This subroutine is a triple nested delay loop.
; if counter1 = 2, counter2 = 30 and 
; counter3 = 32 the delay this blink program
; runs at 504 Hz when the chip is running at 8 MHz.
   ldi  counter1,2
   ldi  counter2,30
   ldi  counter3,32
   dec  counter3
   cpi  counter3,0
   brne count
   ldi  counter3,32
   dec  counter2
   cpi  counter2,0
   brne count
   ldi  counter2,30
   dec  counter1
   cpi  counter1,0
   brne count

And this is assembled .hex file you will be loading onto the Attiny85s:


This file runs at 504 Hz when running at a clock speed of 8 MHz on my test Attiny85 with a crystal controlled oscillator. Every chip will run at this frequency if controlled by my crystal. This is the standard used to measure the speed of the chips. By running this on a chip using the internal oscillator and measuring the difference we can measure the speed of the chip.

Copy this code into a file and name it FreqTest.hex.

Open the Arduino IDE and set the board type to "Attiny85 (internal 8 MHz clock)", and burn the boot loader to set the fuses so the chip runs at 8MHz.

Now copy the FreqTest.hex file onto an Attiny85 using avrdude. Avrdude is the program that the Arduino IDE uses to upload code so you already have it installed.

Use this command to upload the program:

sudo avrdude -b 19200 -c usbtiny -p t85 -v -e -U flash:w:FreqTest.hex

Measure the frequency with your meter. The measured value over 504 times 8,000,000 will give you the actual speed of the chip when running on the internal clock at 8 MHz.

Every manufactured part has some tolerance. The crystal I used has a tolerance of 30 PPM so there is still some possibility of error, but it is minimized.

Step 5: Intro to Statistical Process Control (SPC)

To understand SPC it is necessary to understand the following terms:

The tolerance of the measurement you are trying to hold. Every process has variation, the tolerance sets the limits of how much variation is acceptable. Nominal is the center of the range of tolerance, the ideal measurement. Lower Specification Limit (LSL) and Upper Specification Limit (USL) are the limits of the tolerance.

The Mean is the arithmetic average of a set of values, or distribution.

The Median is the point where half of the values are less and half are more.

The Mode is the most common value.

In an ideal situation the Nominal, Mean, Median, and the Mode will all be the same.

Process Capability (CP) is the measurement to determine if the process is capable of holding the tolerance allowed. To find the CP first you find the Standard Deviation, the Mean + ( Standard Deviation * 3) gives you the Upper Control Limit (UCL). Next find the Lower Control Limit (LCL), Mean - ( Standard Deviation * 3). The capability is the ratio of the specification limits over the control limits, (CP = (USL - LSL) / (UCL - LCL). If the CP equals one the control limits fit exactly within the specification limits. You want it to be larger than one to give you some room for error.

The reason for using +/- three standard deviations is because in a normal distribution 68.2% of the values will fall within 1 standard deviation. 95.5% will fall within 2 standard deviations, and 99.7% will fall within three. These figures are mathematical constants.

CPK is the measurement of how well centered the mean is to the nominal, if they are identical CPK will equal CP. More variation between the two in either direction will result in a lower CPK.

The standard most widely used in industry is a CPK of 1.3. The math mentioned here gets complicated, but it is easy to estimate. With a normal distribution over the center half of the tolerance with the mean centered on the nominal your CPK will be approximately 1.3. An even distribution over the center half of the tolerance with the mean centered on the nominal will give you a CPK of approximately 1.1.

Step 6: Put in the Data and Get the Results

Download the two spreadsheets at the bottom of the step. Attiny85.ods is my data, the same as shown here. SPC.ods is a blank SPC template you can use for this or any other SPC study.

Burn the boot loader and load the program on each chip you are going to test. Run the program, and record the data in a copy of the SPC.ods spreadsheet.

Statistical Process Control
Capability Study Worksheet
Company Atmel
Order # Attiny85
USL - 554
LSL - 454
1 - 522 - 8,285,714
2 - 517 - 8,206,349
3 - 532 - 8,444,444
4 - 509 - 8,079,365
5 - 534 - 8,476,190
6 - 521 - 8,269,841
7 - 507 - 8,047,619
8 - 517 - 8,206,349
9 - 509 - 8,079,365
10 - 524 - 8,317,460
11 - 516 - 8,190,476
12 - 512 - 8,126,984
13 - 514 - 8,158,730
14 - 510 - 8,095,238
15 - 510 - 8,095,238
16 - 516 - 8,190,476
17 - 536 - 8,507,937
Nominal - 504
Mean - 518
Median - 516
Mode - 509
CP - 1.8419
CPK - 1.3262
LSL - 454
LCL - 490.8546
UCL - 545.1454
USL - 554
High Sample 536
Low Sample 507

Step 7: Conclusion

My initial thinking that some of my chips were running slow was wrong.

The test results show a CPK of 1.3262 which proves that the internal clock is well within the +/- 10% they claim.

The variation appears to trend to the high side.

Explore Science Contest

Participated in the
Explore Science Contest