Raspberry Pi PWM Tutorial

Published  May 13, 2016   12
Dilip Raja
Author
Raspberry Pi PWM Tutorial

Raspberry Pi is an ARM architecture processor based board designed for electronic engineers and hobbyists. The PI is one of most trusted project development platforms out there now. With higher processor speed and 1 GB RAM, the PI can be used for many high profile projects like Image processing and Internet of Things.

For doing any of high profile projects, one need to understand the basic functions of PI. We will be covering all the basic functionalities of Raspberry Pi in these tutorials. In each tutorial we will discuss one of functions of PI. By the end of tutorial series you will be able to do high profile projects by yourself. Check these for Getting Started with Raspberry Pi and Raspberry Pi Configuration.

 

We have discussed LED blinky and Button interface with Raspberry Pi in previous tutorials. In this Raspberry Pi PWM tutorial we will talk about getting PWM output with Raspberry Pi. PWM stands for ‘Pulse Width Modulation’. PWM is a method used for getting variable voltage out of constant power supply. We will generate PWM signal from  Raspberry PI and demonstrate the PWM by varying the Brightness of a LED, connected to Pi.

 

Pulse Width Modulation:

We have previously talked about PWM many times in: Pulse width Modulation with ATmega32 , PWM with Arduino Uno, PWM with 555 timer IC and PWM with Arduino Due.

pulse width modulation

In above figure, if the switch is closed continuously over a period of time, the LED will be ‘ON’ during this time continuously. If the switch is closed for half second and opened for next half second, then LED will be ON only in the first half second. Now the proportion for which the LED is ON over the total time is called the Duty Cycle, and can be calculated as follows:

Duty Cycle =Turn ON time/ (Turn ON time + Turn OFF time)

Duty Cycle = (0.5/ (0.5+0.5)) = 50%

So the average output voltage will be 50% of the battery voltage.

 

This is the case for one second and we can see the LED being OFF for half second and LED being ON the other half second. If Frequency of ON and OFF times increased from ‘1 per second’ to ’50 per second’. The human eye cannot capture this frequency. For a normal eye the LED will be seen, as glowing with half of the brightness. So with further reduction of ON time the LED appears much lighter.

We will program the PI for getting a PWM and connect a LED to show its working.

Raspberry Pi 2 Model B GPIO Layout

There are 40 GPIO output pins in Raspberry Pi. But out of 40, only 26 GPIO pins (GPIO2 to GPIO27) can be programmed. TO know more about GPIO pins, go through: LED Blinking with Raspberry Pi

 

Components Required:

Here we are using Raspberry Pi 2 Model B with Raspbian Jessie OS. All the basic Hardware and Software requirements are previously discussed, you can look it up in the Raspberry Pi Introduction, other than that we need:

  • Connecting pins
  • 220Ω or 1KΩresistor
  • LED
  • Bread Board

 

Circuit Explanation:

PWM with Raspberry pi fritzing circuit

As shown in the circuit diagram we are going to connect an LED between PIN35 (GPIO19) and PIN39 (ground). As said earlier, we cannot draw more than 15mA from any one of these pins, so to limit the current we are connecting a 220Ω or 1KΩ resistor in series with the LED.

 

Working Explanation:

Once everything is connected, we can turn ON the Raspberry Pi to write the program in PYHTON and execute it.

We will talk about few commands which we are going to use in PYHTON program.

We are going to import GPIO file from library, below function enables us to program GPIO pins of PI. We are also renaming “GPIO” to “IO”, so in the program whenever we want to refer to GPIO pins we will use the word ‘IO’.

import RPi.GPIO as IO

 

Sometimes, when the GPIO pins, which we are trying to use, might be doing some other functions. In that case, we will receive warnings while executing the program. Below command tells the PI to ignore the warnings and proceed with the program.

IO.setwarnings(False)

 

We can refer the GPIO pins of PI, either by pin number on board or by their function number. In pin diagram, you can see ‘PIN 35’ on the board is ‘GPIO19’. So we tell here either we are going to represent the pin here by ‘35’ or ‘19’.

IO.setmode (IO.BCM)

 

We are setting GPIO19 (or PIN35) as output pin. We will get PWM output from this pin.

IO.setup(19,IO.IN)

 

After setting the pin as output we need to setup the pin as PWM output pin,

p = IO.PWM(output channel , frequency of PWM signal)

The above command is for setting up the channel and also for setting up the frequency of the PWM signal. ‘p’ here is a variable it can be anything. We are using GPIO19 as the PWM output channel. ‘frequency of PWM signal’ has been chosen 100, as we don’t want to see LED blinking.

 

Below command is used to start PWM signal generation, ‘DUTYCYCLE’ is for setting the Turn On ratio, 0 means LED will be ON for 0% of time, 30 means LED will be ON for 30% of the time and 100 means completely ON.

p.start(DUTYCYCLE)

 

This command executes the loop 50 times, x being incremented from 0 to 49.

for x in range (50):

 

While 1: is used for infinity loop. With this command the statements inside this loop will be executed continuously.

With the program being executed, the duty cycle of PWM signal increases. And then decreases after reaching 100%.  With an LED attached to this PIN, brightness of LED increases first and then decreases.

Code

import RPi.GPIO as IO          #calling header file which helps us use GPIO’s of PI

import time                            #calling time to provide delays in program

IO.setwarnings(False)           #do not show any warnings

IO.setmode (IO.BCM)         #we are programming the GPIO by BCM pin numbers. (PIN35 as ‘GPIO19’)

IO.setup(19,IO.OUT)           # initialize GPIO19 as an output.

p = IO.PWM(19,100)          #GPIO19 as PWM output, with 100Hz frequency
p.start(0)                              #generate PWM signal with 0% duty cycle

while 1:                               #execute loop forever

    for x in range (50):                          #execute loop for 50 times, x being incremented from 0 to 49.
        p.ChangeDutyCycle(x)               #change duty cycle for varying the brightness of LED.
        time.sleep(0.1)                           #sleep for 100m second
      
    for x in range (50):                         #execute loop for 50 times, x being incremented from 0 to 49.
        p.ChangeDutyCycle(50-x)        #change duty cycle for changing the brightness of LED.
        time.sleep(0.1)                          #sleep for 100m second

Video

Have any question realated to this Article?

Ask Our Community Members

Comments

Submitted by Chad Tuinstra on Sat, 06/03/2017 - 08:05

Permalink

You mention "We are setting GPIO19 (or PIN35) as output pin." yet the code shows "IO.setup(19,IO.IN)". Later in the article it's correct.

Submitted by adam on Sat, 11/18/2017 - 05:38

Permalink

This worked as stated for me except my Pi 0 with stretch on it didn't like the comment characters so I just deleted those.

Submitted by Mirko on Mon, 11/20/2017 - 21:56

Permalink

I'm so happy I found your tutorial. It helped me a lot. Everything works fine. But I want to dim the LED constantly. When I keep running the loop it uses the CPU the whole time. Is there a way to dim the light and then stop the script? I couldn't solve this, but I'm a python beginner :)

Submitted by aRBemo on Sun, 03/25/2018 - 14:19

Permalink

I can forgive a typo once or twice but to refer to 'PYHTON' all the way through? What language is PYHTON i only know PYTHON!

Submitted by HS on Tue, 06/05/2018 - 00:41

Permalink

@Romain DLC, @aRBemo: don't be harsh on the author because of a few typos. He's taken his time to write this article and publish it for everyone to see. You can read the official rpi docs/code if typos bother you that much

Hi,

 

I've enjoyed your tutorial on PWM for Pi and wondered (1) Is PWM possible on the pixels of the Pi Sense HAT, and (2) if so, could you direct me to some code for that purpose?  I've reviewed the sense hat documentation and haven't found info on this subject, but it is certainly possible I've overlooked it.  

Thanks,

 

Mike