Arduino - Pulse Width Modulation
Arduino: Understanding Pulse Width Modulation (PWM)
Section titled “Arduino: Understanding Pulse Width Modulation (PWM)”Pulse Width Modulation (PWM) is a powerful technique for controlling analog devices with a digital signal. Instead of outputting a continuous analog voltage, PWM rapidly switches a digital pin between HIGH and LOW. The percentage of time the signal is HIGH is known as the duty cycle, which creates an average voltage, allowing you to achieve effects like dimming an LED or controlling the speed of a DC motor.
Core PWM Concepts
Section titled “Core PWM Concepts” HIGH |----------| |----------| | | | | LOW +----------+----------+----------+ <-- Ton ---><--Toff--><-- Ton ---> <------- Period ------>- On-Time (Ton): The duration the signal is HIGH.
- Off-Time (Toff): The duration the signal is LOW.
- Period: The total time for one cycle (Period = Ton + Toff). The inverse of the period is the PWM frequency.
- Duty Cycle: The percentage of the period that the signal is HIGH.
Duty Cycle = (Ton / Period) * 100%.
A 0% duty cycle means the signal is always LOW (0V average). A 100% duty cycle means it’s always HIGH (5V average). A 50% duty cycle means it’s HIGH for half the period, resulting in an average voltage of 2.5V.
The analogWrite() Function
Section titled “The analogWrite() Function”Arduino provides the analogWrite(pin, value) function to easily generate a PWM signal. You don’t need to call pinMode() before using it on a PWM pin.
Syntax
Section titled “Syntax”analogWrite(pin, value);pin: The PWM-capable pin you want to use. On an Arduino UNO, these are marked with a tilde~(pins 3, 5, 6, 9, 10, 11). Always check your board’s documentation for its PWM pins.value: The duty cycle, specified as an integer from0(0% duty cycle) to255(100% duty cycle).
The default PWM frequency on most Arduino boards is approximately 490 Hz, but some pins (e.g., 5 and 6 on the UNO) run at 980 Hz. More advanced boards like the ESP32 offer configurable PWM frequencies.
Example Project: Fading an LED with a Potentiometer
Section titled “Example Project: Fading an LED with a Potentiometer”This classic example demonstrates how to read an analog value from a potentiometer and use it to control the brightness of an LED via PWM.
Components & Wiring
Section titled “Components & Wiring”- 1 × Arduino UNO
- 1 × Potentiometer (any value, 10kΩ is common)
- 1 × LED
- 1 × 220Ω Resistor
// Potentiometer WiringPotentiometer Pin 1 --- Arduino GNDPotentiometer Pin 2 (Wiper) --- Arduino Analog Pin A0Potentiometer Pin 3 --- Arduino 5V
// LED WiringArduino PWM Pin ~9 --- [220Ω Resistor] --- [LED Anode (+)]Arduino GND --- [LED Cathode (-)]Code with map() Function
Section titled “Code with map() Function”The analogRead() function returns a value from 0-1023, but analogWrite() needs a value from 0-255. We can use the handy map() function to scale the input range to the output range.
/** * @file pwm_potentiometer_control.ino * @brief Controls LED brightness with a potentiometer using PWM. * @author Modernized Tutorial */
constexpr int LED_PIN = 9; // Must be a PWM pin (~)constexpr int POT_PIN = A0; // Potentiometer input pin
void setup() { // No pinMode needed for LED_PIN when using analogWrite. // No pinMode needed for analog input pins. Serial.begin(9600);}
void loop() { // 1. Read the value from the potentiometer (0 to 1023) int potValue = analogRead(POT_PIN);
// 2. Map the 10-bit analog input range (0-1023) to the // 8-bit PWM output range (0-255). int pwmValue = map(potValue, 0, 1023, 0, 255);
// 3. Write the mapped value to the LED pin. analogWrite(LED_PIN, pwmValue);
// Optional: Print values to Serial Monitor for debugging. Serial.print("Potentiometer: "); Serial.print(potValue); Serial.print("\t PWM Value: "); Serial.println(pwmValue);
delay(10); // Small delay for stability}Beyond LEDs: Other PWM Applications
Section titled “Beyond LEDs: Other PWM Applications”PWM is incredibly versatile:
- DC Motor Speed Control: By using a motor driver IC (like an L298N or TB6612), you can use PWM to control the effective voltage sent to a motor, thus controlling its speed.
- Servo Motor Control: The Arduino
Servolibrary uses PWM signals to tell a servo motor which angle to move to. - Generating Tones: The
tone()function uses PWM to create sounds of different frequencies with a buzzer or speaker.