Skip to Content

ATtiny85: Smooth PWM LED Fade Using analogWrite() on PB1

Learn how to generate PWM on the ATtiny85 to fade an LED smoothly.
May 12, 2026 by
ATtiny85: Smooth PWM LED Fade Using analogWrite() on PB1
Velxio

Introduction

Pulse-Width Modulation (PWM) is a fundamental technique for controlling analog-like outputs from digital pins. In this project, we'll use an ATtiny85 microcontroller to smoothly fade a yellow LED in and out. The LED is driven by analogWrite() on pin PB1, which corresponds to the OC0B output of Timer0. This example is perfect for beginners wanting to explore PWM on the ATtiny85 using the Arduino environment.

Circuit Walkthrough

The circuit is minimal:

  • Component: A yellow LED (ID: tiny-fade-led) with its anode connected to PB1.
  • Component: A 220 Ω resistor (ID: tiny-fade-r1) to limit current through the LED.
  • The LED cathode links to one end of the resistor; the other resistor terminal connects to GND.

Wiring details:

FromToColor
ATtiny85 PB1LED anode (A)Yellow (#ffcc00)
LED cathode (C)Resistor terminal 1Gray (#888888)
Resistor terminal 2ATtiny85 GNDBlack (#000000)

This forms a standard low-side drive: the microcontroller sources current through the LED and resistor to ground. The 220 Ω resistor is calculated for a forward voltage of ~2 V and current ~10 mA.

Code Walkthrough

The firmware is written in Arduino-style C++ and is straight forward. Let's break it down block by block.

// ATtiny85 — PWM LED fade on PB1 (OC0B / Timer0)
// analogWrite() uses Timer0 on the ATtiny85

void setup() {
  pinMode(1, OUTPUT);  // PB1 = OC0B (PWM capable)
}

void loop() {
  // Fade in
  for (int brightness = 0; brightness <= 255; brightness++) {
    analogWrite(1, brightness);
    delay(6);
  }
  // Fade out
  for (int brightness = 255; brightness >= 0; brightness--) {
    analogWrite(1, brightness);
    delay(6);
  }
  delay(200);
}

setup(): We set pin 1 (PB1) as an output. This pin is also the OC0B output for Timer0, enabling PWM.

loop(): The fade cycle runs continuously:

  • Fade in: A for loop increments brightness from 0 to 255. Each iteration calls analogWrite(1, brightness) which sets the PWM duty cycle. A delay(6) ms controls the speed.
  • Fade out: Another for loop decrements brightness from 255 down to 0.
  • After the fade-out, a delay(200) ms pause before repeating.

The analogWrite() function on the ATtiny85 uses Timer0 hardware to generate a PWM signal at approximately 1 kHz (default). The duty cycle is proportional to the value (0–255): 0 is fully off, 255 is fully on, and intermediate values give varying brightness.

Key Concepts

  • PWM (Pulse-Width Modulation): A digital signal that switches on and off at a high frequency. The average voltage (and hence brightness) is controlled by the duty cycle.
  • Timer0 on ATtiny85: The microcontroller has one 8-bit timer (Timer0) with two PWM outputs: OC0A (PB0) and OC0B (PB1). analogWrite() on pin 1 uses OC0B.
  • Current limiting resistor: LEDs must be used with a resistor to prevent excessive current. The 220 Ω resistor ensures safe operation.

Common Pitfalls & Debugging Tips

  • Wrong pin: Only PB1 (pin 1) supports PWM via analogWrite on most ATtiny85 cores. Double-check wiring.
  • Weak pull-ups: If the LED stays dim, ensure the resistor value is correct. Too high a resistance reduces brightness.
  • Timer conflicts: On ATtiny85, Timer0 is also used for delay() and millis(). Changing Timer0 prescaler may affect timing.
  • LED polarity: The anode (long leg) connects to PB1, cathode to resistor. Reversing polarity will prevent light.

Suggested Extensions

  • Add a potentiometer to control fade speed or target brightness.
  • Drive an RGB LED using three PWM pins (PB0, PB1, and maybe use software PWM on another pin).
  • Implement different fade patterns (e.g., sine wave, sawtooth).
  • Use interrupts to generate PWM without blocking the main loop.

Try It Yourself

Ready to see the LED fade? Open the live example on velxio.dev and run the simulation. Experiment with the code and component values to deepen your understanding of PWM on the ATtiny85.

ATtiny85 Button LED: Internal Pull-Up Fun
Learn to read a button and light an LED on the ATtiny85 using the built-in pull-up resistor.