Analog I/O
Lesson 71: Using analogWrite() for PWM Output
Learn how analogWrite() controls PWM duty cycle for LED brightness and other variable-output tasks.
Progress indicator
Lesson 71 of 71
Learning Objectives
- Understand how analogWrite() generates PWM-style output.
- Learn duty cycle meaning and how brightness maps from 0-255.
- Know common PWM pin requirements and board differences.
- Build smooth fade logic with controlled step changes.
- Avoid common PWM mistakes in beginner Arduino projects.
Concept Explanation
What is analogWrite()
analogWrite() sets PWM output level on supported pins.
PWM rapidly switches pin HIGH/LOW so devices feel an average output value.
analogWrite() Syntax
analogWrite(pin, value);How analogWrite() Works
- Set PWM value for one output pin.
- Timer hardware generates high-frequency pulse waveform.
- Duty cycle changes according to PWM value.
- Device receives average energy based on duty cycle.
PWM Concept Explained
PWM is not true analog voltage output. It is fast digital pulsing where ON-time ratio controls perceived level.
Duty Cycle Basics
- 0% duty cycle: always LOW.
- 50% duty cycle: half cycle HIGH, half LOW.
- 100% duty cycle: always HIGH.
| analogWrite value | Approx duty cycle | LED feel |
|---|---|---|
| 0 | 0% | OFF |
| 128 | ~50% | Medium brightness |
| 255 | ~100% | Full brightness |
analogWrite() Value Range
Beginner-friendly range is usually 0-255. Lower values mean less ON-time.
PWM Pins on Arduino
PWM support depends on board and pin. Always check board pinout/docs for supported PWM pins.
When to Use analogWrite()
- LED dimming and visual indicators.
- Motor speed control via proper driver circuits.
- Output level modulation where full ON/OFF is too abrupt.
Example Code
This sketch fades LED brightness up and down using analogWrite() and step control.
const int LED_PIN = 2;
int brightness = 0;
int stepValue = 25;
void setup() {
pinMode(LED_PIN, OUTPUT);
Serial.begin(115200);
}
void loop() {
analogWrite(LED_PIN, brightness);
Serial.print("brightness=");
Serial.println(brightness);
brightness = brightness + stepValue;
if (brightness >= 255 || brightness <= 0) {
stepValue = -stepValue;
}
delay(120);
}Example Code Explanation
brightnessstores current PWM value.analogWrite(LED_PIN, brightness)applies that PWM level.brightness += stepValuemoves level up/down each cycle.- When brightness hits edges,
stepValuesign is inverted. - This makes smooth fade-in/fade-out loop.
- Serial logs help debug PWM transitions.
What Happens Inside
- CPU writes PWM compare value to output subsystem.
- Timer cycle runs continuously in background.
- Pin stays HIGH for duty portion, LOW for remainder.
- Human eye integrates pulses as brightness level.
- Loop updates compare value for animation effect.
Common Mistakes with analogWrite()
- Using pins that do not support PWM on target board.
- Passing invalid range values and expecting stable behavior.
- Using too large step changes causing flicker/jumps.
- Driving motors directly from MCU pin without proper driver.
Best Practices for analogWrite()
- Confirm PWM-capable pin before writing code.
- Use small step increments for smoother fades.
- Clamp values in valid range for predictable output.
- Print PWM values while tuning animations.
Try it now
Open the simulator workspace and observe PWM brightness values during fade cycles.