What is Pulse Width Modulation (PWM)?

Pulse Width Modulation (PWM) is a technique used in electronics to control the amount of power delivered to a device by varying the width of the pulses in a digital signal. In simpler terms, PWM allows you to control the "average" voltage or power supplied to a device by turning the signal on and off at a rapid pace. The proportion of time that the signal is high (on) versus low (off) is known as the duty cycle.

PWM is particularly useful in situations where you need to simulate an analog output using a digital system, like a microcontroller. For instance, you can use PWM to dim an LED, control the speed of a motor, or generate audio signals. Because most microcontrollers, including Arduino, operate on digital signals, PWM becomes essential in providing a way to mimic analog behavior.

How Does PWM Work?

To understand how PWM works, consider a simple LED circuit. If you apply a constant 5V to the LED, it will light up at full brightness. However, if you rapidly switch the 5V on and off, the LED's brightness will depend on how long the voltage is on versus off in each cycle. If the LED is on for half the time and off for the other half, it will appear to be at half brightness. This ratio of on-time to the total time of the cycle is the duty cycle.

Duty Cycle: The duty cycle is usually expressed as a percentage. A 100% duty cycle means the signal is on all the time (full power), while a 0% duty cycle means the signal is off all the time (no power). A 50% duty cycle means the signal is on for half the time, delivering half the power.

Frequency: The frequency of the PWM signal is how often the signal repeats in one second. Higher frequencies mean the signal switches on and off more rapidly. In most Arduino applications, the frequency is set to a default value, but it can be adjusted if needed.

Understanding PWM on Arduino

The Arduino microcontroller comes with several built-in PWM pins that you can be used to generate PWM signals. These pins are marked with a ~ symbol on the board, indicating their PWM capability.

On the Arduino Uno, the PWM-capable pins are: Pin 3 Pin 5 Pin 6 Pin 9 Pin 10 Pin 11 Each of these pins can output a PWM signal using the analogWrite() function. The Arduino Uno has a default PWM frequency of approximately 490 Hz on most pins, and 980 Hz on pins 5 and 6. This frequency can be altered if needed, but for most applications, the default is sufficient.

How PWM works on Arduino?

The Arduino generates PWM signals by toggling the output pin between high (5V) and low (0V) states at a high frequency. The duty cycle is controlled by the duration of the high state within each cycle. For example, if the duty cycle is set to 50%, the pin is high for half of the cycle and low for the other half, resulting in an average voltage of 2.5V. If the duty cycle is set to 25%, the pin is high for a quarter of the cycle, resulting in an average voltage of 1.25V.

Using analogWrite() Function

The analogWrite() function is used to generate a PWM signal on the Arduino. The syntax is as follows:

analogWrite(pin, value);
  • pin: The PWM-capable pin where the signal is to be generated.
  • value: An integer between 0 and 255 that represents the duty cycle. A value of 0 corresponds to a 0% duty cycle (always off), while 255 corresponds to a 100% duty cycle (always on). For example, to set a 50% duty cycle on pin 9, you would write: analogWrite(9, 128);

Controlling the Brightness of an LED using the PWM on Arduino UNO

Hardware Requirements

  • Arduino UNO R3
  • LED 5mm diameter
  • 220 ohm, ¼ watt Resistance
  • 100 ohm, ¼ watt Resistance
  • 10k-ohm POT
  • Breadboard
  • 25 Connection wires

Code

#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 6, 7, 8, 9);
#define DUTYCYCLE_PIN A0
#define LED_PIN 3
void setup() {
  // Set up the LED pin as an output
  pinMode(LED_PIN, OUTPUT);
  // set up the LCD's number of columns and rows
  lcd.begin(16, 2);
  // set the cursor to (column = 0,row = 0)
  lcd.setCursor(0, 0);
  lcd.print("Duty Cycle :");
}
void loop() {
  // Read the value from the potentiometer
  int potValue = analogRead(DUTYCYCLE_PIN);
  // Map the potentiometer value to the range of PWM (0-255)
  int PWM_Value = map(potValue, 0, 1023, 0, 255);
  // Update the LED brightness (duty cycle)
  analogWrite(LED_PIN, PWM_Value);
  // Map the PWM_Value value to the range of DutyCycle (0-100)
  int dutyCycle = map(PWM_Value, 0, 255, 0, 100);
  // Print the Duty Cyle on the LCD
  lcd.setCursor(0, 1);
  lcd.print(dutyCycle);
  lcd.print(" %   ");
  // Delay to stabilize readings
  delay(100);
}

Built With

Share this project:

Updates