Skip to content

Commit 4411a25

Browse files
author
Kevin J Walters
committed
Merge branch 'master' of https://github.com/adafruit/Adafruit_Learning_System_Guides into cluesensorplotter
2 parents a5ec7b2 + 884c611 commit 4411a25

File tree

12 files changed

+1036
-4
lines changed

12 files changed

+1036
-4
lines changed

CLUE_Light_Painter/bmp2led.py

Lines changed: 397 additions & 0 deletions
Large diffs are not rendered by default.
72 KB
Binary file not shown.
15.2 KB
Binary file not shown.
15.2 KB
Binary file not shown.
38 KB
Binary file not shown.
25.4 KB
Binary file not shown.
27.5 KB
Binary file not shown.

CLUE_Light_Painter/boot.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
"""
2+
Check for connection between pin and GND on hard boot (power-on or reset).
3+
If NO connection: storage is remounted as read/write so the light painter
4+
code can run (it requires temporary files), but code.py can't be edited.
5+
If connected: storage is left in read-only mode. Light painter code can't
6+
run but files are editable.
7+
"""
8+
9+
# pylint: disable=import-error
10+
import board
11+
import digitalio
12+
import storage
13+
14+
PIN = board.D0
15+
16+
IO = digitalio.DigitalInOut(PIN)
17+
IO.direction = digitalio.Direction.INPUT
18+
IO.pull = digitalio.Pull.UP
19+
20+
if IO.value: # No connection
21+
storage.remount('/', False) # Remount storage as read/write for painter

CLUE_Light_Painter/code.py

Lines changed: 518 additions & 0 deletions
Large diffs are not rendered by default.

CLUE_Light_Painter/richbutton.py

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
"""Glorified button class with debounced tap, double-tap, hold and release"""
2+
3+
# pylint: disable=import-error
4+
from time import monotonic
5+
from digitalio import DigitalInOut, Direction, Pull
6+
7+
# pylint: disable=too-many-instance-attributes, too-few-public-methods
8+
class RichButton:
9+
"""
10+
A button class handling more than basic taps: adds debounced tap,
11+
double-tap, hold and release.
12+
"""
13+
14+
TAP = 0
15+
DOUBLE_TAP = 1
16+
HOLD = 2
17+
RELEASE = 3
18+
19+
def __init__(self, pin, *, debounce_period=0.05, hold_period=0.75,
20+
double_tap_period=0.3):
21+
"""
22+
Constructor for RichButton class.
23+
24+
Arguments:
25+
pin (int) : Digital pin connected to button
26+
(opposite leg to GND). Pin will be
27+
configured as INPUT with pullup.
28+
Keyword arguments:
29+
debounce_period (float) : interval, in seconds, in which multiple
30+
presses are ignored (debounced)
31+
(default = 0.05 seconds).
32+
hold_period (float) : interval, in seconds, when a held
33+
button will return a HOLD value from
34+
the action() function (default = 0.75).
35+
double_tap_period (float): interval, in seconds, when a double-
36+
tap can be sensed (vs returning
37+
a second single-tap) (default = 0.3).
38+
Longer double-tap periods will make
39+
single-taps less responsive.
40+
"""
41+
self.in_out = DigitalInOut(pin)
42+
self.in_out.direction = Direction.INPUT
43+
self.in_out.pull = Pull.UP
44+
self._debounce_period = debounce_period
45+
self._hold_period = hold_period
46+
self._double_tap_period = double_tap_period
47+
self._holding = False
48+
self._tap_time = -self._double_tap_period
49+
self._press_time = monotonic()
50+
self._prior_state = self.in_out.value
51+
52+
def action(self):
53+
"""
54+
Process pin input. This MUST be called frequently for debounce, etc.
55+
to work, since interrupts are not available.
56+
Returns:
57+
None, TAP, DOUBLE_TAP, HOLD or RELEASE.
58+
"""
59+
new_state = self.in_out.value
60+
if new_state != self._prior_state:
61+
# Button state changed since last call
62+
self._prior_state = new_state
63+
if not new_state:
64+
# Button initially pressed (TAP not returned until debounce)
65+
self._press_time = monotonic()
66+
else:
67+
# Button initially released
68+
if self._holding:
69+
# Button released after hold
70+
self._holding = False
71+
return self.RELEASE
72+
if (monotonic() - self._press_time) >= self._debounce_period:
73+
# Button released after valid debounce time
74+
if monotonic() - self._tap_time < self._double_tap_period:
75+
# Followed another recent tap, reset double timer
76+
self._tap_time = 0
77+
return self.DOUBLE_TAP
78+
# Else regular debounced release, maybe 1st tap, keep time
79+
self._tap_time = monotonic()
80+
else:
81+
# Button is in same state as last call
82+
if self._prior_state:
83+
# Is not pressed
84+
if (self._tap_time > 0 and
85+
(monotonic() - self._tap_time) > self._double_tap_period):
86+
# Enough time since last tap that it's not a double
87+
self._tap_time = 0
88+
return self.TAP
89+
elif (not self._holding and
90+
(monotonic() - self._press_time) >= self._hold_period):
91+
# Is pressed, and has been for the holding period
92+
self._holding = True
93+
return self.HOLD
94+
return None

0 commit comments

Comments
 (0)