Small Jobs on an ATtiny85

Draft. This tutorial has not been checked against the physical product yet. Confirm wiring, pin assignments and voltage limits against the product documentation before building it.
DifficultyAdvanced
CategoryFoundations
Supported boardsATtiny85, programmed from an Arduino Uno
Time needed60 minutes
PrerequisitesRunning an ATmega328P Without the Board
Tested boardNot yet verified
Tested onNot yet verified
Arduino IDE versionNot yet verified
LibraryNot yet verified

What it does

Eight pins, five of them usable, 8 KB of flash and 512 bytes of RAM, in a chip the size of a fingernail.

That sounds like nothing, and for a great many jobs it is plenty. A light that fades up at dusk. A timer that switches something after ten minutes. A temperature probe that flashes a warning. Any of those on an Uno is a board doing a hundredth of what it could; on an ATtiny85 it is the right size of part for the job, costs very little, and draws microamps asleep.

It is also the clearest demonstration of what the Arduino environment actually is. The same language, the same setup() and loop(), on a chip with no serial port and no bootloader.

Before you begin

Required parts and tools

  • An Arduino Uno, as the programmer.
  • One ATtiny85 in an 8-pin DIP package. This is Siratek product 5695, the 20PU.
  • A breadboard, jumper wires, a 10 microfarad capacitor and a 0.1 microfarad capacitor.
  • An LED and a 220 ohm resistor, to see something happen.

Five usable pins

Eight physical pins: two are power, one is reset, and five are yours.

Chip pin Arduino name Notes
1 PB5 / pin 5 Also RESET. See below
2 PB3 / pin 3 Analog A3
3 PB4 / pin 4 Analog A2
4 GND
5 PB0 / pin 0 PWM
6 PB1 / pin 1 PWM
7 PB2 / pin 2 Analog A1, and the only interrupt pin
8 VCC

Pin 1 is a trap. It is RESET by default, and using it as an ordinary pin requires disabling reset with a fuse — after which you can no longer program the chip without a high-voltage programmer. Treat it as four usable pins plus one you should leave alone, and only consider the fifth when a design is finished.

Pin 7 is worth saving. It is the only pin that can wake the chip from sleep on an external interrupt, which is exactly what a battery project needs.

What it does not have

Being honest about the limits, because they decide whether this chip fits:

  • No hardware serial. No Serial.print() in the usual sense. Debugging is by LED, or by a software serial library that costs a pin and some flash.
  • No bootloader, normally. You program it through another Arduino every time.
  • 8 KB of flash, which a couple of libraries can fill.
  • 512 bytes of RAM, which is a quarter of an Uno’s. One moderate String and it is gone.
  • No I2C or SPI hardware, though the TinyWire libraries bit-bang I2C adequately.
  • The internal oscillator is about one percent accurate, which makes software serial marginal and anything timing-critical drift.

If your sketch needs more than two of those, use a Pro Mini instead: it costs little more and has none of these constraints.

The capacitor on the Uno’s reset

Same as the ATmega328P page, and the same reason: after loading ArduinoISP, a 10 µF capacitor between the Uno’s RESET and GND stops it resetting itself when the IDE opens the port.

Without it, programming fails with a sync error that points nowhere useful. Remove the capacitor when you have finished.

Pin reference

The standalone circuit is almost nothing:

Chip pin Connect to Purpose
8 VCC Supply positive 2.7 to 5.5 V
4 GND Supply negative Ground
8 to 4 0.1 µF capacitor Decoupling, at the chip
5 PB0 LED through 220 ohms Something to see

Three components, one of them the LED.

The programming connections, from the Uno:

Uno ATtiny85 pin
D10 1, RESET
D11 5, PB0
D12 6, PB1
D13 7, PB2
5V 8
GND 4
An ATtiny85 on a breadboard with power, a decoupling capacitor and an LED, plus the six wires to an Uno acting as a programmer and the 10 microfarad capacitor on the Uno's reset
Six wires to program it, three components to run it. The capacitor on the Uno’s reset is what makes programming work.

Wiring steps

  1. Seat the ATtiny85 on the breadboard, notch to the left. Pin 1 is bottom left.
  2. Pin 8 to the positive rail, pin 4 to the negative rail.
  3. 0.1 µF capacitor between pins 8 and 4, right at the chip.
  4. LED and 220 ohm resistor from pin 5 to ground.
  5. Upload ArduinoISP to the Uno, from File, Examples.
  6. Then fit the 10 µF capacitor between the Uno’s RESET and GND.
  7. Wire the six programming connections as in the table.

Software and libraries

Add a board definition, because the ATtiny85 is not a standard Arduino board. ATTinyCore by Spence Konde is the usual choice, installed through Boards Manager with the package URL from its documentation.

Then:

  • Tools, Board: ATtiny25/45/85 (No bootloader)
  • Tools, Chip: ATtiny85
  • Tools, Clock: 8 MHz internal
  • Tools, Programmer: Arduino as ISP

Burn Bootloader once, even though you are not using a bootloader. That step sets the fuses, which is what actually selects the clock. Skip it and the chip runs at its factory default of 1 MHz, and every delay in your sketch will be eight times too long.

Then Sketch, Upload Using Programmer. The ordinary upload button will not work, because there is no bootloader and no serial port.

Minimal working example

// Siratek: proof of life on an ATtiny85. LED on chip pin 5.

const int ledPin = 0;         // PB0, which is chip pin 5

void setup() {
  pinMode(ledPin, OUTPUT);
}

void loop() {
  digitalWrite(ledPin, HIGH);
  delay(500);
  digitalWrite(ledPin, LOW);
  delay(500);
}

Note the pin number. 0 means PB0, which is physical pin 5. The two numbering schemes are unrelated, exactly as on the ATmega328P, and the table above is the translation.

If the blink is eight times too slow, the fuses are still at the factory 1 MHz. Burn Bootloader with the clock set to 8 MHz internal and try again.

Debugging without a serial port

This is the real adjustment. With no Serial.print(), you need other ways to see inside.

The LED is your output. A deliberate blink pattern says more than you would expect: one flash for state A, two for state B, a long flash for an error.

void signal(int times) {
  for (int i = 0; i < times; i++) {
    digitalWrite(ledPin, HIGH);
    delay(150);
    digitalWrite(ledPin, LOW);
    delay(150);
  }
  delay(600);                 // a gap, so the count is readable
}

Develop on an Uno first. Write and debug the logic with the serial monitor on a board that has one, then move the finished sketch to the ATtiny85 and change the pin numbers. That is faster than any amount of blink-counting, and it is what most people do.

Sleeping, which is the point of this chip

An ATtiny85 awake draws a few milliamps. Asleep, with the watchdog waking it periodically, it draws microamps. That is the difference between a coin cell lasting days and lasting a year.

#include <avr/sleep.h>
#include <avr/wdt.h>

ISR(WDT_vect) {
  // Nothing to do. Waking up is the whole job.
}

void sleepForEightSeconds() {
  // Watchdog as a wake-up timer rather than a reset.
  MCUSR = 0;
  WDTCR = _BV(WDCE) | _BV(WDE);
  WDTCR = _BV(WDIE) | _BV(WDP3) | _BV(WDP0);   // interrupt mode, 8 s

  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_enable();
  sleep_mode();                                 // sleeps here
  sleep_disable();
}

void loop() {
  digitalWrite(ledPin, HIGH);
  delay(50);
  digitalWrite(ledPin, LOW);

  sleepForEightSeconds();
}

A flash every eight seconds, with the chip drawing almost nothing in between. The same structure with a sensor reading instead of a flash is a battery project that runs for a season.

Note WDIE rather than WDE: interrupt mode wakes the chip, reset mode restarts it. Setting the wrong one gives you a chip that reboots every eight seconds, which looks similar and is not.

When to use this chip, and when not to

Use it when the job needs a handful of pins, the sketch is small, and the thing must be cheap, tiny or long-lived on a battery.

Do not use it when you need serial output in the field, more than about four pins, a display, or any library that was written assuming an Uno’s memory. The frustration of fitting a project into 512 bytes is rarely worth the saving over a Pro Mini.

Troubleshooting

Symptom Likely cause Check or fix
Blink eight times too slow Fuses still at 1 MHz Burn Bootloader at 8 MHz internal
“Not in sync” when programming Uno resetting itself 10 µF from Uno RESET to GND
Upload button does nothing useful No bootloader Use Upload Using Programmer
Nothing at all Decoupling capacitor missing 0.1 µF at pins 8 and 4
A pin does nothing Arduino number against physical pin PB0 is physical pin 5
Chip no longer programmable Reset disabled by a fuse Needs a high-voltage programmer
Sketch will not fit 8 KB of flash Remove a library, or use a bigger chip
Odd behaviour with a String 512 bytes of RAM Use fixed char buffers
Wakes but immediately restarts Watchdog in reset mode Use WDIE, not WDE
Software serial unreliable Internal oscillator accuracy Use an LED, or a crystal, or a bigger chip

Next steps

  • Easier first: Running an ATmega328P Without the Board, which this follows directly.
  • Related: Regulators, Batteries and Solar, for the coin cell this chip makes practical.
  • Next project: a dusk light: an LDR, an LED and this chip, asleep most of the time.

Sources and attribution

All text, wiring guidance and code in this tutorial are original Siratek work.

  • ATtiny85 datasheet for the pin functions, the memory sizes, the internal oscillator accuracy, the watchdog timer’s interrupt and reset modes and the sleep current.
  • Arduino documentation for the ArduinoISP sketch and Upload Using Programmer.
  • ATTinyCore documentation for the board definitions and clock options.

Siratek product 5695 is the 20PU variant, supplied as a bare DIP chip without a bootloader. Current figures are typical and depend on the clock, supply and sleep mode. No third-party tutorial text, diagrams, photographs or code has been reproduced here.

Product used in this tutorial: ATtiny85 20PU
Shop
Sidebar
0 Wishlist
0 Cart