Pulse Width Modulation (PWM) finds a place in numerous applications in the field of embedded systems, robotics and all kinds of automation; be it process control, home automation or industrial automation. PWM signal is basically a digital pulse train signal. The use of PWM signals ranges all the way from basic LED dimming circuits to complex control systems. In the scope of this article, we shall be touching upon some of the more basic applications such as controlling LED brightness.
To begin with, let us go over some concepts that provide intuitive insight into the core concepts behind the working of PWM.
Duty Cycle
Duty cycle refers to the ratio of on time of the signal to the total time period of the signal. As with any signal, we first define a base frequency of the signal. On this signal, the time for which it is high and low is modulated to change the duty cycle.
Shown below are three different signals with duty cycles of 75%, 50% and 25%. The value of duty cycle of a PWM signal decides the equivalent DC level of the signal.
The resultant DC level of the signal is calculated by the formula given below.
Where Vdc is the net DC level of the PWM signal. DC is the duty cycle of the PWM signal (from 0 to 1) and Vi is the voltage level of the PWM signal. For example, if we consider a 5v PWM signal, at 25% duty cycle the net DC voltage will be 0.25*5 which is 1.25 volts.
PWM on Raspberry Pi
Moving onto the Raspberry Pi, the circuit diagram below shows the connections to be made for the LEDs.
The following image shows all the pins which are available to be configured and used as PWM pins.
Code for Controlling LED Brightness:
import time
import RPi.GPIO as GPIO
ledPin1=18
ledPin2=12
GPIO.setmode(GPIO.BCM)
GPIO.setup(ledPin1, GPIO.OUT)
GPIO.setup(ledPin2, GPIO.OUT)
p1 = GPIO.PWM(ledPin1, 50)
p2 = GPIO.PWM(ledPin2, 50)
p1.start(0)
p2.start(0)
try:
GPIO.output(ledPin,GPIO.HIGH)
while True:
for dc in range(0, 101):
p1.ChangeDutyCycle(dc)
p2.ChangeDutyCycle(100-dc)
time.sleep(0.1)
for dc in range(100, -1):
p1.ChangeDutyCycle(dc)
p2.ChangeDutyCycle(100-dc)
time.sleep(0.1)
except KeyboardInterrupt:
pass
p1.stop()
p2.stop()
GPIO.cleanup()
Demonstration for controlling Bot Speed: