Unit B - Inputs & Outputs

11. PWM, millis() & State Machines

Control average power while several tasks run together.

Estimated time 4 hours

Learning outcomes

  • Explain PWM duty cycle
  • Use analogWrite on Uno PWM pins
  • Replace long delays with millis timing
  • Implement a simple state machine

Parts and preparation

Uno, LED, 330 ohm resistor and potentiometer.

Before power: inspect wiring, confirm supply voltage and ensure all connected circuits share GND.

PWM, millis() & State Machines instructional connection diagram
Open the diagram for a larger view. Trace every connection before building.

PWM

Pulse-width modulation switches rapidly between LOW and HIGH. Duty cycle is the percentage of time HIGH. It controls average LED brightness or a drivers average load power; it is not a true analogue voltage.

Uno PWM

analogWrite uses values 0-255 on PWM-capable pins 3, 5, 6, 9, 10 and 11. A load still needs an appropriate driver.

Non-blocking time

delay stops the sketch from doing other work. Compare millis with a saved timestamp to schedule tasks while loop keeps running.

State machine

A state variable records the current phase. Events and timers decide when to move to another state.

Wiring and safe build sequence

Breadboard wiring for lesson 11: PWM, millis() & State Machines
Breadboard layout for this lesson. Match colours and pins before powering the circuit. Click the image for a larger view.
  1. D9 -> 330 ohm -> LED anode
  2. LED cathode -> GND
  3. Potentiometer wiper -> A0; outer legs -> 5 V and GND
Power rule: switch off before moving wires. Arduino I/O pins are control signals; high-current loads require a driver and suitable external supply.
const byte ledPin = 9;
unsigned long lastReport = 0;

void setup() {
  pinMode(ledPin, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  int raw = analogRead(A0);
  byte brightness = map(raw, 0, 1023, 0, 255);
  analogWrite(ledPin, brightness);

  if (millis() - lastReport >= 500) {
    lastReport = millis();
    Serial.println(brightness);
  }
}

How the code works

  1. LED response remains immediate because no delay blocks loop.
  2. The report task runs only every 500 ms.

Test and record evidence

Expected result: The potentiometer smoothly controls brightness while Serial reports twice per second.

Practical evidence checklist

Common faults and checks
  • Use a pin marked ~ for PWM.
  • Do not connect a motor in place of the LED without a driver and flyback protection.
Extension challenge: Create traffic-light states with separate durations using one state variable and millis.

Check your understanding

Q1. Is PWM a true analogue output?

Show answer

No; it is a digital pulse train with variable duty cycle.

Q2. Why prefer millis for multi-task programs?

Show answer

It schedules work without stopping the rest of loop.