You don't have to remain confined to RGB values though. The FancyLED library in CircuitPython allows you to use HSV, or hue, saturation and value, to affect the NeoPixel strip's color.
The code is very similar to the NeoPixel library RGB code that we just looked at. The goals are still the same: have the pots control the three values that affect the NeoPixel strip's color (in this case HSV) and have these values display on the LCD in real time.
# SPDX-FileCopyrightText: 2018 Kattni Rembor for Adafruit Industries
#
# SPDX-License-Identifier: MIT
import time
import adafruit_character_lcd
import adafruit_fancyled.adafruit_fancyled as fancy
import board
import digitalio
import neopixel
from analogio import AnalogIn
lcd_rs = digitalio.DigitalInOut(board.D5)
lcd_en = digitalio.DigitalInOut(board.D6)
lcd_d7 = digitalio.DigitalInOut(board.D12)
lcd_d6 = digitalio.DigitalInOut(board.D11)
lcd_d5 = digitalio.DigitalInOut(board.D10)
lcd_d4 = digitalio.DigitalInOut(board.D9)
lcd_columns = 16
lcd_rows = 2
lcd = adafruit_character_lcd.Character_LCD(
lcd_rs, lcd_en, lcd_d4, lcd_d5, lcd_d6, lcd_d7, lcd_columns, lcd_rows
)
potH = AnalogIn(board.A0) # pot for hue
potS = AnalogIn(board.A1) # pot for saturation
potV = AnalogIn(board.A2) # pot for value
pixpin = board.D13 # NeoPixel pin
numpix = 8
strip = neopixel.NeoPixel(pixpin, numpix, brightness=1.0)
def val(pin):
# divides voltage (65535) to get a value between 0 and 1
return pin.value / 65535
def round_pot_h():
# rounds decimal value to 2 decimal places
return round(val(potH), 2)
def round_pot_s():
return round(val(potS), 2)
def round_pot_v():
return round(val(potV), 2)
while True:
# calls for HSV values
color = fancy.CHSV(val(potH), val(potS), val(potV))
# converts float HSV values to integer RGB values
packed = color.pack()
# writes converted int values to NeoPixels
strip.fill(packed)
lcd.set_cursor(3, 0)
# text at the top of the screen
lcd.message('H + S + V =')
lcd.set_cursor(1, 1)
# sends the rounded value and converts it to a string
lcd.message(str(round_pot_h()))
lcd.set_cursor(6, 1)
lcd.message(str(round_pot_s()))
lcd.set_cursor(11, 1)
lcd.message(str(round_pot_v()))
time.sleep(0.5)
# refreshes screen to display most recent pot values
lcd.clear()
The first change is the division of the analog voltage value by itself (pin.value / 65535) so that the minimum value read is 0 and the maximum is 1, since that is the range of HSV values.
Next, are the functions round_pot_h, round_pot_s and round_pot_v. These functions return a rounded number for the HSV values. Since HSV uses a decimal range between 0 and 1, the numbers can be very long in length, which won't fit on the LCD screen. Here, the numbers are being rounded to 2 decimal places so that all three HSV values can fit comfortably on the screen. However, you can easily change the number of decimal places to suit your needs.
In the loop, the HSV values are assigned to color, which is then converted from float HSV values to integer RGB values using pack() from the FancyLED library. These integer values are then written to the NeoPixel strip using strip.fill(packed) from the NeoPixel library.
For the LCD portion, the only big change from the NeoPixel RGB value code is that functions are being used and called to round the HSV values. This was done to avoid memory allocation issues.
Also, you'll notice that the values are not being converted to integers for the LCD. This is because although we need integers to write the colors to the NeoPixel strip, we want to see the float HSV values on the screen. Just like the RGB value code, the rounded HSV values are sent to the LCD as strings with str.
Page last edited January 21, 2025
Text editor powered by tinymce.