Code Along - Chapter 10

PWM & Fading

Dim an LED with analogWrite, fade it up and down, drive the brightness from a knob, and fade without blocking the sketch.

Estimated time 75-100 minExercises passed 0 / 6

Switching fast to fake the in-between

A digital pin is only ever fully on or fully off. PWM switches it on and off about 490 times a second, and the fraction of the time it spends HIGH - the duty cycle - decides how bright an LED looks.

analogWrite(pin, duty) takes a duty from 0 (off) to 255 (fully on). It only works on the pins marked ~ on the board: 3, 5, 6, 9, 10 and 11. On any other pin the simulator warns you, exactly as the real board would misbehave.

PWM waveforms at 25, 50 and 75 percent duty and the average power that results
Same voltage, different duty cycle - different average power.
Worked example

Four brightness steps

Watch the virtual LED: its glow follows the duty value, not just on and off.

const int LED = 9;

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

void loop() {
  analogWrite(LED, 0);      // off
  delay(500);
  analogWrite(LED, 64);     // quarter
  delay(500);
  analogWrite(LED, 128);    // half
  delay(500);
  analogWrite(LED, 255);    // full
  delay(500);
}

Turn on JavaScript to edit, run and test this code in the browser.

Exercise 10.1

Half brightness

Not started

Set the LED on pin 9 to half brightness (duty 128) and leave it there.

const int LED = 9;

void setup() {
  pinMode(LED, OUTPUT);
  // Set the LED to half brightness

}

void loop() {
}

Turn on JavaScript to edit, run and test this code in the browser.

Exercise 10.2

Three brightness steps

Not started

Step the LED through 64 → 128 → 255, 400 ms at each level, over and over. No other brightness values.

const int LED = 9;

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

void loop() {
  // 64, then 128, then 255 - 400 ms each

}

Turn on JavaScript to edit, run and test this code in the browser.

Exercise 10.3

Fade up

Not started

Fade the LED from off to full and start again: step the duty from 0 to 255 in steps of 5, waiting 20 ms at each step. Use a for loop.

const int LED = 9;

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

void loop() {
  // duty 0, 5, 10 ... 255 - analogWrite and wait 20 ms each time

}

Turn on JavaScript to edit, run and test this code in the browser.

Exercise 10.4

Breathing LED

Not started

Now fade up and back down, so the LED breathes. Keep the same steps of 5 and 20 ms waits: up from 0 to 255, then down from 255 to 0.

const int LED = 9;

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

void loop() {
  for (int duty = 0; duty <= 255; duty += 5) {
    analogWrite(LED, duty);
    delay(20);
  }

  // Now fade back down

}

Turn on JavaScript to edit, run and test this code in the browser.

Exercise 10.5

The knob dims the LED

Not started

Put Chapter 9 and this chapter together: read the potentiometer on A0 (0-1023) and use it to set the LED brightness (0-255). map() does the scaling. The test turns the knob while your sketch runs.

const int POT = A0;
const int LED = 9;

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

void loop() {
  // Read the knob, scale 0..1023 to 0..255, write it to the LED

}

Turn on JavaScript to edit, run and test this code in the browser.

Exercise 10.6

Fade without blocking

DeeperNot started

All that delay(20) means the sketch can do nothing else while it fades. Here the onboard LED must keep blinking every 500 ms - its timer is already written.

Fade pin 9 with a millis() timer instead: every 10 ms add 5 to the duty, and go back to 0 after 255. No delay().

const int LED = 9;
int duty = 0;
unsigned long lastStep = 0;

unsigned long lastBlink = 0;
bool blinkOn = false;

void setup() {
  pinMode(LED, OUTPUT);
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
  if (millis() - lastBlink >= 500) {
    lastBlink += 500;
    blinkOn = !blinkOn;
    digitalWrite(LED_BUILTIN, blinkOn);
  }

  // Every 10 ms: add 5 to duty, wrap back to 0 after 255, and write it

}

Turn on JavaScript to edit, run and test this code in the browser.

Try it on a real Uno

Put an LED and a 330 Ω resistor on pin 9 - it must be a ~ pin - and upload Breathing LED. Move it to pin 8 and upload again: it only switches fully on and off, which is what the simulator warns about.

Then add the potentiometer from Lesson 10 and upload The knob dims the LED.