Skip to content

Commit

Permalink
Merge pull request #114 from tekktrik/dev/iterable-io-rework
Browse files Browse the repository at this point in the history
Add iterable touchpad functionality
  • Loading branch information
FoamyGuy committed Aug 24, 2022
2 parents a6f916a + dbfa322 commit 47f848f
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 48 deletions.
69 changes: 35 additions & 34 deletions adafruit_circuitplayground/circuit_playground_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
import touchio

try:
from typing import Optional, Iterator
from typing import Optional, Iterator, List
from typing_extensions import Literal
from microcontroller import Pin
except ImportError:
Expand Down Expand Up @@ -82,22 +82,13 @@ def __init__(self) -> None:
self._light = Photocell(board.LIGHT)

# Define touch:
# Initially, self._touches stores the pin used for a particular touch. When that touch is
# used for the first time, the pin is replaced with the corresponding TouchIn object.
# This saves a little RAM over using a separate read-only pin tuple.
# For example, after `cp.touch_A2`, self._touches is equivalent to:
# [None, board.A1, touchio.TouchIn(board.A2), board.A3, ...]
# Slot 0 is not used (A0 is not allowed as a touch pin).
self._touches = [
None,
board.A1,
board.A2,
board.A3,
board.A4,
board.A5,
board.A6,
board.TX,
]
# Initially, self._touches is an empty dictionary. When a touch is used
# for the first time, the pin is added as a key to the dictionary, with
# the corresponding TouchIn object added as the value. This saves a
# little RAM by only populating the dictionary as needed. For example,
# after `cp.touch_A2`, self._touches is equivalent to:
# { board.A2: TouchIn(board.A2) }
self._touches = {}
self._touch_threshold_adjustment = 0

# Define acceleration:
Expand Down Expand Up @@ -359,13 +350,14 @@ def shake(self, shake_threshold: int = 30) -> bool:
"""
return self._lis3dh.shake(shake_threshold=shake_threshold)

def _touch(self, i) -> bool:
if not isinstance(self._touches[i], touchio.TouchIn):
# First time referenced. Get the pin from the slot for this touch
# and replace it with a TouchIn object for the pin.
self._touches[i] = touchio.TouchIn(self._touches[i])
self._touches[i].threshold += self._touch_threshold_adjustment
return self._touches[i].value
def _touch(self, pin: Pin) -> bool:
touchin = self._touches.get(pin)
if not touchin:
# First time referenced. Make TouchIn object for the pin
touchin = touchio.TouchIn(pin)
touchin.threshold += self._touch_threshold_adjustment
self._touches[pin] = touchin
return touchin.value

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

@property
def touch_A2(self) -> bool: # pylint: disable=invalid-name
Expand All @@ -406,7 +398,7 @@ def touch_A2(self) -> bool: # pylint: disable=invalid-name
if cp.touch_A2:
print('Touched pad A2')
"""
return self._touch(2)
return self._touch(board.A2)

@property
def touch_A3(self) -> bool: # pylint: disable=invalid-name
Expand All @@ -425,7 +417,7 @@ def touch_A3(self) -> bool: # pylint: disable=invalid-name
if cp.touch_A3:
print('Touched pad A3')
"""
return self._touch(3)
return self._touch(board.A3)

@property
def touch_A4(self) -> bool: # pylint: disable=invalid-name
Expand All @@ -444,7 +436,7 @@ def touch_A4(self) -> bool: # pylint: disable=invalid-name
if cp.touch_A4:
print('Touched pad A4')
"""
return self._touch(4)
return self._touch(board.A4)

@property
def touch_A5(self) -> bool: # pylint: disable=invalid-name
Expand All @@ -463,7 +455,7 @@ def touch_A5(self) -> bool: # pylint: disable=invalid-name
if cp.touch_A5:
print('Touched pad A5')
"""
return self._touch(5)
return self._touch(board.A5)

@property
def touch_A6(self) -> bool: # pylint: disable=invalid-name
Expand All @@ -482,7 +474,7 @@ def touch_A6(self) -> bool: # pylint: disable=invalid-name
if cp.touch_A6:
print('Touched pad A6'
"""
return self._touch(6)
return self._touch(board.A6)

@property
def touch_TX(self) -> bool: # pylint: disable=invalid-name
Expand All @@ -502,7 +494,7 @@ def touch_TX(self) -> bool: # pylint: disable=invalid-name
if cp.touch_A7:
print('Touched pad A7')
"""
return self._touch(7)
return self._touch(board.TX)

def adjust_touch_threshold(self, adjustment: int) -> None:
"""Adjust the threshold needed to activate the capacitive touch pads.
Expand All @@ -525,11 +517,20 @@ def adjust_touch_threshold(self, adjustment: int) -> None:
if cp.touch_A1:
print('Touched pad A1')
"""
for touch_in in self._touches:
if isinstance(touch_in, touchio.TouchIn):
touch_in.threshold += adjustment
for touch_in in self._touches.values():
touch_in.threshold += adjustment
self._touch_threshold_adjustment += adjustment

@property
def touch_pins(self) -> List[Pin]:
"""A list of all the pins that are set up as touchpad inputs"""
return list(self._touches.keys())

@property
def touched(self) -> List[Pin]:
"""A list of all the pins that are currently registering a touch"""
return [pin for pin, touchpad in self._touches.items() if touchpad.value]

@property
def pixels(self) -> neopixel.NeoPixel:
"""Sequence-like object representing the ten NeoPixels around the outside
Expand Down
42 changes: 28 additions & 14 deletions examples/circuitplayground_touch_all.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,34 @@
# SPDX-License-Identifier: MIT

"""This example prints to the serial console when you touch the capacitive touch pads."""
import time
import board
from adafruit_circuitplayground import cp


# You'll need to first use the touchpads individually to register them as active touchpads
# You don't have to use the result though
is_a1_touched = cp.touch_A1 # This result can be used if you want
if is_a1_touched:
print("A1 was touched upon startup!")
is_a2_touched = cp.touch_A2
is_a3_touched = cp.touch_A3
is_a4_touched = cp.touch_A4

print("Pads that are currently setup as touchpads:")
print(cp.touch_pins)

while True:
if cp.touch_A1:
print("Touched pad A1")
if cp.touch_A2:
print("Touched pad A2")
if cp.touch_A3:
print("Touched pad A3")
if cp.touch_A4:
print("Touched pad A4")
if cp.touch_A5:
print("Touched pad A5")
if cp.touch_A6:
print("Touched pad A6")
if cp.touch_TX:
print("Touched pad TX")

current_touched = cp.touched

if current_touched:
print("Touchpads currently registering a touch:")
print(current_touched)
else:
print("No touchpads are currently registering a touch.")

if all(pad in current_touched for pad in (board.A2, board.A3, board.A4)):
print("This only prints when A2, A3, and A4 are being held at the same time!")

time.sleep(0.25)

0 comments on commit 47f848f

Please sign in to comment.