How to use soft PWM in RPi.GPIO 0.5.2a pt 2 – led dimming and motor speed control
In part 1 of this series, we looked at the basic commands for using software pulse-width modulation (PWM) in RPi.GPIO 0.5.2a and higher. In this article we’ll get a bit more hands-on and into some practical applications for it. It’s all very well being able to make nice square-wave pulses on an oscilloscope, but what’s it actually useful for?
Our servo said? EEEEH AAAAH
I tried using RPi.GPIO soft PWM with servos in response to a query after the last article, but, although it did change the servo positions, it was jittery. Servos require quite precise PWM inputs. These appear to be better suited to hardware PWM solutions (or lower level programming languages). So we’ll leave servos for now and concentrate on controlling the brightness of leds and simple brushed motor speed control.
The idea here is that you can switch an led on and off very fast and trick the eye into thinking it’s on all the time. Most people can see flickering at or below about 50 Hertz (50 times per second). I remember the “good old days” of CRT monitors. I used to prefer one with a refresh rate of at least 72 Hz to avoid eye strain and headaches. So let’s pick an arbitrary number above 50 Hz, but not too high. Let’s say 100 Hz. That gives us a frequency, which we will leave as it is throughout the program.
Dimming leds using duty cycle
Remembering from last time, the duty cycle is the percentage of time the pulse is “ON”. 🙂
We will vary the duty cycle to get our variable brightness. A duty cycle value of 0 means fully off, 100 is fully on. Anything in between gives a proportion of full brightness. (Well that’s what your eye thinks. It actually gives full brightness for a proportion of the time.)
The led dimming circuit
Before we can do anything we have to hook it all together. Your leds may need different value resistors than mine, so check.
We have the +ve ends of: a white led connected to GPIO 25; a red led to GPIO 24. White gets a 330R resistor (it’s a superbright led) from -ve to GND. Red gets 56R (diagram shows 68R, which would also be fine) from -ve to GND. GND on the breadboard is connected to pin 6 GND on the Pi.
These leds are taking their power straight from the Pi’s GPIO ports, which is why I’m being careful to restrict the current drawn by my superbright white led.
In the program below, we are running a couple of loops which change the duty cycles of red and white leds, such that when one is 100, the other is 0. The first loop (lines 27-30) cycles up to 100 and the second one (31-34) cycles down from 100 to 0 (both from the white led’s point of view).
Those two loops are enclosed in a
while True: loop (lines 26-34) that will keep going until you hit
CTRL+C. And that
while True: loop is inside a
try: ... Except KeyboardInterrupt: block that will stop the PWM, clean up the GPIO ports we opened and exit gracefully when we do hit CTRL+C.