Skip to content

Commit c5e21e9

Browse files
committed
selector example marked up for code-guide, plus improvements to blink and button-blink examples
1 parent 2c88754 commit c5e21e9

3 files changed

Lines changed: 76 additions & 24 deletions

File tree

examples/blink

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#!/usr/bin/env python3
2+
#||
23
#|| Blink
34
#|| =====
45
#||
@@ -65,4 +66,4 @@ with led:
6566
#|.
6667

6768
#|| The next example, [button-blink](button-blink), shows how to also
68-
#|| read the state of a GPIO input pin connected to a push-button.
69+
#|| read the state of a GPIO input pin connected to a push-button.

examples/button-blink

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#!/usr/bin/env python3
2+
#||
23
#|| Button Blink
34
#|| ============
45
#||
@@ -37,8 +38,7 @@ with button, led:
3738

3839
#|| However, there's a flaw in this program. If you repeatedly press
3940
#|| and release the button you can see that the program can take up to
40-
#|| half a second to react. The program should react to the button
41-
#|| immediately. To do so it must handle GPIO interrupts in an _event
42-
#|| loop_. That's what we'll look at in the
43-
#|| [selector-button-blink](selector-button-blink) example.
44-
41+
#|| half a second to react. Ideally the program would react to the
42+
#|| button immediately. To do so it must handle GPIO interrupts in an
43+
#|| _event loop_, which we'll look at in the [next
44+
#|| example](selector-button-blink).

examples/selector-button-blink

Lines changed: 69 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#!/usr/bin/env python3
2-
2+
#||
33
#|| Event-Driven Input/Output
44
#|| =========================
55
#||
@@ -15,43 +15,94 @@
1515
#|| driven_: reacting as soon as the signal at the input pin changes
1616
#|| and using timer events to decide when to blink the LED.
1717
#||
18-
#|| An event loop is driven by a `Selector` object, which holds a
19-
#|| number of _event sources_ and waits for an event to occur on one
20-
#|| of them. An event-driven program creates a Selector, creates
21-
#|| _event source_ objects that can signal events, adds those event
22-
#|| sources to the Selector, and repeatedly waits on the Selector for
23-
#|| events to occur.
18+
#|| An event-driven program uses a `Selector` object to wait for
19+
#|| events to occur on a number of _event sources_ -- for example GPIO
20+
#|| input pins, timers or network connections. The program creates a
21+
#|| Selector, creates _event source_ objects that can signal events,
22+
#|| adds the event sources to the Selector, and runs an _event loop_
23+
#|| in which it waits on the Selector for an events to occur and then
24+
#|| handles the latest event reported by the Selector.
2425
#||
2526
#|| As we are converting the button-blink example to be event-driven,
26-
#|| we have two event sources: the GPIO pin connected to the button
27-
#|| and a repeating timer that, when started, tells the program when
28-
#|| to blink the LED.
27+
#|| we need two event sources: the GPIO pin connected to the button
28+
#|| and, because we can't put the process to sleep for half a second
29+
#|| to blink the LED, a repeating timer that tells the program when to
30+
#|| turn the LED off it is currently on and vice versa.
2931

3032
from quick2wire.gpio import pins, In, Out, Both
3133
from quick2wire.selector import Selector, Timer
3234

35+
#| [1] We create the selector that will drive our event loop
3336
selector = Selector()
37+
#|.
3438
button = pins.pin(0, direction=In, interrupt=Both)
3539
led = pins.pin(1, direction=Out)
40+
41+
#| [2] We also create a repeating Timer to trigger the blinking of the
42+
#| LED. The _interval_ parameter specifies the time, in seconds,
43+
#| between Timer events.
3644
timer = Timer(interval=0.5)
45+
#|.
3746

47+
#| [3] Like the button and led Pins, the selector and timer consume
48+
#| operating-system resources, so we add them to the with statement to
49+
#| ensure that they are closed.
3850
with selector, button, led, timer:
51+
#|.
52+
#| [4] We have to add the button and timer to the selector before the
53+
#| selector will report their events.
3954
selector.add(button)
4055
selector.add(timer)
41-
42-
print("ready")
56+
#|.
4357

4458
while True:
59+
#| [5] Now the program's main loop must wait for selector
60+
#| events. When the button or timer signals an event, the
61+
#| selector stores a reference to the object that is ready to
62+
#| be processed in its _ready_ property and returns from its
63+
#| `wait()` method.
4564
selector.wait()
65+
#|.
66+
67+
#| [6] If the timer is ready, we invert the value of the
68+
#| led pin, so that it blinks on and off.
69+
if selector.ready == timer:
70+
#| [7] The program must "consume" the latest timer event
71+
#| by waiting for it, otherwise the timer will continually
72+
#| signal that it is ready, making our program run in a
73+
#| busy-loop.
74+
timer.wait()
75+
#|.
76+
77+
led.value = not led.value
78+
#|.
4679

47-
if selector.ready == button:
48-
if button.value:
80+
#| [8] If the button is ready, the program reads the
81+
#| button state. If the value at the GPIO pin is one
82+
#| (voltage high), the button has been pressed; if zero
83+
#| (voltage low), it has been released.
84+
elif selector.ready == button:
85+
is_pressed = button.value
86+
87+
#| [9] We can use the value read from the button in an if
88+
#| statement (in Python, 0 is treated as false and 1 as
89+
#| true)
90+
if is_pressed:
91+
#|.
92+
#| [10] If the button has been pressed, the program
93+
#| turns on the LED and starts the timer, so that it
94+
#| generates the events that makes the program blinks
95+
#| the LED on and off.
4996
led.value = 1
5097
timer.start()
98+
#|.
5199
else:
100+
#| [11] If the button has been released, the program
101+
#| turns of the LED and stops the timer so that timer
102+
#| events won't turn LED on again.
52103
led.value = 0
53104
timer.stop()
54-
55-
elif selector.ready == timer:
56-
timer.wait()
57-
led.value = not led.value
105+
#|.
106+
#|.
107+
#|| When you run this program you will see that it reacts promptly to
108+
#|| button presses.

0 commit comments

Comments
 (0)