Skip to content

Commit 47f848f

Browse files
authored
Merge pull request #114 from tekktrik/dev/iterable-io-rework
Add iterable touchpad functionality
2 parents a6f916a + dbfa322 commit 47f848f

File tree

2 files changed

+63
-48
lines changed

2 files changed

+63
-48
lines changed

adafruit_circuitplayground/circuit_playground_base.py

+35-34
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
import touchio
3535

3636
try:
37-
from typing import Optional, Iterator
37+
from typing import Optional, Iterator, List
3838
from typing_extensions import Literal
3939
from microcontroller import Pin
4040
except ImportError:
@@ -82,22 +82,13 @@ def __init__(self) -> None:
8282
self._light = Photocell(board.LIGHT)
8383

8484
# Define touch:
85-
# Initially, self._touches stores the pin used for a particular touch. When that touch is
86-
# used for the first time, the pin is replaced with the corresponding TouchIn object.
87-
# This saves a little RAM over using a separate read-only pin tuple.
88-
# For example, after `cp.touch_A2`, self._touches is equivalent to:
89-
# [None, board.A1, touchio.TouchIn(board.A2), board.A3, ...]
90-
# Slot 0 is not used (A0 is not allowed as a touch pin).
91-
self._touches = [
92-
None,
93-
board.A1,
94-
board.A2,
95-
board.A3,
96-
board.A4,
97-
board.A5,
98-
board.A6,
99-
board.TX,
100-
]
85+
# Initially, self._touches is an empty dictionary. When a touch is used
86+
# for the first time, the pin is added as a key to the dictionary, with
87+
# the corresponding TouchIn object added as the value. This saves a
88+
# little RAM by only populating the dictionary as needed. For example,
89+
# after `cp.touch_A2`, self._touches is equivalent to:
90+
# { board.A2: TouchIn(board.A2) }
91+
self._touches = {}
10192
self._touch_threshold_adjustment = 0
10293

10394
# Define acceleration:
@@ -359,13 +350,14 @@ def shake(self, shake_threshold: int = 30) -> bool:
359350
"""
360351
return self._lis3dh.shake(shake_threshold=shake_threshold)
361352

362-
def _touch(self, i) -> bool:
363-
if not isinstance(self._touches[i], touchio.TouchIn):
364-
# First time referenced. Get the pin from the slot for this touch
365-
# and replace it with a TouchIn object for the pin.
366-
self._touches[i] = touchio.TouchIn(self._touches[i])
367-
self._touches[i].threshold += self._touch_threshold_adjustment
368-
return self._touches[i].value
353+
def _touch(self, pin: Pin) -> bool:
354+
touchin = self._touches.get(pin)
355+
if not touchin:
356+
# First time referenced. Make TouchIn object for the pin
357+
touchin = touchio.TouchIn(pin)
358+
touchin.threshold += self._touch_threshold_adjustment
359+
self._touches[pin] = touchin
360+
return touchin.value
369361

370362
# We chose these verbose touch_A# names so that beginners could use it without understanding
371363
# lists and the capital A to match the pin name. The capitalization is not strictly Python
@@ -387,7 +379,7 @@ def touch_A1(self) -> bool: # pylint: disable=invalid-name
387379
if cp.touch_A1:
388380
print('Touched pad A1')
389381
"""
390-
return self._touch(1)
382+
return self._touch(board.A1)
391383

392384
@property
393385
def touch_A2(self) -> bool: # pylint: disable=invalid-name
@@ -406,7 +398,7 @@ def touch_A2(self) -> bool: # pylint: disable=invalid-name
406398
if cp.touch_A2:
407399
print('Touched pad A2')
408400
"""
409-
return self._touch(2)
401+
return self._touch(board.A2)
410402

411403
@property
412404
def touch_A3(self) -> bool: # pylint: disable=invalid-name
@@ -425,7 +417,7 @@ def touch_A3(self) -> bool: # pylint: disable=invalid-name
425417
if cp.touch_A3:
426418
print('Touched pad A3')
427419
"""
428-
return self._touch(3)
420+
return self._touch(board.A3)
429421

430422
@property
431423
def touch_A4(self) -> bool: # pylint: disable=invalid-name
@@ -444,7 +436,7 @@ def touch_A4(self) -> bool: # pylint: disable=invalid-name
444436
if cp.touch_A4:
445437
print('Touched pad A4')
446438
"""
447-
return self._touch(4)
439+
return self._touch(board.A4)
448440

449441
@property
450442
def touch_A5(self) -> bool: # pylint: disable=invalid-name
@@ -463,7 +455,7 @@ def touch_A5(self) -> bool: # pylint: disable=invalid-name
463455
if cp.touch_A5:
464456
print('Touched pad A5')
465457
"""
466-
return self._touch(5)
458+
return self._touch(board.A5)
467459

468460
@property
469461
def touch_A6(self) -> bool: # pylint: disable=invalid-name
@@ -482,7 +474,7 @@ def touch_A6(self) -> bool: # pylint: disable=invalid-name
482474
if cp.touch_A6:
483475
print('Touched pad A6'
484476
"""
485-
return self._touch(6)
477+
return self._touch(board.A6)
486478

487479
@property
488480
def touch_TX(self) -> bool: # pylint: disable=invalid-name
@@ -502,7 +494,7 @@ def touch_TX(self) -> bool: # pylint: disable=invalid-name
502494
if cp.touch_A7:
503495
print('Touched pad A7')
504496
"""
505-
return self._touch(7)
497+
return self._touch(board.TX)
506498

507499
def adjust_touch_threshold(self, adjustment: int) -> None:
508500
"""Adjust the threshold needed to activate the capacitive touch pads.
@@ -525,11 +517,20 @@ def adjust_touch_threshold(self, adjustment: int) -> None:
525517
if cp.touch_A1:
526518
print('Touched pad A1')
527519
"""
528-
for touch_in in self._touches:
529-
if isinstance(touch_in, touchio.TouchIn):
530-
touch_in.threshold += adjustment
520+
for touch_in in self._touches.values():
521+
touch_in.threshold += adjustment
531522
self._touch_threshold_adjustment += adjustment
532523

524+
@property
525+
def touch_pins(self) -> List[Pin]:
526+
"""A list of all the pins that are set up as touchpad inputs"""
527+
return list(self._touches.keys())
528+
529+
@property
530+
def touched(self) -> List[Pin]:
531+
"""A list of all the pins that are currently registering a touch"""
532+
return [pin for pin, touchpad in self._touches.items() if touchpad.value]
533+
533534
@property
534535
def pixels(self) -> neopixel.NeoPixel:
535536
"""Sequence-like object representing the ten NeoPixels around the outside

examples/circuitplayground_touch_all.py

+28-14
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,34 @@
22
# SPDX-License-Identifier: MIT
33

44
"""This example prints to the serial console when you touch the capacitive touch pads."""
5+
import time
6+
import board
57
from adafruit_circuitplayground import cp
68

9+
10+
# You'll need to first use the touchpads individually to register them as active touchpads
11+
# You don't have to use the result though
12+
is_a1_touched = cp.touch_A1 # This result can be used if you want
13+
if is_a1_touched:
14+
print("A1 was touched upon startup!")
15+
is_a2_touched = cp.touch_A2
16+
is_a3_touched = cp.touch_A3
17+
is_a4_touched = cp.touch_A4
18+
19+
print("Pads that are currently setup as touchpads:")
20+
print(cp.touch_pins)
21+
722
while True:
8-
if cp.touch_A1:
9-
print("Touched pad A1")
10-
if cp.touch_A2:
11-
print("Touched pad A2")
12-
if cp.touch_A3:
13-
print("Touched pad A3")
14-
if cp.touch_A4:
15-
print("Touched pad A4")
16-
if cp.touch_A5:
17-
print("Touched pad A5")
18-
if cp.touch_A6:
19-
print("Touched pad A6")
20-
if cp.touch_TX:
21-
print("Touched pad TX")
23+
24+
current_touched = cp.touched
25+
26+
if current_touched:
27+
print("Touchpads currently registering a touch:")
28+
print(current_touched)
29+
else:
30+
print("No touchpads are currently registering a touch.")
31+
32+
if all(pad in current_touched for pad in (board.A2, board.A3, board.A4)):
33+
print("This only prints when A2, A3, and A4 are being held at the same time!")
34+
35+
time.sleep(0.25)

0 commit comments

Comments
 (0)