forked from romilly/quick2wire-python-api
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathselector-button-blink
More file actions
executable file
·108 lines (99 loc) · 4.41 KB
/
selector-button-blink
File metadata and controls
executable file
·108 lines (99 loc) · 4.41 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#!/usr/bin/env python3
#||
#|| Event-Driven Input/Output
#|| =========================
#||
#|| The [button-blink](button-blink) example shows how to read from a
#|| GPIO pin, but not how to react promptly to a signal on the pin.
#|| It reads the pin's value at regular intervals, but if a signal
#|| occurs on the pin between reads the program won't react until the
#|| next time it reads from the pin.
#||
#|| To react promptly to GPIO input we must change the way our program
#|| works. Instead of being in control, polling the GPIO pins and
#|| sleeping for fixed amounts of time, our program needs to be _event
#|| driven_: reacting as soon as the signal at the input pin changes
#|| and using timer events to decide when to blink the LED.
#||
#|| An event-driven program uses a `Selector` object to wait for
#|| events to occur on a number of _event sources_ -- for example GPIO
#|| input pins, timers or network connections. The program creates a
#|| Selector, creates _event source_ objects that can signal events,
#|| adds the event sources to the Selector, and runs an _event loop_
#|| in which it waits on the Selector for an events to occur and then
#|| handles the latest event reported by the Selector.
#||
#|| As we are converting the button-blink example to be event-driven,
#|| we need two event sources: the GPIO pin connected to the button
#|| and, because we can't put the process to sleep for half a second
#|| to blink the LED, a repeating timer that tells the program when to
#|| turn the LED off it is currently on and vice versa.
from quick2wire.gpio import pins, In, Out, Both
from quick2wire.selector import Selector, Timer
#| [1] We create the selector that will drive our event loop
selector = Selector()
#|.
button = pins.pin(0, direction=In, interrupt=Both)
led = pins.pin(1, direction=Out)
#| [2] We also create a repeating Timer to trigger the blinking of the
#| LED. The _interval_ parameter specifies the time, in seconds,
#| between Timer events.
timer = Timer(interval=0.5)
#|.
#| [3] Like the button and led Pins, the selector and timer consume
#| operating-system resources, so we add them to the with statement to
#| ensure that they are closed.
with selector, button, led, timer:
#|.
#| [4] We have to add the button and timer to the selector before the
#| selector will report their events.
selector.add(button)
selector.add(timer)
#|.
while True:
#| [5] Now the program's main loop must wait for selector
#| events. When the button or timer signals an event, the
#| selector stores a reference to the object that is ready to
#| be processed in its _ready_ property and returns from its
#| `wait()` method.
selector.wait()
#|.
#| [6] If the timer is ready, we invert the value of the
#| led pin, so that it blinks on and off.
if selector.ready == timer:
#| [7] The program must "consume" the latest timer event
#| by waiting for it, otherwise the timer will continually
#| signal that it is ready, making our program run in a
#| busy-loop.
timer.wait()
#|.
led.value = not led.value
#|.
#| [8] If the button is ready, the program reads the
#| button state. If the value at the GPIO pin is one
#| (voltage high), the button has been pressed; if zero
#| (voltage low), it has been released.
elif selector.ready == button:
is_pressed = button.value
#| [9] We can use the value read from the button in an if
#| statement (in Python, 0 is treated as false and 1 as
#| true)
if is_pressed:
#|.
#| [10] If the button has been pressed, the program
#| turns on the LED and starts the timer, so that it
#| generates the events that makes the program blinks
#| the LED on and off.
led.value = 1
timer.start()
#|.
else:
#| [11] If the button has been released, the program
#| turns of the LED and stops the timer so that timer
#| events won't turn LED on again.
led.value = 0
timer.stop()
#|.
#|.
#|| When you run this program you will see that it reacts promptly to
#|| button presses.