Skip to content

Commit 605dd1b

Browse files
authored
Merge pull request #7 from caternuson/iss6
Add threshold and sensitivity control
2 parents 231d053 + 7bf008f commit 605dd1b

File tree

3 files changed

+131
-37
lines changed

3 files changed

+131
-37
lines changed

adafruit_cap1188/cap1188.py

+81-26
Original file line numberDiff line numberDiff line change
@@ -48,31 +48,36 @@
4848
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_CAP1188.git"
4949

5050
# pylint: disable=bad-whitespace
51-
CAP1188_MID = const(0x5D)
52-
CAP1188_PID = const(0x50)
53-
CAP1188_MAIN_CONTROL = const(0x00)
54-
CAP1188_GENERAL_STATUS = const(0x02)
55-
CAP1188_INPUT_STATUS = const(0x03)
56-
CAP1188_LED_STATUS = const(0x04)
57-
CAP1188_NOISE_FLAGS = const(0x0A)
58-
CAP1188_DELTA_COUNT =(const(0x10),
51+
_CAP1188_MID = const(0x5D)
52+
_CAP1188_PID = const(0x50)
53+
_CAP1188_MAIN_CONTROL = const(0x00)
54+
_CAP1188_GENERAL_STATUS = const(0x02)
55+
_CAP1188_INPUT_STATUS = const(0x03)
56+
_CAP1188_LED_STATUS = const(0x04)
57+
_CAP1188_NOISE_FLAGS = const(0x0A)
58+
_CAP1188_DELTA_COUNT =(const(0x10),
5959
const(0x11),
6060
const(0x12),
6161
const(0x13),
6262
const(0x14),
6363
const(0x15),
6464
const(0x16),
6565
const(0x17))
66-
CAP1188_CAL_ACTIVATE = const(0x26)
67-
CAP1188_MULTI_TOUCH_CFG = const(0x2A)
68-
CAP1188_STANDBY_CFG = const(0x41)
69-
CAP1188_LED_LINKING = const(0x72)
70-
CAP1188_PRODUCT_ID = const(0xFD)
71-
CAP1188_MANU_ID = const(0xFE)
72-
CAP1188_REVISION = const(0xFF)
66+
_CAP1188_SENSITIVTY = const(0x1F)
67+
_CAP1188_CAL_ACTIVATE = const(0x26)
68+
_CAP1188_MULTI_TOUCH_CFG = const(0x2A)
69+
_CAP1188_THESHOLD_1 = const(0x30)
70+
_CAP1188_STANDBY_CFG = const(0x41)
71+
_CAP1188_LED_LINKING = const(0x72)
72+
_CAP1188_PRODUCT_ID = const(0xFD)
73+
_CAP1188_MANU_ID = const(0xFE)
74+
_CAP1188_REVISION = const(0xFF)
7375
# pylint: enable=bad-whitespace
7476

77+
_SENSITIVITY = (128, 64, 32, 16, 8, 4, 2, 1)
78+
7579
class CAP1188_Channel:
80+
# pylint: disable=protected-access
7681
"""Helper class to represent a touch channel on the CAP1188. Not meant to
7782
be used directly."""
7883
def __init__(self, cap1188, pin):
@@ -89,6 +94,18 @@ def raw_value(self):
8994
"""The raw touch measurement."""
9095
return self._cap1188.delta_count(self._pin)
9196

97+
@property
98+
def threshold(self):
99+
"""The touch threshold value."""
100+
return self._cap1188._read_register(_CAP1188_THESHOLD_1 + self._pin - 1)
101+
102+
@threshold.setter
103+
def threshold(self, value):
104+
value = int(value)
105+
if not 0 <= value <= 127:
106+
raise ValueError("Threshold value must be in range 0 to 127.")
107+
self._cap1188._write_register(_CAP1188_THESHOLD_1 + self._pin - 1, value)
108+
92109
def recalibrate(self):
93110
"""Perform a self recalibration."""
94111
self._cap1188.recalibrate_pins(1 << self._pin - 1)
@@ -97,15 +114,16 @@ def recalibrate(self):
97114
class CAP1188:
98115
"""CAP1188 driver base, must be extended for I2C/SPI interfacing."""
99116
def __init__(self):
100-
mid = self._read_register(CAP1188_MANU_ID)
101-
if mid != CAP1188_MID:
117+
mid = self._read_register(_CAP1188_MANU_ID)
118+
if mid != _CAP1188_MID:
102119
raise RuntimeError('Failed to find CAP1188! Manufacturer ID: 0x{:02x}'.format(mid))
103-
pid = self._read_register(CAP1188_PRODUCT_ID)
104-
if pid != CAP1188_PID:
120+
pid = self._read_register(_CAP1188_PRODUCT_ID)
121+
if pid != _CAP1188_PID:
105122
raise RuntimeError('Failed to find CAP1188! Product ID: 0x{:02x}'.format(pid))
106123
self._channels = [None]*8
107-
self._write_register(CAP1188_LED_LINKING, 0xFF) # turn on LED linking
108-
self._write_register(CAP1188_MULTI_TOUCH_CFG, 0x00) # allow multi touch
124+
self._write_register(_CAP1188_LED_LINKING, 0xFF) # turn on LED linking
125+
self._write_register(_CAP1188_MULTI_TOUCH_CFG, 0x00) # allow multi touch
126+
self._write_register(0x2F, 0x10) # turn off input-1-sets-all-inputs feature
109127
self.recalibrate()
110128

111129
def __getitem__(self, key):
@@ -126,10 +144,39 @@ def touched_pins(self):
126144
def touched(self):
127145
"""Return 8 bit value representing touch state of all pins."""
128146
# clear the INT bit and any previously touched pins
129-
current = self._read_register(CAP1188_MAIN_CONTROL)
130-
self._write_register(CAP1188_MAIN_CONTROL, current & ~0x01)
147+
current = self._read_register(_CAP1188_MAIN_CONTROL)
148+
self._write_register(_CAP1188_MAIN_CONTROL, current & ~0x01)
131149
# return only currently touched pins
132-
return self._read_register(CAP1188_INPUT_STATUS)
150+
return self._read_register(_CAP1188_INPUT_STATUS)
151+
152+
@property
153+
def sensitivity(self):
154+
"""The sensitvity of touch detections. Range is 1 (least) to 128 (most)."""
155+
return _SENSITIVITY[self._read_register(_CAP1188_SENSITIVTY) >> 4 & 0x07]
156+
157+
@sensitivity.setter
158+
def sensitivity(self, value):
159+
if value not in _SENSITIVITY:
160+
raise ValueError("Sensitivty must be one of: {}".format(_SENSITIVITY))
161+
value = _SENSITIVITY.index(value) << 4
162+
new_setting = self._read_register(_CAP1188_SENSITIVTY) & 0x8F | value
163+
self._write_register(_CAP1188_SENSITIVTY, new_setting)
164+
165+
@property
166+
def thresholds(self):
167+
"""Touch threshold value for all channels."""
168+
return self.threshold_values()
169+
170+
@thresholds.setter
171+
def thresholds(self, value):
172+
value = int(value)
173+
if not 0 <= value <= 127:
174+
raise ValueError("Threshold value must be in range 0 to 127.")
175+
self._write_block(_CAP1188_THESHOLD_1, bytearray((value,)*8))
176+
177+
def threshold_values(self):
178+
"""Return tuple of touch threshold values for all channels."""
179+
return tuple(self._read_block(_CAP1188_THESHOLD_1, 8))
133180

134181
def recalibrate(self):
135182
"""Perform a self recalibration on all the pins."""
@@ -140,13 +187,13 @@ def delta_count(self, pin):
140187
if pin < 1 or pin > 8:
141188
raise IndexError('Pin must be a value 1-8.')
142189
# 8 bit 2's complement
143-
raw_value = self._read_register(CAP1188_DELTA_COUNT[pin-1])
190+
raw_value = self._read_register(_CAP1188_DELTA_COUNT[pin-1])
144191
raw_value = raw_value - 256 if raw_value & 128 else raw_value
145192
return raw_value
146193

147194
def recalibrate_pins(self, mask):
148195
"""Recalibrate pins specified by bit mask."""
149-
self._write_register(CAP1188_CAL_ACTIVATE, mask)
196+
self._write_register(_CAP1188_CAL_ACTIVATE, mask)
150197

151198
def _read_register(self, address):
152199
"""Return 8 bit value of register at address."""
@@ -155,3 +202,11 @@ def _read_register(self, address):
155202
def _write_register(self, address, value):
156203
"""Write 8 bit value to registter at address."""
157204
raise NotImplementedError
205+
206+
def _read_block(self, start, length):
207+
"""Return byte array of values from start address to length."""
208+
raise NotImplementedError
209+
210+
def _write_block(self, start, data):
211+
"""Write out data beginning at start address."""
212+
raise NotImplementedError

adafruit_cap1188/i2c.py

+15-2
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,12 @@
5050
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_CAP1188.git"
5151

5252
# pylint: disable=bad-whitespace
53-
CAP1188_DEFAULT_ADDRESS = const(0x29)
53+
_CAP1188_DEFAULT_ADDRESS = const(0x29)
5454
# pylint: enable=bad-whitespace
5555

5656
class CAP1188_I2C(CAP1188):
5757
"""Driver for the CAP1188 connected over I2C."""
58-
def __init__(self, i2c, address=CAP1188_DEFAULT_ADDRESS):
58+
def __init__(self, i2c, address=_CAP1188_DEFAULT_ADDRESS):
5959
self._i2c = i2c_device.I2CDevice(i2c, address)
6060
self._buf = bytearray(2)
6161
super().__init__()
@@ -74,3 +74,16 @@ def _write_register(self, address, value):
7474
self._buf[1] = value
7575
with self._i2c as i2c:
7676
i2c.write(self._buf)
77+
78+
def _read_block(self, start, length):
79+
"""Return byte array of values from start address to length."""
80+
result = bytearray(length)
81+
with self._i2c as i2c:
82+
i2c.write(bytes((start,)))
83+
i2c.readinto(result)
84+
return result
85+
86+
def _write_block(self, start, data):
87+
"""Write out data beginning at start address."""
88+
with self._i2c as i2c:
89+
i2c.write(bytes((start,)) + data)

adafruit_cap1188/spi.py

+35-9
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,9 @@
5050
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_CAP1188.git"
5151

5252
# pylint: disable=bad-whitespace
53-
CAP1188_SPI_SET_ADDR = const(0x7D)
54-
CAP1188_SPI_WRITE_DATA = const(0x7E)
55-
CAP1188_SPI_READ_DATA = const(0x7F)
53+
_CAP1188_SPI_SET_ADDR = const(0x7D)
54+
_CAP1188_SPI_WRITE_DATA = const(0x7E)
55+
_CAP1188_SPI_READ_DATA = const(0x7F)
5656
# pylint: enable=bad-whitespace
5757

5858
class CAP1188_SPI(CAP1188):
@@ -63,19 +63,45 @@ def __init__(self, spi, cs):
6363
super().__init__()
6464

6565
def _read_register(self, address):
66+
# pylint: disable=no-member
6667
"""Return 8 bit value of register at address."""
67-
self._buf[0] = CAP1188_SPI_SET_ADDR
68+
self._buf[0] = _CAP1188_SPI_SET_ADDR
6869
self._buf[1] = address
69-
self._buf[2] = CAP1188_SPI_READ_DATA
70+
self._buf[2] = _CAP1188_SPI_READ_DATA
7071
with self._spi as spi:
71-
spi.write_readinto(self._buf, self._buf) # pylint: disable=no-member
72+
spi.write_readinto(self._buf, self._buf)
7273
return self._buf[3]
7374

7475
def _write_register(self, address, value):
76+
# pylint: disable=no-member
7577
"""Write 8 bit value to registter at address."""
76-
self._buf[0] = CAP1188_SPI_SET_ADDR
78+
self._buf[0] = _CAP1188_SPI_SET_ADDR
7779
self._buf[1] = address
78-
self._buf[2] = CAP1188_SPI_WRITE_DATA
80+
self._buf[2] = _CAP1188_SPI_WRITE_DATA
7981
self._buf[3] = value
8082
with self._spi as spi:
81-
spi.write(self._buf) # pylint: disable=no-member
83+
spi.write(self._buf)
84+
85+
def _read_block(self, start, length):
86+
# pylint: disable=no-member
87+
"""Return byte array of values from start address to length."""
88+
self._buf[0] = _CAP1188_SPI_SET_ADDR
89+
self._buf[1] = start
90+
self._buf[2] = _CAP1188_SPI_READ_DATA
91+
result = bytearray((_CAP1188_SPI_READ_DATA,)*length)
92+
with self._spi as spi:
93+
spi.write(self._buf, end=3)
94+
spi.write_readinto(result, result)
95+
return result
96+
97+
def _write_block(self, start, data):
98+
# pylint: disable=no-member
99+
"""Write out data beginning at start address."""
100+
self._buf[0] = _CAP1188_SPI_SET_ADDR
101+
self._buf[1] = start
102+
with self._spi as spi:
103+
spi.write(self._buf, end=2)
104+
self._buf[0] = _CAP1188_SPI_WRITE_DATA
105+
for value in data:
106+
self._buf[1] = value
107+
spi.write(self._buf, end=2)

0 commit comments

Comments
 (0)