Pulse Width Modulation (PWM) is a powerful technique used in electronics to control the amount of power delivered to devices such as motors and LEDs. With Arduino, PWM makes it possible to easily adjust motor speed or LED brightness with just a few lines of code. In this post, we’ll explore what PWM is, how it works, and how you can use it to control motors and LEDs with your Arduino.
1. What is PWM?
PWM, or Pulse Width Modulation, is a method of varying the width of pulses in a signal to control the amount of power delivered to an electronic device. Instead of varying the voltage, PWM rapidly turns the power on and off, with the “on” time relative to the “off” time determining the overall power level.
Understanding Duty Cycle
The key concept in PWM is the duty cycle, which represents the proportion of time that the signal is high (on) in each cycle. The duty cycle is expressed as a percentage:
- 0% Duty Cycle: The signal is always off (no power delivered).
- 50% Duty Cycle: The signal is on half the time and off half the time (half power).
- 100% Duty Cycle: The signal is always on (full power).
By adjusting the duty cycle, you can control how much power is delivered to a device, making it possible to dim LEDs or control motor speed with precision.
2. How PWM Works on Arduino
Arduino has built-in support for PWM on certain digital pins. These pins generate a square wave signal, which you can modify using the analogWrite()
function to adjust the duty cycle.
PWM-Capable Pins on Arduino
On most Arduino boards, the PWM-capable pins are marked with a ~
symbol next to the pin number. For example, on an Arduino Uno, pins 3, 5, 6, 9, 10, and 11 can be used for PWM.
Using the analogWrite()
Function
To control the duty cycle on a PWM pin, you use the analogWrite(pin, value)
function, where:
- pin is the PWM-capable pin you want to control.
- value is an integer between 0 and 255, representing the duty cycle (0 = 0% duty cycle, 255 = 100% duty cycle).
3. Controlling LED Brightness with PWM
Let’s start by using PWM to control the brightness of an LED.
Components Needed:
- Arduino board (e.g., Arduino Uno)
- LED
- Resistor (220Ω)
- Breadboard and jumper wires
Circuit Setup:
- Connect the longer leg (anode) of the LED to a PWM-capable pin (e.g., pin 9) through a 220Ω resistor.
- Connect the shorter leg (cathode) of the LED to the ground (GND) on the Arduino.
Code Example:
int ledPin = 9; // PWM-capable pin
void setup() {
pinMode(ledPin, OUTPUT); // Set the LED pin as output
}
void loop() {
for (int brightness = 0; brightness <= 255; brightness++) {
analogWrite(ledPin, brightness); // Increase brightness
delay(10); // Small delay for smooth transition
}
for (int brightness = 255; brightness >= 0; brightness--) {
analogWrite(ledPin, brightness); // Decrease brightness
delay(10); // Small delay for smooth transition
}
}
Explanation:
This code gradually increases and then decreases the brightness of the LED by changing the duty cycle from 0 to 255 and back. The analogWrite()
function adjusts the duty cycle, and the LED’s brightness changes smoothly as a result.
4. Controlling Motor Speed with PWM
PWM is also widely used to control the speed of DC motors, making it possible to adjust the motor speed without the need for complex circuitry.
Components Needed:
- Arduino board
- DC motor
- NPN transistor (e.g., 2N2222)
- Diode (e.g., 1N4007)
- Resistor (1kΩ)
- External power supply (e.g., 9V battery)
- Breadboard and jumper wires
Circuit Setup:
- Connect the collector of the NPN transistor to one terminal of the DC motor.
- Connect the other terminal of the DC motor to the positive terminal of the external power supply.
- Connect the emitter of the transistor to the ground of the external power supply.
- Place a diode across the motor terminals, with the cathode connected to the positive terminal (to protect against back EMF).
- Connect a 1kΩ resistor between the base of the transistor and the PWM-capable pin (e.g., pin 9) on the Arduino.
- Connect the ground of the Arduino to the ground of the external power supply.
Code Example:
int motorPin = 9; // PWM-capable pin
void setup() {
pinMode(motorPin, OUTPUT); // Set the motor pin as output
}
void loop() {
for (int speed = 0; speed <= 255; speed++) {
analogWrite(motorPin, speed); // Increase motor speed
delay(20); // Small delay for smooth transition
}
for (int speed = 255; speed >= 0; speed--) {
analogWrite(motorPin, speed); // Decrease motor speed
delay(20); // Small delay for smooth transition
}
}
Explanation:
In this code, the speed of the DC motor is gradually increased and then decreased by adjusting the duty cycle of the PWM signal sent to the transistor’s base. The transistor acts as a switch, controlling the motor speed based on the PWM signal from the Arduino.
5. Practical Applications of PWM
PWM is an incredibly versatile technique with a wide range of applications beyond controlling LEDs and motors. Some practical examples include:
- Dimming Lights: PWM can be used to create dimmable lighting systems.
- Servo Motor Control: PWM is used to control the position of servo motors in robotics.
- Audio Signal Generation: PWM can be used to generate tones for buzzers or simple audio output.
- Power Management: PWM is employed in power supply circuits for efficient voltage regulation and power control.
6. Conclusion
Pulse Width Modulation (PWM) is a powerful tool in your Arduino toolkit, enabling you to control the power delivered to various devices with precision. Whether you’re dimming an LED, adjusting the speed of a motor, or generating signals, PWM provides a flexible and efficient way to manage power in your projects. By understanding and experimenting with PWM, you can add a new level of control and sophistication to your electronic designs.
Happy tinkering!