Once you've gotten the board set up, click Download: Project Zip below in the code guide. Expand the .zip file and then drag these files to your CIRCUITPY Drive:
- rising.bmp
- sinking.bmp
- font (folder)
Libraries Needed:
- adafruit_apds9960
- adafruit_bitmap_font
- adafruit_bmp280.mpy
- adafruit_bus_device
- adafruit_clue.mpy
- adafruit_display_shapes
- adafruit_display_text
- adafruit_fancyled
- adafruit_imageload
- adafruit_lis3dh.mpy
- adafruit_lis3mdl.mpy
- adafruit_lsm6ds.mpy
- adafruit_register
- adaafruit_sht31d.mpy
- neopixel.mpy
When you're done, your CLUE's CIRCUITPY drive should look like this.
Code
Copy the code from the code-block above and paste it into the Mu editor and save it to your CLUE as code.py (or copy code.py from the zip file and place on the CIRCUITPY drive).
Don't make any changes yet! It's tempting to go ahead and add your num_leds variable or start customizing right away, but in this case, that may break the code. At first, just upload the code as-is to be sure you've got it everything installed as it should be.
# SPDX-FileCopyrightText: 2020 Erin St. Blaine for Adafruit Industries
#
# SPDX-License-Identifier: MIT
"""
Read the barometric reading in the air
Visualize air reading changes over time as a color animation on a NeoPixel strip
Display a "sinking" or "rising" graphic on the screen along with recent reading data
Code by Erin St Blaine for Adafruit Industries :)
"""
import time
import board
import neopixel
from adafruit_clue import clue
import adafruit_fancyled.adafruit_fancyled as fancy
import displayio
from adafruit_display_text import label
from adafruit_bitmap_font import bitmap_font
num_leds = 79 #number of LEDs in your strip
timeToCheck = 23400 # set the amount of time between sensor checks. 7800 is approx. 1 hour
# Barometer or Thermometer? Uncomment the section you want to use
#BAROMETER RANGES (hPa)
#set desired reading range -- the NeoPixel palette choice will be determined by these thresholds
deviceType = 0
min_reading = 960
med_reading = 965
high_reading= 970
max_reading = 975
"""
# THERMOMETER RANGES (C)
# set desired temperature range - NeoPixel palette choice determined by these thresholds
deviceType = 1
min_reading = 25
med_reading = 26
high_reading= 27
max_reading = 28
"""
# get an initial sensor reading
if deviceType ==0:
reading = clue.pressure
else:
reading = clue.temperature
#set up variables for "remembering" past readings
reading1 = reading
reading2 = reading1
reading3 = reading2
counter = 0
toggle = 1 # for on/off switch on button A
displayOn = 1 # to turn the display on and off with button B
button_b_pressed = False
button_a_pressed = False
clue.display.brightness = 0.8
clue_display = displayio.Group()
# draw the rising image
rising_bmp = displayio.OnDiskBitmap("rising.bmp")
rising_sprite = displayio.TileGrid(rising_bmp, pixel_shader=rising_bmp.pixel_shader)
clue_display.append(rising_sprite)
# draw the sinking image
sinking_bmp = displayio.OnDiskBitmap("sinking.bmp")
sinking_sprite = displayio.TileGrid(sinking_bmp, pixel_shader=sinking_bmp.pixel_shader)
clue_display.append(sinking_sprite)
# Create text
# first create the group
text_group = displayio.Group()
# Make a label
reading_font = bitmap_font.load_font("/font/RacingSansOne-Regular-29.bdf")
reading_font.load_glyphs("0123456789ADSWabcdefghijklmnopqrstuvwxyz:!".encode('utf-8'))
reading_label = label.Label(reading_font, color=0xffffff)
reading_label.x = 10
reading_label.y = 24
text_group.append(reading_label)
reading2_label = label.Label(reading_font, color=0xdaf5f4)
reading2_label.x = 10
reading2_label.y = 54
text_group.append(reading2_label)
reading3_label = label.Label(reading_font, color=0x4f3ab1)
reading3_label.x = 10
reading3_label.y = 84
text_group.append(reading3_label)
timer_label = label.Label(reading_font, color=0x072170)
timer_label.x = 10
timer_label.y = 114
text_group.append(timer_label)
clue_display.append(text_group)
clue.display.root_group = clue_display
# Define color Palettes
waterPalette = [0x00d9ff, 0x006f82, 0x43bfb9, 0x0066ff]
icePalette = [0x8080FF, 0x8080FF, 0x8080FF, 0x0000FF, 0xC88AFF]
sunPalette = [0xffaa00, 0xffdd00, 0x7d5b06, 0xfffca8]
firePalette = [0xff0000, 0xff5500, 0x8a3104, 0xffaa00 ]
forestPalette = [0x76DB00, 0x69f505, 0x05f551, 0x3B6D00]
# set up default initial palettes, just for startup
palette = forestPalette
palette2 = waterPalette
palette3 = icePalette
# Declare a NeoPixel object on pin A4 with num_leds pixels, no auto-write.
# Set brightness to max because we'll be using FancyLED's brightness control.
pixels = neopixel.NeoPixel(board.A4, num_leds, brightness=1.0,
auto_write=False)
offset = 0 # Positional offset into color palette to get it to 'spin'
while True:
# use button A to toggle the NeoPixels on or off by changing brightness
if clue.button_a and not button_a_pressed: # If button A pressed...
print("Button A pressed.")
if toggle == 1:
toggle = 0
pixels.brightness = 0
clue.display.brightness = 0
elif toggle == 0:
toggle = 1
pixels.brightness = 1.0
clue.display.brightness = 0.8
button_a_pressed = True # Set to True.
time.sleep(0.03) # Debounce.
if not clue.button_a and button_a_pressed: # On button release...
button_a_pressed = False # Set to False.
time.sleep(0.03) # Debounce.
if clue.button_b and not button_b_pressed: # If button B pressed...
print("Button B pressed.")
# Toggle only the display on and off
if displayOn == 0:
clue.display.brightness = 0.8
displayOn = 1
else:
clue.display.brightness = 0
displayOn = 0
button_b_pressed = True # Set to True.
time.sleep(0.03) # Debounce.
if not clue.button_b and button_b_pressed: # On button release...
button_b_pressed = False # Set to False.
time.sleep(0.03) # Debounce.
# assign color palette to NeoPixel section 1 based on the current reading reading
if reading1 < min_reading:
palette = firePalette
elif min_reading > reading1 > med_reading:
palette = sunPalette
elif med_reading > reading1 > high_reading:
palette = forestPalette
elif high_reading > reading1 > max_reading:
palette = waterPalette
else:
palette = icePalette
# Map colors to pixels. Adjust range numbers to light up specific pixels. This configuration
# maps to a reflected gradient, with pixel 0 in the upper left corner
# Load each pixel's color from the palette using an offset, run it
# through the gamma function, pack RGB value and assign to pixel.
for i in range(23, 31): #center right -- present moment
color = fancy.palette_lookup(palette, offset + i / num_leds)
color = fancy.gamma_adjust(color, brightness=0.25)
pixels[i] = color.pack()
for i in range(63, 71): #center left -- present moment
color = fancy.palette_lookup(palette, offset + i / num_leds)
color = fancy.gamma_adjust(color, brightness=0.25)
pixels[i] = color.pack()
for i in range(16, 23): #top mid right -- 1 cycle ago
color = fancy.palette_lookup(palette2, offset + i / num_leds)
color = fancy.gamma_adjust(color, brightness=0.25)
pixels[i] = color.pack()
for i in range(71, 78): #top mid left -- 1 cycle ago
color = fancy.palette_lookup(palette2, offset + i / num_leds)
color = fancy.gamma_adjust(color, brightness=0.25)
pixels[i] = color.pack()
for i in range(31, 38): #bottom mid right -- 1 cycle ago
color = fancy.palette_lookup(palette2, offset + i / num_leds)
color = fancy.gamma_adjust(color, brightness=0.25)
pixels[i] = color.pack()
for i in range(56, 63): #bottom mid left -- 1 cycle ago
color = fancy.palette_lookup(palette2, offset + i / num_leds)
color = fancy.gamma_adjust(color, brightness=0.25)
pixels[i] = color.pack()
for i in range(0, 16): #top right -- 2 cycles ago
color = fancy.palette_lookup(palette3, offset + i / num_leds)
color = fancy.gamma_adjust(color, brightness=0.25)
pixels[i] = color.pack()
for i in range(77, 79): #top left -- 2 cycles ago
color = fancy.palette_lookup(palette3, offset + i / num_leds)
color = fancy.gamma_adjust(color, brightness=0.25)
pixels[i] = color.pack()
for i in range(38, 56): #bottom -- 2 cycles ago
color = fancy.palette_lookup(palette3, offset + i / num_leds)
color = fancy.gamma_adjust(color, brightness=0.25)
pixels[i] = color.pack()
pixels.show()
offset += 0.01 # Bigger number = faster spin
reading_label.text = "Now {:.1f}".format(reading1)
reading2_label.text = "Last {:.1f}".format(reading2)
reading3_label.text = "Prev {:.1f}".format(reading3)
timer_label.text = "{}".format(counter)
clue.display.root_group = clue_display
# Is it time to update?
if counter > timeToCheck:
# This moves the current data to the "1 hour old" section of pixels and the "1 hour old"
# data to the "2 hours old" section of pixels
palette3 = palette2
palette2 = palette
reading3 = reading2
reading2 = reading1
reading1 = reading
# take a new sensor reading and reset the counter
if deviceType == 0:
reading = clue.pressure
else:
reading = clue.temperature
counter = 0
# if reading is rising, show rising image and position text at the bottom
if reading1 > reading2:
sinking_sprite.x = 300
reading_label.y = 134
reading2_label.y = 164
reading3_label.y = 194
timer_label.y = 224
# if reading is falling, show sinking image and position text at the top
elif reading1 < reading2: #reading is falling
sinking_sprite.x = 0
reading_label.y = 24
reading2_label.y = 54
reading3_label.y = 84
timer_label.y = 114
# otherwise keep counting up
else:
counter = counter + 1
Troubleshooting
If all goes well, your NeoPixels have come on in various colors and your screen is showing either a submarine image or a hot air balloon image, as well as a pressure readout. Hooray!
If that didn't happen, here are a few things to try:
- Double check that you have all the libraries shown above installed in your board's lib folder
- Make sure the fonts are installed in a folder called fonts at the root of your CIRCUITPY drive
- Check to be sure your .bmp files are both sitting at the root of your CIRCUITPY drive
- Try copying and saving code.py once more. Don't change anything in the code yet! Let's get it working as-is first.
If you're using the mu editor to load your code, click the Serial button to open the serial monitor, then press ctrl-D to enter the REPL. This will run your code line-by-line and give you a clue as to what is going wrong. More about this lovely debugging tool here
If your screen is showing images and text but your LEDs aren't lighting up:
- Double check your wiring. Is the white / data wire going to pin #2 and the black / ground wire going to G?
- Check to be sure you've connected to the IN end of your NeoPixel strip instead of the OUT end. It won't work if you hook them up backwards.
If you've checked all of this and it's still not working, try updating and reloading CircuitPython on the CLUE. Here are instructions about how to do that.
Page last edited January 22, 2025
Text editor powered by tinymce.