/ adafruit_focaltouch.py
adafruit_focaltouch.py
1 # The MIT License (MIT) 2 # 3 # Copyright (c) 2017 ladyada for adafruit industries 4 # 5 # Permission is hereby granted, free of charge, to any person obtaining a copy 6 # of this software and associated documentation files (the "Software"), to deal 7 # in the Software without restriction, including without limitation the rights 8 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 # copies of the Software, and to permit persons to whom the Software is 10 # furnished to do so, subject to the following conditions: 11 # 12 # The above copyright notice and this permission notice shall be included in 13 # all copies or substantial portions of the Software. 14 # 15 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 # THE SOFTWARE. 22 """ 23 `adafruit_focaltouch` 24 ==================================================== 25 26 CircuitPython driver for common low-cost FocalTech capacitive touch chips. 27 Currently supports FT6206 & FT6236. 28 29 * Author(s): ladyada 30 31 Implementation Notes 32 -------------------- 33 34 **Hardware:** 35 36 * Adafruit `2.8" TFT LCD with Cap Touch Breakout Board w/MicroSD Socket 37 <http://www.adafruit.com/product/2090>`_ (Product ID: 2090) 38 39 * Adafruit `2.8" TFT Touch Shield for Arduino w/Capacitive Touch 40 <http://www.adafruit.com/product/1947>`_ (Product ID: 1947) 41 42 **Software and Dependencies:** 43 44 * Adafruit CircuitPython firmware for the ESP8622 and M0-based boards: 45 https://github.com/adafruit/circuitpython/releases 46 * Adafruit's Bus Device library (when using I2C/SPI): 47 https://github.com/adafruit/Adafruit_CircuitPython_BusDevice 48 """ 49 50 # imports 51 52 __version__ = "0.0.0-auto.0" 53 __repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_FocalTouch.git" 54 55 try: 56 import struct 57 except ImportError: 58 import ustruct as struct 59 60 from adafruit_bus_device.i2c_device import I2CDevice 61 62 from micropython import const 63 64 65 _FT6206_DEFAULT_I2C_ADDR = 0x38 66 67 _FT6XXX_REG_DATA = const(0x00) 68 _FT6XXX_REG_NUMTOUCHES = const(0x02) 69 _FT6XXX_REG_THRESHHOLD = const(0x80) 70 _FT6XXX_REG_POINTRATE = const(0x88) 71 _FT6XXX_REG_LIBH = const(0xA1) 72 _FT6XXX_REG_LIBL = const(0xA2) 73 _FT6XXX_REG_CHIPID = const(0xA3) 74 _FT6XXX_REG_FIRMVERS = const(0xA6) 75 _FT6XXX_REG_VENDID = const(0xA8) 76 _FT6XXX_REG_RELEASE = const(0xAF) 77 78 79 class Adafruit_FocalTouch: 80 """ 81 A driver for the FocalTech capacitive touch sensor. 82 """ 83 84 _debug = False 85 chip = None 86 87 def __init__(self, i2c, address=_FT6206_DEFAULT_I2C_ADDR, debug=False): 88 self._i2c = I2CDevice(i2c, address) 89 self._debug = debug 90 91 chip_data = self._read(_FT6XXX_REG_LIBH, 8) 92 lib_ver, chip_id, _, _, firm_id, _, vend_id = struct.unpack( 93 ">HBBBBBB", chip_data 94 ) 95 96 if vend_id != 0x11: 97 raise RuntimeError("Did not find FT chip") 98 99 if chip_id == 0x06: 100 self.chip = "FT6206" 101 elif chip_id == 0x64: 102 self.chip = "FT6236" 103 104 if debug: 105 print("Library vers %04X" % lib_ver) 106 print("Firmware ID %02X" % firm_id) 107 print("Point rate %d Hz" % self._read(_FT6XXX_REG_POINTRATE, 1)[0]) 108 print("Thresh %d" % self._read(_FT6XXX_REG_THRESHHOLD, 1)[0]) 109 110 @property 111 def touched(self): 112 """ Returns the number of touches currently detected """ 113 return self._read(_FT6XXX_REG_NUMTOUCHES, 1)[0] 114 115 # pylint: disable=unused-variable 116 @property 117 def touches(self): 118 """ 119 Returns a list of touchpoint dicts, with 'x' and 'y' containing the 120 touch coordinates, and 'id' as the touch # for multitouch tracking 121 """ 122 touchpoints = [] 123 data = self._read(_FT6XXX_REG_DATA, 32) 124 125 for i in range(2): 126 point_data = data[i * 6 + 3 : i * 6 + 9] 127 if all([i == 0xFF for i in point_data]): 128 continue 129 # print([hex(i) for i in point_data]) 130 x, y, weight, misc = struct.unpack(">HHBB", point_data) 131 # print(x, y, weight, misc) 132 touch_id = y >> 12 133 x &= 0xFFF 134 y &= 0xFFF 135 point = {"x": x, "y": y, "id": touch_id} 136 touchpoints.append(point) 137 return touchpoints 138 139 # pylint: enable=unused-variable 140 141 def _read(self, register, length): 142 """Returns an array of 'length' bytes from the 'register'""" 143 with self._i2c as i2c: 144 i2c.write(bytes([register & 0xFF])) 145 result = bytearray(length) 146 i2c.readinto(result) 147 if self._debug: 148 print("\t$%02X => %s" % (register, [hex(i) for i in result])) 149 return result 150 151 def _write(self, register, values): 152 """Writes an array of 'length' bytes to the 'register'""" 153 with self._i2c as i2c: 154 values = [(v & 0xFF) for v in [register] + values] 155 i2c.write(bytes(values)) 156 if self._debug: 157 print("\t$%02X <= %s" % (values[0], [hex(i) for i in values[1:]]))