IoTSimulator

Blink an LED with an ATtiny85

Connect a red LED and a resistor to an ATtiny85 microcontroller and watch it blink on and off once per second. This is the first project everyone does with a new chip — simple, satisfying, and a solid foundation for everything else.
Muhammad Ichsanul Fadhil
IoTSim Editor
September 20, 2026
Blink an LED with an ATtiny85

Live project track

Interactive hardware & logic preview

Every microcontroller project starts here. Blink an LED, confirm the chip is alive, confirm the wiring is right, confirm the code uploaded — then move on to bigger things. It sounds simple, but making a light blink on command is the moment a chip stops being a piece of plastic and starts doing something useful. The ATtiny85 is a tiny 8-pin chip, and this is the first thing you should build with it.

In this project, you will connect a red LED and a 220Ω resistor to an ATtiny85 microcontroller and program it to blink once per second. The main ideas are two: a resistor is always needed to protect the LED from too much current, and the chip's PB0 pin (physical pin 5) is called pin 0 in your code.

Why the LED Needs a Resistor

An LED is not a light bulb — it does not naturally limit how much current flows through it. If you connect an LED directly to 5V without a resistor, current rushes through unchecked and the LED burns out in seconds. The 220Ω resistor sits in the path of that current and slows it down to a safe level, around 14 milliamps, which is bright enough to see clearly but low enough to protect both the LED and the ATtiny85 pin that is driving it.

Current path from ATtiny85 PB0 through resistor to LED and back to GND
Current path from ATtiny85 PB0 through resistor to LED and back to GND

The diagram shows how voltage is shared across the circuit. The total supply is 5V. The resistor uses up 3V of that, leaving 2V across the LED — exactly what a standard red LED needs. Think of it like a pipe with a narrow section in the middle: the narrow part (the resistor) controls how fast water (current) flows through the whole pipe.

ComponentVoltage usedWhat it does
220Ω Resistor3.0VSlows current to a safe ~14 mA
Red LED2.0VConverts current into light
Total5.0VFull supply voltage accounted for

If you ever swap the LED for a different color, the voltage it needs changes slightly — blue and white LEDs use about 3.0–3.3V instead of 2V. The same 220Ω resistor still works fine for a beginner project, though the LED will be slightly dimmer.

Understanding the ATtiny85 Pins

The ATtiny85 has 8 physical pins, but only 6 of them are usable as inputs or outputs (two are power and ground). The chip is small enough to hold between two fingers, but it has everything needed to run a full program. The most important thing to understand before wiring is that the physical pin numbers on the chip and the pin numbers you type in your code are different.

ATtiny85 DIP-8 pinout showing physical pin numbers and Arduino code pin names
ATtiny85 DIP-8 pinout showing physical pin numbers and Arduino code pin names

The diagram above shows the chip with its notch at the top. Physical pin 5 (bottom-right) is called PB0 in hardware terms, but in your Arduino code you refer to it simply as pin 0. Physical pin 4 (bottom-left) is GND — this is the negative return for everything in the circuit. You do not type a number for GND in your code; the chip handles that connection automatically.

Physical pinNameCode pinUsed in this project
Pin 4GND—✅ Ground (LED return path)
Pin 5PB00✅ LED output signal
Pin 8VCC—✅ 5V power supply
Pins 1–3, 6–7PB1–PB51–5Unused in this project

When wiring the circuit, hold the chip with the notch at the top. Pins 1–4 run down the left side, and pins 5–8 run up the right side. Your LED connects from pin 5 (through the resistor) down to pin 4 — physically right next to each other on the chip.

Connecting the Circuit

The wiring is three connections: the ATtiny85 output to the resistor, the resistor to the LED anode, and the LED cathode back to GND. The resistor is not polarized — either end can face the chip. The LED is polarized — the longer leg (anode) faces the resistor, and the shorter leg (cathode) faces GND.

Pin Connection Map
LED + Resistor
220Ω Lead 1
→
ATtiny85
PB0 (Pin 5)
Explanation
Receives the HIGH/LOW signal from the chip. Resistor limits current to ~14 mA.
LED + Resistor
220Ω Lead 2 → LED Anode (+)
→
ATtiny85
In series
Explanation
Current flows from resistor directly into the LED's anode (longer leg).
LED + Resistor
LED Cathode (−)
→
ATtiny85
GND (Pin 4)
Explanation
Ground return. Current exits the LED here and flows back to the chip.

A common beginner mistake is plugging the LED in backwards. If the LED does not light up and everything else looks correct, try flipping the LED around. The flat edge on the LED body and the shorter leg both mark the cathode (negative) side.

Complete Code

The sketch below is the full program. It is eight lines of actual logic — short enough to read in one glance and understand completely.

C++ Source
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// ATtiny85 LED Blink
// Turns an LED on for 500ms then off for 500ms, repeating forever

const int LED_PIN = 0;        // PB0, Physical Pin 5
const int BLINK_INTERVAL = 500; // milliseconds on / off

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

void loop() {
  digitalWrite(LED_PIN, HIGH); // LED on
  delay(BLINK_INTERVAL);
  digitalWrite(LED_PIN, LOW);  // LED off
  delay(BLINK_INTERVAL);
}

How the Code Works, Part by Part

Even though the sketch is short, each line has a specific purpose. Understanding what each line does gives you the building blocks for every other ATtiny85 project.

▸ The Two Constants

LED_PIN = 0 gives the number a readable name so you never have to remember that pin 0 means physical pin 5. BLINK_INTERVAL = 500 sets the on/off time in milliseconds. Changing this one number changes the blink speed everywhere in the program at once — set it to 100 for a fast flicker, or 2000 for a slow two-second pulse.

C++ Source
1
2
const int LED_PIN = 0;          // PB0, Physical Pin 5
const int BLINK_INTERVAL = 500; // milliseconds on / off

Using named constants instead of raw numbers is a good habit even in small programs. If you add a second LED on a different pin later, you add a second constant with a clear name rather than hunting through the code for bare numbers.

▸ setup() — Runs Once at Startup

pinMode(LED_PIN, OUTPUT) tells the ATtiny85 to configure pin 0 as an output, meaning the chip will drive it either HIGH (5V) or LOW (0V). Without this line, the pin defaults to an input and digitalWrite() would have no effect.

C++ Source
1
2
3
void setup() {
  pinMode(LED_PIN, OUTPUT);
}

setup() runs exactly once when the chip powers on or resets. Everything you put here happens before the main loop begins. For this project, one line is all it needs.

▸ loop() — Runs Forever

After setup() finishes, the chip jumps into loop() and stays there forever, repeating it from top to bottom continuously. The four lines inside do: turn LED on → wait 500ms → turn LED off → wait 500ms → repeat. The delay() function pauses the chip for the given number of milliseconds while holding the pin at whatever level it was last set to.

C++ Source
1
2
3
4
5
6
void loop() {
  digitalWrite(LED_PIN, HIGH); // LED on
  delay(BLINK_INTERVAL);
  digitalWrite(LED_PIN, LOW);  // LED off
  delay(BLINK_INTERVAL);
}
Square wave timing diagram showing 500ms ON and 500ms OFF blink pattern
Square wave timing diagram showing 500ms ON and 500ms OFF blink pattern

The diagram shows what the output signal looks like over time. The pin switches between 5V and 0V in a perfectly regular rhythm, once per second. Each HIGH phase is 500ms (the LED is on), each LOW phase is 500ms (the LED is off), and the whole cycle takes exactly 1 second.

Fixing Common Problems

If the LED does not blink as expected, the table below covers the most likely causes.

What you seeLikely causeWhat to try
LED stays completely offLED is wired backwards (cathode facing resistor)Flip the LED around — longer leg faces the resistor
LED stays always onWrong pin number in code (e.g. wrote 5 instead of 0)Use 0 for PB0, not the physical pin number 5
Blink is 8× too slow (4 sec instead of 0.5 sec)ATtiny85 running at 1 MHz instead of 8 MHzIn Arduino IDE → Tools → Clock: select Internal 8 MHz and burn bootloader
Very dim glow, barely visibleWrong resistor value — might be 220 kΩ instead of 220ΩCheck resistor color bands: Red–Red–Brown–Gold = 220Ω

The clock speed issue is extremely common for ATtiny85 beginners. The chip ships from the factory running at 1 MHz with a clock divider turned on, which makes every delay(500) feel like delay(4000). Burning the bootloader with 8 MHz selected fixes it permanently.

Try It in the Simulator

Click Start Simulation (▶) in the toolbar. The red LED on the canvas will immediately begin blinking — on for half a second, off for half a second. Try editing BLINK_INTERVAL in the code panel: change it to 100 and restart to see a rapid flicker, or 2000 for a slow two-second pulse. The simulator responds instantly to code changes.

Keywords
#ATtiny85 #AVR #LED #Blink #Beginner #DIP-8 #Embedded
Total word count: 1343 words

Project discussion

Questions, feedback, and community insights
No discussions yet. Be the first to start!