Reputation: 548
I am using an rasperry pi with latest raspian jessie installed.
I want to react to an keydown event, then a function should be called and executed exactly once and a parameter should be incremented.
what I currently have is
# Import Libraries
from gpiozero import LED,Button
from signal import pause
from time import sleep
# LED Declaration
LED1 = LED(21)
LED2 = LED(16)
LED3 = LED(20)
# Button declaration
button = Button(19)
LED1.off()
LED2.off()
LED3.off()
current = 0
# Function for setting Outputs
def output(current):
print(current)
if current == 0:
LED1.off()
LED2.off()
LED3.off()
if current == 1:
LED1.on()
LED2.off()
LED3.off()
if current == 2:
LED1.off()
LED2.on()
LED3.off()
if current == 3:
LED1.on()
LED2.on()
LED3.off()
if current == 4:
LED1.off()
LED2.off()
LED3.on()
if current == 5:
LED1.on()
LED2.off()
LED3.on()
if current == 6:
LED1.off()
LED2.on()
LED3.on()
if current == 7:
LED1.on()
LED2.on()
LED3.on()
def increment(current):
print(current)
if current < 7:
current += 1
output(current)
return
if current == 7:
current = 0
output(current)
return
# Check for pressed button
while True:
if button.when_pressed True:
increment(current)
How can i keep sure that my function is just called once and my current variable is incremented correctly and not being reset to 0 when function is triggered once?
Upvotes: 0
Views: 722
Reputation: 7058
At this moment, you try to use current
to keep track of the state of the incrementor. But the current
within the increment
is not the same as the current
in the global (module) namespace. Easiest way to circumvent this is to declare current
as global
in the increment function, but I think it is best to create a class to keep this state
class MyLeds()
def __init__(self, *leds, current=0):
self._leds = leds
self._current = current
def increment():
self._current = (self._current + 1) % (2 ** len(self._leds) - 1)
self._output()
def _output():
for i, led in enumerate(leds):
on = self._current & 2**i
led.on() if on else led.off()
# print('led %i is %s' % (i+1, on))
I made the code also more flexible for more leds using bitwise &
.
The rest of your script would look like this, then:
if __name__ == '__main__':
from gpiozero
from signal import pause
from time import sleep
# LED Declaration
led_ports = (21, 16, 20)
leds = tuple(gpiozero.LED(led) for led in led_ports)
for led in leds:
led.off()
my_leds = MyLeds(leds)
# Button declaration
button = gpiozero.Button(19)
while True:
if button.when_pressed:
my_leds.increment()
Upvotes: 1
Reputation: 2690
You while loop will block the GUI from working. So try using the button's command option to call a function. Also, it is best practice to use a class to create the GUI. It helps avoid using global variables, etc.
from tkinter import *
class Counter:
def __init__(self, master):
self.current = 0
# Button declaration
button = Button(master, text='+', command=self.increment)
button.grid()
def increment(self):
self.current += 1
print(self.current)
root = Tk()
app = Counter(root)
root.mainloop()
Upvotes: 1