The BLM badge comes with six side-lit RGB NeoPixel LEDs and four capacitive touch pads. This CircuitPython example combines those two features to create touch controlled rainbow LEDs. All the hardware needed for this example is built-in to the BLM Badge, so no soldering or external components are necessary!
This section will walk you through loading the necessary CircuitPython libraries, then provide and explain a code example for touch controlled LEDs. You should have already installed CircuitPython on your board and have a CIRCUITPY drive available on your computer.
CircuitPython Library Installation
For this example, you'll need to copy two libraries to your BLM badge: NeoPixel and Adafruit Pypixelbuf.
First, download the Adafruit CircuitPython Library Bundle from circuitpython.org. Open the resulting file, and then open the lib folder contained within.
Find the following files:
- adafruit_pypixelbuf.mpy
- neopixel.mpy
Copy the two files listed above to the lib folder on your CIRCUITPY drive.
Before you continue, make sure that the lib folder on your CIRCUITPY drive contains the adafruit_pypixelbuf.mpy and neopixel.mpy files.
# SPDX-FileCopyrightText: 2021 Kattni Rembor for Adafruit Industries # # SPDX-License-Identifier: MIT import time import board import touchio import digitalio import neopixel from rainbowio import colorwheel pixels = neopixel.NeoPixel(board.NEOPIXEL, 6, auto_write=False) red_led = digitalio.DigitalInOut(board.D13) red_led.direction = digitalio.Direction.OUTPUT cap1 = touchio.TouchIn(board.CAP1) cap2 = touchio.TouchIn(board.CAP2) cap3 = touchio.TouchIn(board.CAP3) cap4 = touchio.TouchIn(board.CAP4) pixels.fill((255, 0, 0)) pixels.show() mode = 0 touched_4 = False color_value = 1 while True: if cap1.value and mode == 0: # Touch pad 1 to increase the brightness. pixels.brightness += 0.05 pixels.show() time.sleep(0.15) if cap2.value and mode == 0: # Touch pad 2 to decrease the brightness. pixels.brightness -= 0.05 pixels.show() time.sleep(0.15) if cap3.value and mode == 0: # Touch pad 3 to cycle through a rainbow of colors on the NeoPixels. color_value = (color_value + 1) % 255 pixels.fill(colorwheel(color_value)) pixels.show() if cap4.value and not touched_4: # Touch pad 4 to "disable" the other pads. mode += 1 if mode > 1: mode = 0 touched_4 = True time.sleep(0.05) if not cap4.value and touched_4: # This prevents pad 4 from spamming mode changes. touched_4 = False time.sleep(0.05) if mode == 0: # The little red LED is off when pads 1-3 are "enabled". red_led.value = False if mode == 1: # The little red LED is on when pads 1-3 are "disabled". red_led.value = True
First you import the necessary libraries and modules. Note that there are modules being imported that you did not need to copy to the lib folder in the previous step. That's because those modules are built-in to CircuitPython.
Next is the hardware set up. This example uses the NeoPixels, the little red LED and the four capacitive touch pads, so you initialise these towards the beginning of your code.
Then, you turn the pixels on red, and set up three variables needed later in the code for various reasons. The fourth pad swaps between two modes, 0 and 1, so mode
begins at 0
. Tracking whether the fourth pad has been touched begins with touched_4 = False
. Finally, the color_value
variable is used to cycle through the rainbow, and begins as 1
.
Inside the loop, you check whether each pad was touched and what the mode is, and then do an action based on that information. There's a bit more detail to it than that, so it's best to break it down.
First, you check whether the first capacitive touch pad is touched, and if it is, AND the mode is 0, you increase the brightness of the LEDs by 0.05
. Brightness is a value between 0 and 1. If brightness is already 1, nothing will happen. There is a time.sleep(0.15)
to slow down the touch response a bit so you can more easily control the brightness.
Second, you check whether the second capacitive touch pad is touched, and if it is, AND the mode is 0, you decrease the brightness of the LEDs by 0.05
. If the brightness is already 0, nothing will happen. The same sleep()
is included here as well.
Third, you check whether the third capacitive touch pad is touched, and if it is, AND the mode is 0, you fill the NeoPixel LEDs in a rainbow cycle. As you touch the pad, the LEDs will cycle from red to green to blue and back to red.
The fourth pad toggles whether the other three are "active" or not. When you touch it the first time, the little red LED will turn on indicating that the other pads will not respond. It does this by setting mode = 1
. Remember for the other three pads, we check whether the mode is equal to 0 before we perform the associated action. So, when the mode is set to 1, the other three pads do nothing when touched. This way you can set your LEDs to the color and brightness you want, and touch the fourth pad to "freeze" it in that state. To be able to change those settings again, touch the fourth pad again. The little red LED will turn off, indicating the other three pads are now responsive again.
When you touch a touch pad, it sends an input signal. That signal happens very quickly, and without any modification to the code, the board will receive multiple signals when you think you are only touching it once. This is desirable with regards to the rainbow cycle - you want it to continue to cycle through the colors as you touch the pad. However, if we left the fourth pad code unmodified, it would send multiple signals every time you touched it, and that means it would cycle back and forth through the two modes multiple times every time you attempted to change the mode. You'd struggle to end up in the mode you were aiming for. Using touched_4
to track the touch state prevents the signal spamming from happening.
The first section of code involving the fourth pad checks to see if the fourth pad has been touched AND touched_4 = False
, and if both are valid, it adds 1 to the mode. mode
begins at 0
, so the first time you touch the pad, it changes it to 1
. The second time you touch the pad, mode
is already 1
, which means mode
is increased to 2
. Since we are only dealing with two modes, 0 and 1, it checks to see if mode is greater than 1, and if so, sets it back to 0. This is how it toggles between two modes. Then, it sets touched_4 = True
. This means that if cap4.value and not touched_4
is no longer valid, so it doesn't try to execute the code beneath it. That is how it prevents the code from spamming mode changes.
The second section of code involving the fourth pad checks to see if the fourth pad is not being touched AND that touched_4
is True
. Remember, at the end of the last section of code, we set touched_4 = True
. That means, when you remove your finger from the pad and stop touching it, this section of code will run. It sets touched_4
back to False
to reset the tracking. Now you can touch the fourth pad again to run the previous section of code and switch modes. The code ensures that you can only switch modes one at a time!
Finally, if mode
is 0
, meaning the first three touch pads are "enabled", the little red LED is turned off. If mode
is 1
, meaning the first three touch pads are "disabled", the little red LED is turned on.
That's what goes into creating a touch controlled rainbow NeoPixel LED project using CircuitPython and the BLM badge!
To turn the brightness up, touch the first capacitive touch pad (the one closest to the lanyard clip).
To toggle reactivity on the first three touch pads, touch the fourth pad. The first time you touch it, it stops the other pads from reacting (note in the image, the rainbow doesn't cycle when the third pad is touched after the fourth pad). When you touch it again, it "re-enables" the reactivity of the other three pads. Handy for when you find a color and brightness you like, and want it to stay there!
Text editor powered by tinymce.