Skip to content

Commit 718ecd5

Browse files
committed
Add interval option to Simple Button
1 parent 9cd11e9 commit 718ecd5

File tree

2 files changed

+43
-8
lines changed

2 files changed

+43
-8
lines changed

async_button.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,9 @@ class SimpleButton:
5151
task.
5252
"""
5353

54-
def __init__(self, pin: Pin, value_when_pressed: bool, pull: bool = True):
54+
def __init__(
55+
self, pin: Pin, value_when_pressed: bool, *, pull: bool = True, interval=0.05
56+
):
5557
"""
5658
5759
:param Pin pin: Pin to wait for
@@ -62,9 +64,14 @@ def __init__(self, pin: Pin, value_when_pressed: bool, pull: bool = True):
6264
it is ``True``. If an external pull is already provided for the pin, you can set
6365
pull to ``False``. However, enabling an internal pull when an external one is already
6466
present is not a problem; it simply uses slightly more current.
67+
:param float interval: How long to wait between checks of whether the button has changed.
68+
Default is 0.05s (human experience of "instantaneous" is up to 0.1s). This parameter
69+
can be set to zero and the button will be checked as often as possible, although other
70+
coroutines will still be able to run.
6571
"""
6672
self.pin: Pin = pin
6773
self.value_when_pressed = value_when_pressed
74+
self.interval = interval
6875
if pull:
6976
self.pull = digitalio.Pull.DOWN if value_when_pressed else digitalio.Pull.UP
7077
else:
@@ -79,7 +86,7 @@ async def pressed(self):
7986
while True:
8087
if counter.count > 0:
8188
return
82-
await asyncio.sleep(0)
89+
await asyncio.sleep(self.interval)
8390

8491
async def released(self):
8592
"""
@@ -90,7 +97,7 @@ async def released(self):
9097
while True:
9198
if counter.count > 0:
9299
return
93-
await asyncio.sleep(0)
100+
await asyncio.sleep(self.interval)
94101

95102

96103
class Button:

tests/test_async_simple_button.py

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,14 @@ def setUp(self) -> None:
2626
self.counter.__enter__.return_value = (
2727
self.counter
2828
) # return self as a context manager
29-
type(self.counter).count = PropertyMock(side_effect=[0, 0, 1])
29+
type(self.counter).count = PropertyMock(side_effect=[0, 0, 1, 0, 0, 1])
3030
self.countio.Counter.return_value = self.counter
3131
self.asyncio = MagicMock()
3232
self.asyncio.sleep = AsyncMock()
3333
self.patch_asyncio = patch("async_button.asyncio", self.asyncio)
3434
self.patch_asyncio.start()
3535
self.edge_rise = self.countio.Edge.RISE
3636
self.edge_fall = self.countio.Edge.FALL
37-
self.simple_button_class = async_button.SimpleButton
3837

3938
def tearDown(self) -> None:
4039
self.patch_asyncio.stop()
@@ -49,25 +48,54 @@ async def test_pressed_active_high(self):
4948
self.assertEqual(self.asyncio.sleep.await_count, 2)
5049

5150
async def test_released_active_high(self):
52-
button = self.simple_button_class("P1", True)
51+
button = async_button.SimpleButton("P1", True)
5352
await button.released()
5453
self.countio.Counter.assert_called_once_with(
5554
"P1", edge=self.edge_fall, pull=digitalio.Pull.DOWN
5655
)
5756
self.assertEqual(self.asyncio.sleep.await_count, 2)
5857

5958
async def test_pressed_active_low(self):
60-
button = self.simple_button_class("P1", False)
59+
button = async_button.SimpleButton("P1", False)
6160
await button.pressed()
6261
self.countio.Counter.assert_called_once_with(
6362
"P1", edge=self.edge_fall, pull=digitalio.Pull.UP
6463
)
6564
self.assertEqual(self.asyncio.sleep.await_count, 2)
6665

6766
async def test_released_active_low(self):
68-
button = self.simple_button_class("P1", False)
67+
button = async_button.SimpleButton("P1", False)
6968
await button.released()
7069
self.countio.Counter.assert_called_once_with(
7170
"P1", edge=self.edge_rise, pull=digitalio.Pull.UP
7271
)
7372
self.assertEqual(self.asyncio.sleep.await_count, 2)
73+
74+
async def test_pull_false_is_respected(self):
75+
button = async_button.SimpleButton("P1", False, pull=False)
76+
await button.released()
77+
self.countio.Counter.assert_called_once_with(
78+
"P1", edge=self.edge_rise, pull=None
79+
)
80+
self.assertEqual(self.asyncio.sleep.await_count, 2)
81+
82+
async def test_default_interval(self):
83+
button = async_button.SimpleButton("P1", False)
84+
await button.pressed()
85+
self.asyncio.sleep.assert_awaited_with(0.05)
86+
await button.released()
87+
self.asyncio.sleep.assert_awaited_with(0.05)
88+
89+
async def test_interval_zero(self):
90+
button = async_button.SimpleButton("P1", False, interval=0)
91+
await button.pressed()
92+
self.asyncio.sleep.assert_awaited_with(0)
93+
await button.released()
94+
self.asyncio.sleep.assert_awaited_with(0)
95+
96+
async def test_other_interval(self):
97+
button = async_button.SimpleButton("P1", False, interval=1.25)
98+
await button.pressed()
99+
self.asyncio.sleep.assert_awaited_with(1.25)
100+
await button.released()
101+
self.asyncio.sleep.assert_awaited_with(1.25)

0 commit comments

Comments
 (0)