Pi Pico Micropython, 2 button, brightness and patterns, not functioning as expected

Hi All I have attempted to merge 2 pieces of code using 2 buttons.
Button 1 is for Brightness.
Button 2 is for the patterns.
In this basic first design (just so it’s not too complicated) the animation modes(button 2) gives simple different colours.
Button 1 will only control red which is how the brightness code originally started out. In doing this now (because I have merged 2 pieces of code, the leds will turn red at the specified brightness of button 1(when pushed) and the shell will show the percentage brightness.
The leds will then return to whichever (current_mode) colour has been selected using button 2

What I am trying to achieve is for the whole strip or ring to still be color/pattern controlled with button 2 and for button 1 to change the brightness for whichever colour /pattern is showing at the time.
code below
any assistance greatly appreciated
cheers
Nick

import neopixel
from machine import Pin
import time

# NeoPixel setup
PIXEL_PIN = 0 # Example pin, adjust as needed
NUM_PIXELS = 24 # Number of NeoPixels
np = neopixel.NeoPixel(Pin(PIXEL_PIN), NUM_PIXELS)
#pixels = neopixel.NeoPixel(Pin(NEOPIXEL_PIN), NUM_PIXELS)


# Button setup
BUTTON1_PIN = 14 # to change brightness
BUTTON2_PIN = 15 # to change patterns
button1 = Pin(BUTTON1_PIN, Pin.IN, Pin.PULL_UP)
button2 = Pin(BUTTON2_PIN, Pin.IN, Pin.PULL_UP)

brightness_levels = [0.05, 0.1, 0.3, 0.6, 1.0] # Example brightness levels
current_brightness_index = 0

# Define colors (RGB tuples)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
PINK = (250, 0  ,250)
ORANGE = (255, 50, 0)
OFF = (0, 0, 0)

colors = [RED, GREEN, BLUE, OFF]
current_color_index = 0

def set_all_pixels_color(r, g, b, brightness):
    for i in range(NUM_PIXELS):
        np[i] =(int(r * brightness), int(g * brightness), int(b * brightness))
    np.write()

# Initial state
set_all_pixels_color(255, 0, 0, brightness_levels[current_brightness_index])

# Set initial color
np.fill(colors[current_color_index])
np.write()

current_mode = 0
num_modes = 6 # Adjust based on your number of animation functions

last_button_state = True # True for unpressed (pull-up)
last_debounce_time = 0
DEBOUNCE_DELAY = 50 # milliseconds


def set_all_pixels_color(r, g, b, brightness):   # this is meant to enable brightness control
    for i in range(NUM_PIXELS):
        np[i] = (int(r * brightness), int(g * brightness), int(b * brightness))
    np.write()

def animation_mode_0():    #set_all_pixels_color
    # Example: Solid Red
    for i in range(NUM_PIXELS):
        np[i] = (255, 0, 0)
    np.write()

def animation_mode_1():    #set_all_pixels_color
    # Example: Solid Blue
    for i in range(NUM_PIXELS):
        np[i] = (0, 0, 255)
    np.write()

def animation_mode_2():    # Example: Rainbow cycle (simplified, needs more logic for smooth animation)
    for i in range(NUM_PIXELS):
        np[i] = (0, 255, 0) # Green 
    np.write()


def animation_mode_3():     
    for i in range(NUM_PIXELS):
        np[i] = (250, 0, 250) # Pink
        np.write() 

def animation_mode_4():  #set_all_pixels_color
    # Example: Rainbow cycle (simplified, needs more logic for smooth animation)
    for i in range(NUM_PIXELS):
        np[i] = (250, 55, 0) # Orange 
    np.write()

def animation_mode_5():  #set_all_pixels_color
    # Example: Rainbow cycle (simplified, needs more logic for smooth animation)
    for i in range(NUM_PIXELS):
        np[i] = (0, 0, 0) # Off
    np.write()
    
    
animations = [animation_mode_0, animation_mode_1, animation_mode_2, animation_mode_3, animation_mode_4,animation_mode_5 ]


while True:
#     #brightness
#     if button1.value() == 0:  # Button pressed
#         time.sleep_ms(50)  # Debounce
#         if button1.value() == 0: # Confirm press after debounce
#             current_brightness_index = (current_brightness_index + 1) % len(brightness_levels)
#             set_all_pixels_color(255, 0, 0, brightness_levels[current_brightness_index])
#             print(f"Brightness set to: {brightness_levels[current_brightness_index] * 100}%")
#             while button1.value() == 0: # Wait for button release
#                 time.sleep_ms(10)
#     time.sleep_ms(10) # Small delay for main loop
    
   #brightness
    if button1.value() == 0:  # Button pressed
        time.sleep_ms(50)  # Debounce
        if button1.value() == 0: # Confirm press after debounce
            current_brightness_index = (current_brightness_index + 1) % len(brightness_levels)
            set_all_pixels_color(255, 0, 0, brightness_levels[current_brightness_index])      
            print(f"Brightness set to: {brightness_levels[current_brightness_index] * 100}%")
            while button1.value() == 0: # Wait for button release
                time.sleep_ms(10)
    time.sleep_ms(10) # Small delay for main loop
    
    
     # Button   2  colour change                      polling and debouncing
    current_button2_state = button2.value()
    if current_button2_state == False and last_button2_state == True: # Button pressed
        if (time.ticks_ms() - last_debounce_time) > DEBOUNCE_DELAY:
            current_mode = (current_mode + 1) % num_modes
            last_debounce_time = time.ticks_ms()
    last_button2_state = current_button2_state
    
    # Execute current animation mode
    animations[current_mode]()

    # Short delay to prevent busy-waiting too intensely, adjust as needed
    time.sleep_ms(10)
#time.sleep_ms(10) # Small delay to prevent busy-waiting
#       # pattern change    
#     if button2.value() == 0:  # Button is pressed (pulled low)
#         time.sleep_ms(50)  # Debounce delay
#         if button2.value() == 0:  # Confirm button press after debounce
#             current_color_index = (current_color_index + 1) % len(colors)
#             np.fill(colors[current_color_index])                         
#             np.write()
#             while button2.value() == 0:  # Wait for button release
#                 time.sleep_ms(10)
#         time.sleep_ms(10) # Small delay to prevent busy-waiting



Hi folks
I don’t know whether the solution to my query is too difficult or not .

I would have hoped someone might have an answer because if it’s really obvious I am totally unable to see it.

That’s how my brain works. I have changed the code numerous times (10-20 at least) but I cannot solve it.
If it’s really difficult , that’s amazing and thanks for taking a look.
I have modified the code a little this morning

In lines at approx 32-35 I have changed the colour to yellow and extended the time so I can see the code roll through this point, and then at “animation_mode_0” I have reduced the brightness of red so I can see where the code stops.

Button 2 will still roll through the animation modes, button 1 will not change the brightness of the pixels. Where am I going wrong?
Thanks
Nick

import neopixel
from machine import Pin
import time

# NeoPixel setup
PIXEL_PIN = 0 # Example pin, adjust as needed
NUM_PIXELS = 24 # Number of NeoPixels
np = neopixel.NeoPixel(Pin(PIXEL_PIN), NUM_PIXELS)
#BRIGHTNESS = 0.5
#pixels = neopixel.NeoPixel(Pin(NEOPIXEL_PIN), NUM_PIXELS)
#np.brightness = BRIGHTNESS

# Button setup
BUTTON1_PIN = 14 # to change brightness
BUTTON2_PIN = 15 # to change patterns
button1 = Pin(BUTTON1_PIN, Pin.IN, Pin.PULL_UP)
button2 = Pin(BUTTON2_PIN, Pin.IN, Pin.PULL_UP)
#def animation_mode() = current_mode():
current_brightness = 8
#brightness_step = 32      # How much brightness changes per button press
# 
# last_button_state = True # Assuming PULL_UP, so True is released, False is pressed

# Initialize button with pull-up resistor
button1 = machine.Pin(BUTTON1_PIN, machine.Pin.IN, machine.Pin.PULL_UP)

#Brightness levels (0-255)
brightness_levels = [0, 8, 32, 64, 128, 192, 255]
current_brightness_index = 0

#Set initial brightness
np.brightness = brightness_levels[current_brightness_index]  #[animation_mode]
np.fill((50, 50, 0)) # Example: set all pixels to red
np.write()
time.sleep_ms(500)

last_button1_state = button1.value()



# brightness_levels = [0.05, 0.1, 0.3, 0.6, 1.0] # Example brightness levels
# current_brightness_index = 0

# Define colors (RGB tuples)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
PINK = (250, 0  ,250)
ORANGE = (255, 50, 0)
OFF = (0, 0, 0)

colors = [RED, GREEN, BLUE, PINK, ORANGE, OFF]
#current_color_index = 0

# def update_brightness():
#     global current_brightness
#     # Update all pixels with the current brightness and a specific color
#     for i in range(NUM_PIXELS):
#         # Example: set all pixels to red with current brightness
#         np[i] = ( (0 , 0, 0) current_brightness)
#      np.write() # or np.show() depending on your neopixel library version
# 
# #update_brightness() # Set initial brightness


current_mode = 0
num_modes = 6 # Adjust based on your number of animation functions

last_button_state = True # True for unpressed (pull-up)
last_debounce_time = 0
DEBOUNCE_DELAY = 50 # milliseconds


def animation_mode_0():    #set_all_pixels_color
    # Example: Solid Red
    for i in range(NUM_PIXELS):
        np[i] = (25, 0, 0)
    np.write()

def animation_mode_1():    #set_all_pixels_color
    # Example: Solid Blue
    for i in range(NUM_PIXELS):
        np[i] = (0, 0, 255)
    np.write()

def animation_mode_2():    # Example: Rainbow cycle (simplified, needs more logic for smooth animation)
    for i in range(NUM_PIXELS):
        np[i] = (0, 255, 0) # Green 
    np.write()


def animation_mode_3():     
    for i in range(NUM_PIXELS):
        np[i] = (250, 0, 250) # Pink
        np.write() 

def animation_mode_4():  #set_all_pixels_color
    # Example: Rainbow cycle (simplified, needs more logic for smooth animation)
    for i in range(NUM_PIXELS):
        np[i] = (250, 55, 0) # Orange 
    np.write()

def animation_mode_5():  #set_all_pixels_color
    # Example: Rainbow cycle (simplified, needs more logic for smooth animation)
    for i in range(NUM_PIXELS):
        np[i] = (0, 0, 0) # Off
    np.write()
    
    
animations = [animation_mode_0, animation_mode_1, animation_mode_2, animation_mode_3, animation_mode_4,animation_mode_5 ]


while True:
    #brightness
    current_button1_state = button1.value()

    if current_button1_state != last_button1_state:
        if current_button1_state == 0:  # Button pressed (assuming pull-up)
            current_brightness_index = (current_brightness_index + 1) % len(brightness_levels)
            np.brightness = brightness_levels [current_brightness_index]  #[ animation_mode]
            np.write()
            print(f"Brightness set to: {np.brightness}")

    last_button1_state = current_button1_state
    time.sleep_ms(200)  # Debounce delay
    
    
#     current_button1_state = button1.value()
# 
#     if current_button1_state == False and last_button_state == True: # Button pressed (assuming PULL_UP)
#         current_brightness += brightness_step
#         if current_brightness > 255:
#             current_brightness = 0 # Cycle brightness
#         update_brightness()
#         time.sleep_ms(200) # Debounce delay
# 
#     last_button1_state = current_button1_state
#     time.sleep_ms(10) # Small delay to prevent busy-waiting    
    
    
     # Button   2  colour change                      polling and debouncing
    current_button2_state = button2.value()
    if current_button2_state == False and last_button2_state == True: # Button pressed
        if (time.ticks_ms() - last_debounce_time) > DEBOUNCE_DELAY:
            current_mode = (current_mode + 1) % num_modes
            last_debounce_time = time.ticks_ms()
    last_button2_state = current_button2_state
    
    # Execute current animation mode
    animations[current_mode]()

    # Short delay to prevent busy-waiting too intensely, adjust as needed
    time.sleep_ms(10)



1 Like

Hi @Nicholas193967,

Firstly, in future, could you please remove the commented out code from the code you upload to the forum. I know it seems like a small thing, but it makes the code harder to navigate when there are a lot of commented out sections that you need to skip over.

I’m having a look at your code now but it’s a little hard to know why its not working with no diagnostic information. With your current setup, what is happening when you press Button1 and Button2. I presume the animations are still running when you press Button2?

Hi Jane
Thanks for taking a look .

A lot of the commented out code was left in because it was changes that I did try which I thought maybe should have worked and might still hold the solution .

I realize it makes it a little harder to read , but shows that I have tried different ways with no success.

When I push button 1 the shell shows/prints what brightness the pixels should be , but the pixels do not change brightness.

When I push button 2 the different animation modes light up correctly.

I have included code that I have cleaned up
cheers
Nick

import neopixel
from machine import Pin
import time

# NeoPixel setup
PIXEL_PIN = 0 # Example pin, adjust as needed
NUM_PIXELS = 24 # Number of NeoPixels
np = neopixel.NeoPixel(Pin(PIXEL_PIN), NUM_PIXELS)

BUTTON1_PIN = 14 # to change brightness
BUTTON2_PIN = 15 # to change patterns
button1 = Pin(BUTTON1_PIN, Pin.IN, Pin.PULL_UP)
button2 = Pin(BUTTON2_PIN, Pin.IN, Pin.PULL_UP)
#def animation_mode() = current_mode():
current_brightness = 8
#brightness_step = 32      # How much brightness changes per button press
# 


# Initialize button with pull-up resistor
button1 = machine.Pin(BUTTON1_PIN, machine.Pin.IN, machine.Pin.PULL_UP)

#Brightness levels (0-255)
brightness_levels = [0, 8, 32, 64, 128, 192, 255]
current_brightness_index = 0

#Set initial brightness
np.brightness = brightness_levels[current_brightness_index]  #[animation_mode]
np.fill((50, 50, 0)) # Example: set all pixels to red
np.write()
time.sleep_ms(500)

last_button1_state = button1.value()

# Define colors (RGB tuples)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
PINK = (250, 0  ,250)
ORANGE = (255, 50, 0)
OFF = (0, 0, 0)

colors = [RED, GREEN, BLUE, PINK, ORANGE, OFF]
#current_color_index = 0

current_mode = 0
num_modes = 6 # Adjust based on your number of animation functions

last_button_state = True # True for unpressed (pull-up)
last_debounce_time = 0
DEBOUNCE_DELAY = 50 # milliseconds


def animation_mode_0():    #set_all_pixels_color
    # Example: Solid Red
    for i in range(NUM_PIXELS):
        np[i] = (25, 0, 0)
    np.write()

def animation_mode_1():    #set_all_pixels_color
    # Example: Solid Blue
    for i in range(NUM_PIXELS):
        np[i] = (0, 0, 255)
    np.write()

def animation_mode_2():    # Example: Rainbow cycle (simplified, needs more logic for smooth animation)
    for i in range(NUM_PIXELS):
        np[i] = (0, 255, 0) # Green 
    np.write()


def animation_mode_3():     
    for i in range(NUM_PIXELS):
        np[i] = (250, 0, 250) # Pink
        np.write() 

def animation_mode_4():  #set_all_pixels_color
    # Example: Rainbow cycle (simplified, needs more logic for smooth animation)
    for i in range(NUM_PIXELS):
        np[i] = (250, 55, 0) # Orange 
    np.write()

def animation_mode_5():  #set_all_pixels_color
    # Example: Rainbow cycle (simplified, needs more logic for smooth animation)
    for i in range(NUM_PIXELS):
        np[i] = (0, 0, 0) # Off
    np.write()
    
    
animations = [animation_mode_0, animation_mode_1, animation_mode_2, animation_mode_3, animation_mode_4,animation_mode_5 ]


while True:
    #brightness
    current_button1_state = button1.value()

    if current_button1_state != last_button1_state:
        if current_button1_state == 0:  # Button pressed (assuming pull-up)
            current_brightness_index = (current_brightness_index + 1) % len(brightness_levels)
            np.brightness = brightness_levels [current_brightness_index]  #[ animation_mode]
            np.write()
            print(f"Brightness set to: {np.brightness}")

    last_button1_state = current_button1_state
    time.sleep_ms(200)  # Debounce delay
    
    
  # Button   2  colour change                      polling and debouncing
    current_button2_state = button2.value()
    if current_button2_state == False and last_button2_state == True: # Button pressed
        if (time.ticks_ms() - last_debounce_time) > DEBOUNCE_DELAY:
            current_mode = (current_mode + 1) % num_modes
            last_debounce_time = time.ticks_ms()
    last_button2_state = current_button2_state
    
    # Execute current animation mode
    animations[current_mode]()

    # Short delay to prevent busy-waiting too intensely, adjust as needed
    time.sleep_ms(10)




No worries, Nicholas, thanks for that. It makes it much easier.

The first thing that I am noticing is that this line in your while True loop:

np.brightness = brightness_levels [current_brightness_index] #[ animation_mode]

Has a space between the list name and the index. You’ll need to remove that.

Secondly, I’m seeing that you are assigning the brightness to the np object which is from the neopixel class for micropython. However, the neopixel class does not have a brightness setting, just RGB values adjusted up or down as shown from the neopixel library.

np[0] = (255, 0, 0) # set to red, full brightness
np[1] = (0, 128, 0) # set to green, half brightness
np[2] = (0, 0, 64)  # set to blue, quarter brightness

Unless I am missing something in your code, I can’t see any point where the brightness levels are actually affecting the RGB values used.

So, you would need a list of RGB values of all of your colours depending on brightness levels and move through the list of these values with the button press.

Hi Jane,
Thanks for your investigation.
I will have a look at your suggestion
Isn’t the code I’m attaching below assigning brightness to the “np” object and in this code the brightness will vary according to the values at line 14.
However this code only applies to one colour unfortunatly
cheers
Nick

import neopixel
from machine import Pin
import time

# NeoPixel setup
PIXEL_PIN = 0 # Example pin, adjust as needed
NUM_PIXELS = 24 # Number of NeoPixels
np = neopixel.NeoPixel(Pin(PIXEL_PIN), NUM_PIXELS)

# Button setup
BUTTON_PIN = 14 # Example pin, adjust as needed
button = Pin(BUTTON_PIN, Pin.IN, Pin.PULL_UP)

brightness_levels = [0.005,0.1, 0.3, 0.6, 1.0] # Example brightness levels
current_brightness_index = 0

def set_all_pixels_color(r, g, b, brightness):
    for i in range(NUM_PIXELS):
        np[i] = (int(r * brightness), int(g * brightness), int(b * brightness))
    np.write()

# Initial state
set_all_pixels_color(255, 0, 0, brightness_levels[current_brightness_index])

while True:
    if button.value() == 0:  # Button pressed
        time.sleep_ms(50)  # Debounce
        if button.value() == 0: # Confirm press after debounce
            current_brightness_index = (current_brightness_index + 1) % len(brightness_levels)
            set_all_pixels_color(255, 0, 0, brightness_levels[current_brightness_index])
            print(f"Brightness set to: {brightness_levels[current_brightness_index] * 100}%")
            while button.value() == 0: # Wait for button release
                time.sleep_ms(10)
    time.sleep_ms(10) # Small delay for main loop

In this code, you just attached, the brightness won’t be assigned to the np object, however it should still be read by the set_all_pixels_color(). It was not present in the code you posted in the previous post but I can see you posted something similar in the first post. I should have double checked.

In this case, even if its not very pythonic, I would think it would be better to assign the brightness to specific RGB values so that you can get the exact colours hue you want, especially when you’re picking colours like Pink or Orange.

Let me know if that helps.

1 Like

Hi Jane

I am not sure how assigning different brightness values to each RGB colour or variety of colour e.g. pink or orange would work because I might have five different brightnesses that I want each colour to be for different reasons which means if I had seven colours I’d have 35 options so I’m just wondering how that would work. I suppose this is why I have been pursuing the method I have in the hope that it wouldn’t be as difficult as it has turned out to be. I was originally hoping that I would not even have to come on the forum to get this done but such was not to be.
Cheers

Hi @Nicholas193967,

It’s not really necessary, you can do it as you have written and just modify the colours with brightness on the fly.

It’s more how I would do it than anything else.

Again, its not very pythonic, but I like the certainty of predefined values.

Hi @Nicholas193967.

I like @Jane’s idea. I dunno if it’s really that unpythonic anyway. :slight_smile:

If we want to think in terms of brightness, and pass it around dynamically, why don’t we switch to HSV.

Neopixels in micropython want’s RGB but we can write a wrapper.

import neopixel
from coloursys import hsv_to_rgb

def np_set_hsv_at_idx(i, h, s, v):
    r, g, b = hsv_to_rgb(h, s, v)
    np[i] = (int(r*255), int(g*255), int(b*255))
    np.write()

# e.g.
red_hsv = (0.0, 1.0, 1.0) #It's toooooo red. Yuck!
brightness_vector= (1.0, 0.62, 0.41) #pretty dim and a cool tone

#let's zip those up for a gentle red
dull_red = tuple(colour * brightness for colour, brightness in zip(red_hsv , brightness_vector))
#that new red can be our first pixel.
np_set_hsv_at_idx(0, dull_red[0], dull_red[1], dull_red[2])

I didn’t test the code but I dunno It’ll probs be fine… send it lol.
You might need to import colorsys.

Would that make your program simpler to manage and write?

2 Likes

Hi Pixmusix
Thank you for your contribution. I have heard of HSV although I have never used it or seen it used. I have just quickly looked up converting rgb to hsv but that is way above my pay grade.
I have put your code into Thonny and tried to compile but I get invalid syntax on line 4, and I am sorry but I don’t really understand your code.
I thought trying to achieve my original objective in rgb would be simple, since it is possible to dim Neopixels and it is possible to change patterns so I thought that combining the two would be simple
Nick

2 Likes

oh!! I forgot the define key word.
Fixed it in my code above.

This is handled for you by colorsys.

Have a play around here. :slight_smile:

You’ll get a feel for it.

The reason I think you might like HSV is that you can isolate choosing a colour and a choosing a brightness into two steps. :+1:

Oh, there is a : at the end of line 16. Did that end up in your code too?

1 Like

syntax error line16.
thank you for your encouragment and help

2 Likes

yes I had the : now I need to import coloursys…shall proceed

2 Likes

Honestly, Pixmusix, I feel like everyone has a slightly different idea of what pythonic means :stuck_out_tongue: But I appreciate that you like my idea. And I really like your idea.

Let us know how it goes, @Nicholas193967.

1 Like

Hi Guys
I have had a look at the colour picker web page and obtained the following colours although I have discovered that the do not need to be used to obtain any particular colour

`hsv(6 100% 86.3%) red,
hsv(242 92.3% 86.3%) blue,
hsv(119 92.3% 86.3%) green,
hsv(130 100% 86.3%) green,

`I have changed the pixel that is to be iluminated

np_set_hsv_at_idx(2, bright_green[0], bright_green[1], bright_green[2])   #idx(?  = the led that will light up\

I cannot work out how to light up all the pixels in my case ( ring of 24), or to change colours at the push of a button .

This project will be used as a light painting wand for photographic purposes which is why I want to be able to change the patterns, change the brightness, do it all at the push of a 2-4 buttons as it will be portable running off a battery , and change the colour.

At the moment I don’t see how this system will do it but I am trying to see if it will work

I have left all the commented out parts as I perceive that they will be necessary to complete the tasks I have mentioned. the code as it stands now is below.
cheers
Nick

import neopixel
from colorsys import hsv_to_rgb
from machine import Pin


# NeoPixel setup
PIXEL_PIN = 0 # Example pin, adjust as needed
NUM_PIXELS = 24 # Number of NeoPixels
np = neopixel.NeoPixel(Pin(PIXEL_PIN), NUM_PIXELS)

def np_set_hsv_at_idx(i, h, s, v):
    r, g, b = hsv_to_rgb(h, s, v)
    np[i] = (int(r*255), int(g*255), int(b*255))
    np.write()

# e.g.
#red_hsv = (0.0, 1.0, 1.0) #It's toooooo . Yum!
green_hsv = (113.0, 1.0, 1.0) #It's toooooo Yum!
#blue_hsv = (105.0, 1.0, 1.0) #It's toooooo Yum!
# pink_hsv = (0.0, 1.0, 1.0) #It's toooooo Yum!

brightness_vector= (0.3923, 1.0, 0.8) #pretty dim and a cool tone       # brightness_vector= (0.3923, 1.0, 0.8) green
#brightness_vector= (1.0, 0.62, 0.41) #pretty dim and a cool tone       #brightness_vector= (0.3923, 1.1, 0.8)white
#brightness_vector= (0.9, 5.9, 5.8) #pretty dim and a cool tone

#let's zip those up for a gentle red
bright_green = tuple(colour * brightness for colour, brightness in zip(green_hsv , brightness_vector))
#that new red can be our first pixel.
np_set_hsv_at_idx(2, bright_green[0], bright_green[1], bright_green[2])   #idx(?  = the led that will light up

#let's zip those up for a gentle red
bright_green = tuple(colour * brightness for colour, brightness in zip(green_hsv , brightness_vector))
#that new red can be our first pixel.
np_set_hsv_at_idx(2, bright_green[0], bright_green[1], bright_green[2])   #idx(?  = the led that will light up

#hsv(6 100% 86.3%)     red
#hsv(242 92.3% 86.3%)  blue
#hsv(119 92.3% 86.3%)  green
#hsv(130 100% 86.3%)   green

#********************

Hey Nicholas, a couple of things:

  • The i in np_set_hsv_at_idx is the individual pixel in the strip. If you want to change it so that all pixels will be lit, you could change the function to:
def np_set_hsv_at_idx(h, s, v):
    r, g, b = hsv(h,s,v)
    for pixel in in range(NUM_PIXEL):
        np[i] = (int(r*255), int(g*255), int(b*255))
    np.write()

That should let you light up every pixel in the strip.

The reason that Pixmusix’s rewrite would work is that you than change the brightness by redefining the brightness vector with a button press than redoing your np_set_hsv_at_idx() function.

I’m sorry I can’t address the other question now about button inputs right now, but I can assure you that with some minor modifications it can work with this code.

2 Likes

This can always be a problem with Python, separate code works ok but not when merged. Usually means the individual code has not been written as a stand alone object.

From the posts by others the brightness level is a change to the actual colour value. And if I consider how Neopixels work there really is no other way to do it. The LEDs have 3 control pins RGB and no brightness pin.

Taking Janes code further and just addressing pixel 0.
np[0] = (255, 0, 0) # set to red, full brightness
Button pressed to reduce brightness …
np[0] = (128, 0, 0) # set to red, half brightness
Button pressed to reduce brightness …
np[0] = (64, 0, 0) # set to red, quarter brightness

Your code would need to have [255, 128, 64] set up in list which is accessed when the brightness changes. Or you could calculate the values.

To set any pixel you change the number used in np[0] first pixel, np[23] last pixel.
Set these with np[ ] then use np.write() to activate them.
Or use the code provided by @Pixmusix and @Jane.

Your code has a while loop, it checks the button states, if changed it sets the colours and updates the pixels, waits for a bit then loops again. You keep a variable or list which contains the current colour and from that calculate the new colour or level of colour.

Maybe I should give myself a little project and get some working code. Might do that out of interest anyway.

Cheers
Jim

2 Likes

Wired up 16 LED Neopixel ring, buttons were high active.
Following code changes colour and brightness when buttons pressed.

Cheers
Jim

from machine import Pin
import neopixel
import time

NUM_PIXELS = 16
DATA_PIN = 18
BUTTON1_PIN = 16
BUTTON2_PIN = 17

button1 = Pin(BUTTON1_PIN, Pin.IN, Pin.PULL_DOWN)
button2 = Pin(BUTTON2_PIN, Pin.IN, Pin.PULL_DOWN)

np = neopixel.NeoPixel(machine.Pin(DATA_PIN), NUM_PIXELS)

brightness = 8
current_colour = 0
colours = [(64, 0, 0), (0, 64, 0), (0, 0, 64), (64, 64, 64)]

################################################################
def set_colour(c,b):
    colour = list(colours[c])
    if colour[0] > 0: colour[0] = b
    if colour[1] > 0: colour[1] = b
    if colour[2] > 0: colour[2] = b
    np.fill(colour)
    np.write()
    return

###############################################################
def main():
    global current_colour, brightness
    set_colour(current_colour,brightness)    # set initial colour
    while True:
        if button1.value() == 1:
            brightness = brightness + 16
            if brightness > 128: brightness = 8
        if button2.value() == 1:
            current_colour += 1
            if current_colour > 2: current_colour = 0
        set_colour(current_colour,brightness)
        time.sleep_ms(50) 
    return
###############################################################
if __name__ == "__main__":
    print('Neo Pixel Colur Changer ...')
    main()
    print("Finished ...")
##############################################################
    


    

2 Likes

Wow Jim ,impressive.
The first thing that happens when I run the code without pushing any buttons is that the ring flashes at 100kmph ( very fast )

My board is hard wired for pull up so I have changed the button instructions to pull up (see following ) .

button1 = Pin(BUTTON1_PIN, Pin.IN, Pin.PULL_UP)
button2 = Pin(BUTTON2_PIN, Pin.IN, Pin.PULL_UP)

I have aslo changed the following lines from 1 to 0.Please correct me if I’m wrong

if button1.value() == 0:  # 1
if button2.value() != 0:  # 1

Where did you obtain your colours on line 17 from and what do I need to to do to extend the range of colours to something like this or even a couple more
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
PINK = (250, 0 ,250)
ORANGE = (255, 50, 0)
OFF = (0, 0, 0)

current_colour = 0
colours = [(64, 0, 0), (0, 64, 0), (0, 0, 64), (64, 64, 64)]

################################################################
def set_colour(c,b):
    colour = list(colours[c])
    if colour[0] > 0: colour[0] = b
    if colour[1] > 0: colour[1] = b
    if colour[2] > 0: colour[2] = b
    np.fill(colour)
    np.write()
    time.sleep_ms(50)
    return



The code as it now stands is below and I have stopped the rapid flashing

from machine import Pin
import neopixel
import time

NUM_PIXELS = 24
DATA_PIN = 0
BUTTON1_PIN = 14
BUTTON2_PIN = 15

button1 = Pin(BUTTON1_PIN, Pin.IN, Pin.PULL_UP)
button2 = Pin(BUTTON2_PIN, Pin.IN, Pin.PULL_UP)

np = neopixel.NeoPixel(machine.Pin(DATA_PIN), NUM_PIXELS)

brightness = 4
current_colour = 0
colours = [(64, 0, 0), (0, 64, 0), (0, 0, 64),  (64, 64, 64)]

################################################################
def set_colour(c,b):
    colour = list(colours[c])
    if colour[0] > 0: colour[0] = b
    if colour[1] > 0: colour[1] = b
    if colour[2] > 0: colour[2] = b
    np.fill(colour)
    np.write()
    time.sleep_ms(50)
    return

###############################################################
def main():
    global current_colour, brightness
    set_colour(current_colour,brightness)    # set initial colour
    while True:
        if button1.value() == 0:  #1
            brightness = brightness + 16
            if brightness > 128: brightness = 8
            time.sleep_ms(50)
        if button2.value() == 0:  # 1
            current_colour += 1
            if current_colour > 2: current_colour = 0
        set_colour(current_colour,brightness)
        time.sleep_ms(50) 
    return
###############################################################
if __name__ == "__main__":
    print('Neo Pixel Colur Changer ...')
    main()
    print("Finished ...")
##############################################################


thank you
Nick

1 Like