Pulse Width Modulation (PWM) is a technique used to simulate an analog output using digital signals.
PWM is widely used in Arduino to control the brightness of LEDs, the speed of motors, and other applications requiring analog-like behavior.
This tutorial explains PWM in Arduino, its usage, and practical examples.
Table of Contents
1. What Is PWM?
PWM is a technique where a digital signal is turned on and off rapidly to simulate an analog output. The average voltage depends on the proportion of the “on” time (duty cycle) to the total cycle time.
Key Terms:
- Duty Cycle: Percentage of time the signal is “on.”
- 0%: Fully off.
- 50%: Half brightness/speed.
- 100%: Fully on.
- Frequency: Number of PWM cycles per second (measured in Hz).
2. How Does PWM Work?
PWM toggles a digital pin between HIGH (on) and LOW (off) at a high frequency. The human eye or connected device perceives the average output voltage based on the duty cycle.
For example:
- A 50% duty cycle on a 5V Arduino pin provides an average output of 2.5V.
3. PWM on Arduino
3.1 PWM Pins
PWM is available on specific pins marked with a ~ symbol on most Arduino boards.
Board | PWM Pins |
---|---|
Arduino Uno | 3, 5, 6, 9, 10, 11 |
Arduino Mega | 2-13, 44-46 |
Arduino Nano | 3, 5, 6, 9, 10, 11 |
3.2 analogWrite()
The analogWrite(pin, value) function generates a PWM signal on the specified pin.
Syntax:
analogWrite(pin, value);
- pin: PWM-capable pin.
- value: Duty cycle (0-255).
- 0: 0% duty cycle (off).
- 255: 100% duty cycle (fully on).
Example:
void setup() { pinMode(9, OUTPUT); // Configure pin 9 as output } void loop() { analogWrite(9, 127); // 50% duty cycle (half brightness) }
4. Practical Examples
4.1 Control LED Brightness
Control the brightness of an LED using analogWrite().
Circuit:
- Connect the positive leg of the LED to a PWM pin (e.g., pin 9) via a 220Ω resistor.
- Connect the negative leg to GND.
Code:
const int ledPin = 9; void setup() { pinMode(ledPin, OUTPUT); } void loop() { analogWrite(ledPin, 127); // Set LED to 50% brightness }
4.2 Control DC Motor Speed
Control the speed of a DC motor using a PWM pin and a motor driver (e.g., L298N).
Circuit:
- Connect the motor driver to a PWM pin (e.g., pin 10).
- Connect the motor to the motor driver’s output pins.
- Provide external power to the motor driver.
Code:
const int motorPin = 10; void setup() { pinMode(motorPin, OUTPUT); } void loop() { analogWrite(motorPin, 128); // Set motor speed to 50% delay(2000); analogWrite(motorPin, 255); // Set motor speed to 100% delay(2000); }
4.3 Fade an LED
Gradually increase and decrease the brightness of an LED to create a fading effect.
Code:
const int ledPin = 9; void setup() { pinMode(ledPin, OUTPUT); } void loop() { // Increase brightness for (int brightness = 0; brightness <= 255; brightness++) { analogWrite(ledPin, brightness); delay(10); // Wait 10ms } // Decrease brightness for (int brightness = 255; brightness >= 0; brightness--) { analogWrite(ledPin, brightness); delay(10); // Wait 10ms } }
5. Advanced PWM Control
5.1 Adjusting PWM Frequency
The default PWM frequency depends on the pin and the Arduino board. For applications like controlling motors, you may need to adjust the frequency.
Change Frequency Using Timers
Each PWM pin is tied to a timer. Modify the timer’s prescaler to change the PWM frequency.
Example:
Set a custom PWM frequency on pin 9 (Timer1 on Arduino Uno):
void setup() { pinMode(9, OUTPUT); // Set Timer1 frequency TCCR1B = TCCR1B & 0b11111000 | 0x01; // Set prescaler to 1 (fastest) } void loop() { analogWrite(9, 128); // 50% duty cycle }
6. Best Practices for Using PWM
- Use Appropriate Pins:
- Use pins with the ~ symbol for PWM output.
- Avoid Conflicts:
- PWM pins share timers. Ensure changes to timer settings do not interfere with other functionality (e.g., delay() or Servo library).
- Add a Resistor for LEDs:
- Use a resistor (e.g., 220Ω) in series with LEDs to limit current.
- Match Power Ratings:
- Ensure the connected device (e.g., motor) matches the PWM pin’s power limits or use a driver.
- Adjust Frequency for Motors:
- Lower frequencies are better for motor control to avoid whining noises.
Conclusion
PWM is a versatile feature in Arduino, enabling analog-like control over LEDs, motors, and other devices. Using the analogWrite() function, you can easily adjust the duty cycle to control brightness, speed, or intensity.
This tutorial covered the basics of PWM, practical applications, and tips for advanced control.
For more details, visit the official Arduino reference.