1

I'm trying to figure out how I can solve this issue. I have a Raspberry Pi that is set up with a breadboard that consists of:

  • 1 RGB light
  • 2 buttons (left and right)
  • 1 OLED screen

Each component works and I can run each one. What I'm trying to do is write a script that will allow me to select the "mode" with the left button (everything off vs lights vs screen on).

When a mode is selected, the right button then allows me to select between options within that mode. Below is the code as I have it:

def off():
    lights = [red,green,blue]
    for light in lights:
        light.off()
        
def lightSelector():
    off()
    number = 0
    while number < 5:
        if rightButton.is_pressed:
            if number == 0:
                off()
                red.on()
                sleep(1)
                number += 1
            elif number == 1:
                off()
                green.on()
                sleep(1)
                number += 1
            elif number == 2:
                off()
                blue.on()
                sleep(1)
                number += 1
            elif number == 3:
                off()
                row()
                sleep(1)
                number+= 1
            else:
                number = 0
                
def picture():
    image = Image.open('grant.jpeg')
    image_r = image.resize((width,height), Image.BICUBIC)
    image_bw = image_r.convert("1")

    for x in range(width):
            for y in range(height):
                    oled.pixel(x,y,bool(int(image_bw.getpixel((x,y)))))
    oled.show()
 
def oledOff():
    oled.fill(0)
    oled.show()

def buttons():
    x = 0
    y = 0
    while y is 0:
        print('x = ' , x)
        print('y = ' , y)
        if leftButton.is_pressed:
            if x == 0 :
                oledOff()
                off()
                sleep(0.5)
                x += 1
            elif x == 1:
                oledOff()
                off()
                lightSelector()
                sleep(0.5)
                x += 1
            elif x == 2:
                oledOff()
                off()
                picture()
                sleep(0.5)
                x += 1
            else:
                x = 0

oledOff()
off()
buttons()

The idea is that the buttons() function is the main overall function and will call the others as needed. My issue is that once I get to y == 1, or the lightSelector() function, it no longer registers that the leftButton is being pressed and won't switch to the next mode and I'm stuck in the lightSelector() function.

I know at baseline I can spell out lightSelector within the buttons function instead of calling another function but I'm trying to not be as verbose. I don't have any experience with threading or multprocessing and looked into it but couldn't see how that would help.

Peter Badida
  • 11,310
  • 10
  • 44
  • 90
  • Kepp a button state for your light - do not loop inside lightSelector. when entering lightSelector check wich state your light is at, advance it and return to main function. main loop around the "get if button is pressed" – Patrick Artner Jun 27 '21 at 10:36
  • 1
    `while y is 0:` is a code smell - use `while y == 0:` or in your case use `while True` and get rid of `y` as it never changes if you need to escape the endless loop use `break` – Patrick Artner Jun 27 '21 at 10:38
  • your shown code is no [mre] - there is no way "to get y == 1" - there is a whole function pictures that is completely unrelated. You have a program logic problem, you already identified what is wrong (being stuck in certain parts) - so change your program flow logic to fix it.... hardly something we are able to help. – Patrick Artner Jun 27 '21 at 10:42
  • @PatrickArtner I changed some of this, thanks for the input. I was able to get a solution by an "if rightButton.is_pressed: do light things; elif leftButton.is_pressed: return" in the lightSelector function. This isn't quite what I was looking for, I was thinking of some process where the main function continues to run in the background and the nested function would respond but this seems outside of my skill level. – broke student Jun 27 '21 at 12:28
  • @brokestudent for the latter [just use async](https://docs.python.org/3/library/asyncio-task.html) if you want, it basically hides that `while True` for you and you can then play just with "events" directly. – Peter Badida Jun 29 '21 at 22:31
  • @brokestudent for the latter [just use async](https://docs.python.org/3/library/asyncio-task.html) if you want, it basically hides that while True for you and you can then play just with "events" directly. [Also relevant](https://stackoverflow.com/a/45615121/5994041) to async if you start thinking about one "thread" being a slave for task processing e.g. handling hw inputs and other "thread" being just the GUI/CLI view. – Peter Badida Jun 29 '21 at 22:50

0 Answers0