RPI.GPIO Help

hakugin.gin at gmail.com hakugin.gin at gmail.com
Fri Sep 11 21:24:13 CEST 2015


On Friday, September 11, 2015 at 2:25:15 PM UTC-4, John McKenzie wrote:
> Hello.
> 
>  Thanks to the help of people here and in other newsgroups I seem to have 
> something working doing the basics. (Buttons work, colours light up 
> appropriately.)
> 
>  When I followed MRAB's instructions and read about scopes of variables 
> that solved my most recent problem, but it introduced a bug. I think I 
> fixed the bug but after all my stupid mistakes and forgetfulness that 
> seems too good to be true. I expect there is a better, more elegant, or 
> more Pythonic way to do what I did so please feel free to share on the 
> subject.
> 
>  I had a problem where if I pressed a button while the LEDs were already 
> flashing the colour of that button it would block a new colour from 
> starting when I pressed a new button. So if the LED strip was red and I 
> pressed the red button again nothing would happen when I pressed the blue 
> or yellow button. Similar problem for the other two buttons.
> 
>  So inside my callbacks I added this code:
> 
>    if colour == 1:
>         pass
>     elif colour == 2 or 3:
>         colour = 1
> 
> 
>  Now it seems OK from my limited testing.
> 
> 
>  Here is the code that has buttons and colours working and includes my 
> bug fix:
> 
> 
> import atexit 
> import time 
> from blinkstick import blinkstick 
> import RPi.GPIO as GPIO   
> 
> led = blinkstick.find_first() 
> colour = 0
> time_red = 0
> time_yellow = 0
> time_blue = 0
> timestamp = time.strftime("%H:%M:%S")
> 
> GPIO.setmode(GPIO.BCM)
> GPIO.setup(22, GPIO.IN, pull_up_down=GPIO.PUD_UP)
> GPIO.setup(23, GPIO.IN, pull_up_down=GPIO.PUD_UP)
> GPIO.setup(24, GPIO.IN, pull_up_down=GPIO.PUD_UP)
> 
> 
> def red_button(channel):
>     global colour
>     if colour == 1:
>         pass
>     elif colour == 2 or 3:
>         colour = 1
>         while colour == 1:
>             led.pulse(red=255, green=0, blue=0, repeats=1, duration=2000, 
> steps=50)
> def yellow_button(channel):
>     global colour
>     if colour == 2:
>         pass
>     elif colour == 1 or 3:
>         colour = 2
>         while colour == 2:
>             led.pulse(red=255, green=96, blue=0, repeats=1, 
> duration=2000, steps=50)
> def blue_button(channel):
>     global colour
>     if colour == 3:
>         pass
>     elif colour == 1 or 2:
>         colour = 3
>         while colour == 3:
>             led.pulse(red=0, green=0, blue=255, repeats=1, duration=2000, 
> steps=50)
> 
> 
> GPIO.add_event_detect(22, GPIO.FALLING, callback=red_button, 
> bouncetime=200)
> GPIO.add_event_detect(23, GPIO.FALLING, callback=yellow_button, 
> bouncetime=200)
> GPIO.add_event_detect(24, GPIO.FALLING, callback=blue_button, 
> bouncetime=200)
> 
> 
> while True:
>     if colour == 1:
>         time_red += 1
>     elif colour == 2:
>         time_yellow += 1
>     elif colour == 3:
>         time_blue += 1
> 
>     time.sleep(0.1)
> 
> 
> def exit_handler():
>     print "\033[0;41;37mRed Team:\033[0m ", time_red
>     print "\033[0;43;30mYellow Time:\033[0m ", time_yellow
>     print "\033[0;44;37mBlue Time:\033[0m ", time_blue
>     flog = open("flag1.log", "a")
>     flog.write(timestamp + "\n" + "Red Team: " + str(time_red) + "\n" + 
> "Yellow Team: " + str(time_yellow) + "\n" + "Blue Team: " + str
> (time_blue) + "\n")
>     flog.close()
>     led.set_color(name="black")
> atexit.register(exit_handler)
> GPIO.cleanup()
> 
> 
> 
>  I think I am OK GPIO wise now, although always happy to improve the code 
> and in the long term I want to do so.
> 
>  Will start new threads for more straight forward Python questions like 
> help with saving a log of the results, timing, etc.
> 
>  Thanks for your help, everyone.

I just noticed another potential issue with your code. You added "while" loops to your button functions, you should adjust the code so that the "led.pulse" call is in the main loop.

For example, at the beginning add something like:

pulse_settings = []


Change your button functions to change this new variable when the button is pressed:


def red_button(channel):
    global colour, pulse_settings
    if colour != 1:
        colour = 1
        pulse_settings = (red=255, green=0, blue=0, repeats=1, duration=2000, steps=50)


Then change your main "while" loop:

while True:
    if colour == 1:
        time_red += 1
    elif colour == 2:
        time_yellow += 1
    elif colour == 3:
        time_blue += 1
    led.pulse(pulse_settings)
    time.sleep(pulse_settings[4]) # sets the delay to the duration of the pulse effect


These are merely suggestions, again I do not have access to my RPi to test, your mileage may vary.


More information about the Python-list mailing list