
Introduction to PWM
Pulse Width Modulation (PWM) is a technique in which the pulse width is adjusted while maintaining a constant wave frequency. This method allows a digital source to create an analog signal effectively.
PWM Generation
A PWM signal has two key components that determine its behavior: duty cycle and frequency.
What is the Duty Cycle of a Signal?
Each pulse period includes an ON phase (typically 5V) and an OFF phase (0V). The duty cycle represents the fraction of the period during which the signal is in the ON state.
For example, consider a pulse with a 10 ms period that stays ON (high) for 2 ms. The duty cycle is calculated as:
D=2ms/10ms=20%
Using the PWM technique, we can control the power delivered to a load by adjusting the ON-OFF signal. PWM signals are commonly used to control the speed of DC motors and adjust the brightness of LEDs.
Below are examples of Pulse Width Modulated signals with varying duty cycles.
Frequency of Signal
The frequency of a PWM signal defines how quickly it completes one cycle—meaning how fast it switches between ON (high) and OFF (low) states. For instance, a frequency of 1000 Hz means the signal completes 1000 cycles per second. When this ON-OFF pattern is repeated at a high enough frequency, the PWM signal can simulate a steady analog voltage based on the duty cycle, effectively delivering a constant output to connected devices.
Example: To generate a 2V analog signal from a digital source that can switch between 5V (high) and 0V (low), we can use PWM with a 40% duty cycle. This would output 5V for 40% of each cycle. When the signal cycles quickly enough, the average voltage seen at the output approximates an analog value. If the digital low is 0V (as is typical), the average voltage can be calculated as the digital high voltage multiplied by the duty cycle: ( 5\text{V} \times 0.4 = 2\text{V} ).
Now, let’s explore how to use PWM with Arduino.
PWM Pins of Arduino Uno
The Arduino Uno features six 8-bit PWM channels. Pins marked with the ‘~’ symbol indicate PWM support. The PWM-enabled pins are shown in the image below.
Arduino PWM Pin Details
Arduino Functions for PWM
analogWrite(pin, dutyCycle)
This function generates a PWM signal or outputs an analog value to a specified PWM pin.
- pin: The PWM-capable pin where the signal is generated.
- dutyCycle: A value from 0 (0% duty cycle, always OFF) to 255 (100% duty cycle, always ON).
LED Fading using Arduino PWM
Let’s create a simple application where an LED will continuously fade in and out. This LED fading effect is commonly used for decorative lighting during events and festivals.
LED Interfacing to Arduino Uno
LED Fading using Arduino
Sketch for LED fading using Arduino PWM
int led = 6; // the PWM pin the LED is attached to
int brightness = 0; // how bright the LED is
int fadeAmount = 5; // how many points to fade the LED by
void setup() {
pinMode(led, OUTPUT); // declare pwm pin to be an output:
}
void loop() {
analogWrite(led, brightness); // set the brightness of led
// change the brightness for next time through the loop:
brightness = brightness + fadeAmount;
// reverse the direction of the fading at the ends of the fade:
if (brightness <= 0 || brightness >= 255) {
fadeAmount = -fadeAmount;
}
delay(30); // wait for 30 milliseconds to see the dimming effect
}
Control LED Brightness using a Potentiometer
Let’s create an application to control LED brightness using an Arduino and a potentiometer. As the potentiometer knob is rotated, Arduino’s ADC will read the analog signal. A PWM signal, proportional to this analog input, will then be generated to adjust the LED’s brightness.
Interfacing Diagram
LED Brightness Control using potentiometer with Arduino
Code for controlling LED Brightness using arduino
int ledPin = 6; // LED connected to digital pin 9
int analogPin = A0; // potentiometer connected to analog pin 3
int val = 0; // variable to store the read value
void setup()
{
pinMode(ledPin, OUTPUT); // sets the pin as output
}
void loop()
{
val = analogRead(analogPin); // read the input pin
analogWrite(ledPin, val / 4);// analogRead values go from 0 to 1023, analogWrite values from 0 to 255
}
For more implementation, you can visit