Index
Introduction
Pulse Width Modulation (PWM) is a technique used to generate analog signals from digital outputs. By varying the width of the pulses (the duty cycle) sent to a component, you can control its behavior, such as the brightness of an LED or the speed of a motor. The ESP32 has dedicated hardware to handle PWM, making it a powerful tool for various projects.
Hardware
- ESP32 Development Board
- LED
- 220Ω Resistor
- Breadboard and Jumper Wires
- Power Supply or USB Cable
Understanding PWM on the ESP32
The ESP32 supports PWM through its LEDC (LED Control) peripheral, which allows you to control up to 16 PWM channels with different frequencies and resolutions. The duty cycle for each channel can be set from 0% to 100%, where 0% is fully off and 100% is fully on.
Configuring PWM Channels
- Choose a PWM-capable GPIO pin. Almost all GPIO pins on the ESP32 support PWM, except a few like GPIO 6 to 11 (used for flash).
- Select a PWM channel (0 to 15), frequency, and resolution.
Coding PWM on the ESP32
Basic PWM Example: LED Brightness Control
- Open the Arduino IDE and create a new sketch.
- Install the ESP32 Board Add-on if you haven’t already by going to Tools > Board > Board Manager and searching for “ESP32.”
- Copy and paste the following code:
const int ledPin = 18; // GPIO 18
const int pwmChannel = 0;
const int pwmFrequency = 5000; // 5 kHz
const int pwmResolution = 8; // 8-bit resolution (0-255)
void setup() {
// Configure PWM
ledcSetup(pwmChannel, pwmFrequency, pwmResolution);
// Attach PWM to GPIO
ledcAttachPin(ledPin, pwmChannel);
}
void loop() {
// Gradually increase brightness
for (int dutyCycle = 0; dutyCycle <= 255; dutyCycle++) {
ledcWrite(pwmChannel, dutyCycle);
delay(15);
}
// Gradually decrease brightness
for (int dutyCycle = 255; dutyCycle >= 0; dutyCycle--) {
ledcWrite(pwmChannel, dutyCycle);
delay(15);
}
}
This code will gradually increase and decrease the brightness of the LED, demonstrating how PWM controls the duty cycle.
PWM Frequency and Resolution Adjustments
- Frequency: Adjusting the frequency allows you to control the rate at which the PWM signal oscillates. A higher frequency results in a smoother signal, while a lower frequency may cause visible flickering in LEDs.
- Resolution: The resolution determines the granularity of the PWM signal. An 8-bit resolution gives you 256 levels of brightness, while a 10-bit resolution gives you 1024 levels.
const int pwmFrequency = 1000; // 1 kHz
const int pwmResolution = 10; // 10-bit resolution (0-1023)
Controlling Servo Motors with PWM
PWM can also control servo motors by adjusting the duty cycle to position the servo’s arm. Servo motors typically require a PWM signal with a frequency of around 50 Hz and a duty cycle between 2.5% and 12.5%.
Example code for controlling a servo motor:
#include <Servo.h>
Servo myServo;
const int servoPin = 18;
void setup() {
myServo.attach(servoPin);
}
void loop() {
for (int angle = 0; angle <= 180; angle++) {
myServo.write(angle);
delay(15);
}
for (int angle = 180; angle >= 0; angle--) {
myServo.write(angle);
delay(15);
}
}
Troubleshooting and Tips
- Check Connections: Ensure your circuit is connected correctly, with the LED and resistor in series.
- Correct GPIO Pin: Use a PWM-capable GPIO pin.
- Power Supply: Ensure the ESP32 is properly powered, either through USB or an external source.
- Frequency and Resolution: Experiment with different frequencies and resolutions to achieve the desired behavior.