Modify PWM through button presses
Learn to control LED brightness using Pulse Width Modulation (PWM) by button presses on a Raspberry Pi
Written by: Jonathan Tynan
Last updated: Apr 27 2024
In this tutorial, we bring all the previous lessons together. We are reading button presses and will use these readings to modify the brightness of an LED by changing the PWM duty cycle. This tutorial brings together digital pin reading, writing and PWM modification. This is a simple demonstration of how to integrate various physical components and get them working with each other.
Components
See Blink LED Tutorial for more details on these components.
- Breadboard
- LED
- 220 Ω Resistor
- Jumper Wires
See Read Button Press Tutorial for more details on these components:
- 2 Push Buttons
The Circuit
Below we can see the circuit diagram for this project. First we have the Raspberry Pi ground connected to the ground rail of the breadboard and a 3.3V pin connected to the power rail of the bread board. We then have an LED which is connected to the ground rail and to Pin 11 through a 220 Ω resistor. Next we have 2 buttons, where both are connected to the powered rail on the breadboard and the otherside of the buttons are connected to pins 13 and 29.
The Code
Below is an example program that will detect button presses to increase or decrease the brightness of an LED.
Okay, now lets break down this code and look at its sections.
-
Above is where we are setting up the variables that we’re going to need.
brightness
which we are giving an inital value of 128 which is 50% of our maximum, 255. We are also settinglast_read_time
to 0 andread_interval
to 400. We are using this to implement a simple debounce technique, in which we wait a certain amount of time (the interval) in a non-blocking manner. -
Now we do our GPIO setup, where we call
raspi_init
and define the pins we are using. -
Next, we setup our individual pins. We’re going to write to the
led_pin
so we’re setting that to output, and then we’re setting its dutycycle to our initial brightness setting. Then we set our buttons to be inputs and set the pull-down resistors on them so that they are no longer floating and we can be sure they readLOW
when not pressed. -
So we can debounce our buttons we’ll create timers and a variable to hold the current time. Like in previous tutorials, we define how our program is going to end to ensure cleanup. In this case we are opening up our dummy window and watching for any key presses.
-
Above we have the main part of the code, the inside of the while loop. At the start of every loop we are getting the current time from
timer_ticks
. We are then checking if more time has elapsed since the last button read than the interval that we set earlier.If this is the case, then it’s time to check the buttons. We then read both buttons and if they’re high then we’ll either increase or decrease the brightness appropriately, set the duty cycle to this new brightness and record the last read time as the current time.
-
As usual once our program has run we cleanup all our resources and safely exit the program.
If we run this we should see an output like the following GIF.
Modifying PWM Range
As described in the previous tutorial, we can change the range of possible PWM values and have finer control over the brightness of the LED. In this tutorial, we use the typical PWM range of 0-255, but we could expand this to a higher resolution, like 1023, for more precise control of the exact brightness levels. Experiment with adjustments to the PWM range, modifying the parameters in your code, and observe how these changes affect the LED’s response to button presses. Each step increase in the PWM range will allow for more nuanced adjustments and provide smoother transitions between light levels. Conversely, a decrease in the PWM range will limit these transitions, and make each button press cause a more noticeable change in brightness.