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
.