Small Jobs on an ATtiny85
| Difficulty | Advanced |
|---|---|
| Category | Foundations |
| Supported boards | ATtiny85, programmed from an Arduino Uno |
| Time needed | 60 minutes |
| Prerequisites | Running an ATmega328P Without the Board |
| Tested board | Not yet verified |
| Tested on | Not yet verified |
| Arduino IDE version | Not yet verified |
| Library | Not 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
Stringand it is gone. - No I2C or SPI hardware, though the
TinyWirelibraries 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 |
Wiring steps
- Seat the ATtiny85 on the breadboard, notch to the left. Pin 1 is bottom left.
- Pin 8 to the positive rail, pin 4 to the negative rail.
- 0.1 µF capacitor between pins 8 and 4, right at the chip.
- LED and 220 ohm resistor from pin 5 to ground.
- Upload ArduinoISP to the Uno, from File, Examples.
- Then fit the 10 µF capacitor between the Uno’s
RESETandGND. - 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.

