
Lesson 3: PWM output
On the UNO R3, analogWrite() doesn’t produce a steady voltage between 0 and 5 V. It writes a PWM wave: the pin switches fully on and off, and the value you pass sets how much of the time it’s on1.
What you need
- Arduino UNO R3
- USB cable
- An LED and a current-limiting resistor
- The potentiometer from Lesson 2
- Jumper wires
Wire it, then check it
Run the LED and a resistor in series from pin 9 to GND, and keep the knob on A0 from Lesson 2. Each UNO R3 I/O pin is rated for 20 mA DC5.
Not working on a real board? Start with the wiring checklist.
Arduino version
l3-fade-arduino.ino// Lesson 3, Arduino version: the knob on A0 sets how
// bright the LED on pin 9 is.
void setup() {
pinMode(9, OUTPUT);
}
void loop() {
int reading = analogRead(A0); // 0 to 1023
analogWrite(9, reading / 4); // 0 to 255
}Register version
l3-fade-registers.ino// Lesson 3, register version: Timer1 drives pin 9 (OC1A)
// directly.
void setup() {
DDRB |= (1 << DDB1); // pin 9 (PB1, OC1A) is an output
// Non-inverting PWM on OC1A, 8-bit phase-correct (mode 1)
TCCR1A = (1 << COM1A1) | (1 << WGM10);
// Timer clock = 16 MHz / 64
TCCR1B = (1 << CS11) | (1 << CS10);
}
void loop() {
// Still read with analogRead: this lesson is about PWM
int reading = analogRead(A0);
OCR1A = reading / 4; // duty = OCR1A / 255
}Arduino’s startup code puts Timer1 in 8-bit phase-correct PWM with a prescaler of 64, using CS11 and CS103. This version writes the registers itself. In TCCR1A, COM1A1 clears the output when counting up past OCR1A and sets it when counting down, and WGM10 selects mode 1: phase-correct PWM with TOP = 255. The frequency is 16 MHz ÷ (2 × 64 × 255), about 490 Hz. OCR1A sets the share of time the pin is on, from always off at 0 to always on at 2552.
Registers in this lesson (ATmega328P data-space addresses)2
| Register | Address | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
|---|---|---|---|---|---|---|---|---|---|
| TCCR1A | 0x80 | COM1A1 | COM1A0 | COM1B1 | COM1B0 | – | – | WGM11 | WGM10 |
| TCCR1B | 0x81 | ICNC1 | ICES1 | – | WGM13 | WGM12 | CS12 | CS11 | CS10 |
| OCR1AL | 0x88 | bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0 |
Run it in the lab
At 1.25 V the reading is 256, OCR1A is 64, and the LED is on about 25% of the time2.
Drill
Why divide the reading by 4?
Show the answer
analogReadgives 0 to 1023;analogWritetakes 0 to 255. Arduino’s ownanalogWriteexample does the same division. 1What PWM frequency does pin 9 run at?
What does the pin do when OCR1A is 0 in this mode?
Show the answer
It stays LOW the whole time. In non-inverting phase-correct PWM, OCR1A at BOTTOM gives a continuously low output. 2
Sources
- Arduino reference: analogWrite
- Microchip ATmega328P datasheet DS40002061A: Timer1 PWM frequency (p135), extreme values (p136), Tables 16-3 and 16-4 (p141)
- ArduinoCore-avr, cores/arduino/wiring.c: Timer1 prescaler 64, 8-bit phase-correct PWM
- ArduinoCore-avr, variants/standard/pins_arduino.h: pin 9 is TIMER1A
- Arduino UNO R3 technical specifications: Clock speed: ATmega328P 16 MHz; DC Current per I/O Pin: 20 mA