From 702483ee453efc6c77797a4ee9bc953df8b06d9c Mon Sep 17 00:00:00 2001 From: Cedar Grove Maker Studios Date: Wed, 19 Jan 2022 23:17:22 -0800 Subject: [PATCH 01/17] Add Displayio Button compatibility --- adafruit_stmpe610.py | 771 ++++++++++++++++++++++++++----------------- 1 file changed, 468 insertions(+), 303 deletions(-) mode change 100644 => 100755 adafruit_stmpe610.py diff --git a/adafruit_stmpe610.py b/adafruit_stmpe610.py old mode 100644 new mode 100755 index 9862efa..dcd9a7b --- a/adafruit_stmpe610.py +++ b/adafruit_stmpe610.py @@ -1,303 +1,468 @@ -# SPDX-FileCopyrightText: 2017 Jerry Needell for Adafruit Industries -# -# SPDX-License-Identifier: MIT - -""" -`adafruit_stmpe610` -==================================================== - -This is a CircuitPython Driver for the STMPE610 Resistive Touch sensor - -* Author(s): Jerry Needell -""" - -# imports - -import time -from micropython import const - - -__version__ = "0.0.0-auto.0" -__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_STMPE610.git" - - -_STMPE_ADDR = const(0x41) -_STMPE_VERSION = const(0x0811) - -_STMPE_SYS_CTRL1 = const(0x03) -_STMPE_SYS_CTRL1_RESET = const(0x02) -_STMPE_SYS_CTRL2 = const(0x04) - -_STMPE_TSC_CTRL = const(0x40) -_STMPE_TSC_CTRL_EN = const(0x01) -_STMPE_TSC_CTRL_XYZ = const(0x00) -_STMPE_TSC_CTRL_XY = const(0x02) - -_STMPE_INT_CTRL = const(0x09) -_STMPE_INT_CTRL_POL_HIGH = const(0x04) -_STMPE_INT_CTRL_POL_LOW = const(0x00) -_STMPE_INT_CTRL_EDGE = const(0x02) -_STMPE_INT_CTRL_LEVEL = const(0x00) -_STMPE_INT_CTRL_ENABLE = const(0x01) -_STMPE_INT_CTRL_DISABLE = const(0x00) - - -_STMPE_INT_EN = const(0x0A) -_STMPE_INT_EN_TOUCHDET = const(0x01) -_STMPE_INT_EN_FIFOTH = const(0x02) -_STMPE_INT_EN_FIFOOF = const(0x04) -_STMPE_INT_EN_FIFOFULL = const(0x08) -_STMPE_INT_EN_FIFOEMPTY = const(0x10) -_STMPE_INT_EN_ADC = const(0x40) -_STMPE_INT_EN_GPIO = const(0x80) - -_STMPE_INT_STA = const(0x0B) -_STMPE_INT_STA_TOUCHDET = const(0x01) - -_STMPE_ADC_CTRL1 = const(0x20) -_STMPE_ADC_CTRL1_12BIT = const(0x08) -_STMPE_ADC_CTRL1_10BIT = const(0x00) - -_STMPE_ADC_CTRL2 = const(0x21) -_STMPE_ADC_CTRL2_1_625MHZ = const(0x00) -_STMPE_ADC_CTRL2_3_25MHZ = const(0x01) -_STMPE_ADC_CTRL2_6_5MHZ = const(0x02) - -_STMPE_TSC_CFG = const(0x41) -_STMPE_TSC_CFG_1SAMPLE = const(0x00) -_STMPE_TSC_CFG_2SAMPLE = const(0x40) -_STMPE_TSC_CFG_4SAMPLE = const(0x80) -_STMPE_TSC_CFG_8SAMPLE = const(0xC0) -_STMPE_TSC_CFG_DELAY_10US = const(0x00) -_STMPE_TSC_CFG_DELAY_50US = const(0x08) -_STMPE_TSC_CFG_DELAY_100US = const(0x10) -_STMPE_TSC_CFG_DELAY_500US = const(0x18) -_STMPE_TSC_CFG_DELAY_1MS = const(0x20) -_STMPE_TSC_CFG_DELAY_5MS = const(0x28) -_STMPE_TSC_CFG_DELAY_10MS = const(0x30) -_STMPE_TSC_CFG_DELAY_50MS = const(0x38) -_STMPE_TSC_CFG_SETTLE_10US = const(0x00) -_STMPE_TSC_CFG_SETTLE_100US = const(0x01) -_STMPE_TSC_CFG_SETTLE_500US = const(0x02) -_STMPE_TSC_CFG_SETTLE_1MS = const(0x03) -_STMPE_TSC_CFG_SETTLE_5MS = const(0x04) -_STMPE_TSC_CFG_SETTLE_10MS = const(0x05) -_STMPE_TSC_CFG_SETTLE_50MS = const(0x06) -_STMPE_TSC_CFG_SETTLE_100MS = const(0x07) - -_STMPE_FIFO_TH = const(0x4A) - -_STMPE_FIFO_SIZE = const(0x4C) - -_STMPE_FIFO_STA = const(0x4B) -_STMPE_FIFO_STA_RESET = const(0x01) -_STMPE_FIFO_STA_OFLOW = const(0x80) -_STMPE_FIFO_STA_FULL = const(0x40) -_STMPE_FIFO_STA_EMPTY = const(0x20) -_STMPE_FIFO_STA_THTRIG = const(0x10) - -_STMPE_TSC_I_DRIVE = const(0x58) -_STMPE_TSC_I_DRIVE_20MA = const(0x00) -_STMPE_TSC_I_DRIVE_50MA = const(0x01) - -_STMPE_TSC_DATA_X = const(0x4D) -_STMPE_TSC_DATA_Y = const(0x4F) -_STMPE_TSC_FRACTION_Z = const(0x56) - -_STMPE_GPIO_SET_PIN = const(0x10) -_STMPE_GPIO_CLR_PIN = const(0x11) -_STMPE_GPIO_DIR = const(0x13) -_STMPE_GPIO_ALT_FUNCT = const(0x17) - - -class Adafruit_STMPE610: - """ - A driver for the STMPE610 Resistive Touch sensor. - """ - - def __init__(self): - """Reset the controller""" - self._write_register_byte(_STMPE_SYS_CTRL1, _STMPE_SYS_CTRL1_RESET) - time.sleep(0.001) - - self._write_register_byte(_STMPE_SYS_CTRL2, 0x0) # turn on clocks! - self._write_register_byte( - _STMPE_TSC_CTRL, _STMPE_TSC_CTRL_XYZ | _STMPE_TSC_CTRL_EN - ) # XYZ and enable! - self._write_register_byte(_STMPE_INT_EN, _STMPE_INT_EN_TOUCHDET) - self._write_register_byte( - _STMPE_ADC_CTRL1, _STMPE_ADC_CTRL1_10BIT | (0x6 << 4) - ) # 96 clocks per conversion - self._write_register_byte(_STMPE_ADC_CTRL2, _STMPE_ADC_CTRL2_6_5MHZ) - self._write_register_byte( - _STMPE_TSC_CFG, - _STMPE_TSC_CFG_4SAMPLE - | _STMPE_TSC_CFG_DELAY_1MS - | _STMPE_TSC_CFG_SETTLE_5MS, - ) - self._write_register_byte(_STMPE_TSC_FRACTION_Z, 0x6) - self._write_register_byte(_STMPE_FIFO_TH, 1) - self._write_register_byte(_STMPE_FIFO_STA, _STMPE_FIFO_STA_RESET) - self._write_register_byte(_STMPE_FIFO_STA, 0) # unreset - self._write_register_byte(_STMPE_TSC_I_DRIVE, _STMPE_TSC_I_DRIVE_50MA) - self._write_register_byte(_STMPE_INT_STA, 0xFF) # reset all ints - self._write_register_byte( - _STMPE_INT_CTRL, _STMPE_INT_CTRL_POL_HIGH | _STMPE_INT_CTRL_ENABLE - ) - - def read_data(self): - """Request next stored reading - return tuple containing (x,y,pressure) """ - d_1 = self._read_byte(0xD7) - d_2 = self._read_byte(0xD7) - d_3 = self._read_byte(0xD7) - d_4 = self._read_byte(0xD7) - x_loc = d_1 << 4 | d_2 >> 4 - y_loc = (d_2 & 0xF) << 8 | d_3 - pressure = d_4 - # reset all ints (not sure what this does) - if self.buffer_empty: - self._write_register_byte(_STMPE_INT_STA, 0xFF) - return (x_loc, y_loc, pressure) - - def _read_byte(self, register): - """Read a byte register value and return it""" - return self._read_register(register, 1)[0] - - def _read_register(self, register, length): - # Read an arbitrarily long register (specified by length number of - # bytes) and return a bytearray of the retrieved data. - # Subclasses MUST implement this! - raise NotImplementedError - - def _write_register_byte(self, register, value): - # Write a single byte register at the specified register address. - # Subclasses MUST implement this! - raise NotImplementedError - - @property - def touches(self): - """ - Returns a list of touchpoint dicts, with 'x' and 'y' containing the - touch coordinates, and 'pressure' - """ - touchpoints = [] - while (len(touchpoints) < 4) and not self.buffer_empty: - (x_loc, y_loc, pressure) = self.read_data() - point = {"x": x_loc, "y": y_loc, "pressure": pressure} - touchpoints.append(point) - return touchpoints - - @property - def get_version(self): - "Read the version number from the sensosr" - v_1 = self._read_byte(0) - v_2 = self._read_byte(1) - version = v_1 << 8 | v_2 - # print("version ",hex(version)) - return version - - @property - def touched(self): - "Report if any touches have been detectd" - touch = self._read_byte(_STMPE_TSC_CTRL) & 0x80 - return touch == 0x80 - - @property - def buffer_size(self): - "The amount of touch data in the buffer" - return self._read_byte(_STMPE_FIFO_SIZE) - - @property - def buffer_empty(self): - "Buffer empty status" - empty = self._read_byte(_STMPE_FIFO_STA) & _STMPE_FIFO_STA_EMPTY - return empty != 0 - - @property - def get_point(self): - "Read one touch from the buffer" - (x_loc, y_loc, pressure) = self.read_data() - point = {"x": x_loc, "y": y_loc, "pressure": pressure} - return point - - -class Adafruit_STMPE610_I2C(Adafruit_STMPE610): - """ - I2C driver for the STMPE610 Resistive Touch sensor. - """ - - def __init__(self, i2c, address=_STMPE_ADDR): - """ - Check the STMPE610 was founnd - Default address is 0x41 but another address can be passed in as an argument - """ - import adafruit_bus_device.i2c_device as i2cdev # pylint: disable=import-outside-toplevel - - self._i2c = i2cdev.I2CDevice(i2c, address) - # Check device version. - version = self.get_version - if _STMPE_VERSION != version: - raise RuntimeError("Failed to find STMPE610! Chip Version 0x%x" % version) - super().__init__() - - def _read_register(self, register, length): - """Low level register reading over I2C, returns a list of values""" - with self._i2c as i2c: - i2c.write(bytearray([register & 0xFF])) - result = bytearray(length) - i2c.readinto(result) - # print("$%02X => %s" % (register, [hex(i) for i in result])) - return result - - def _write_register_byte(self, register, value): - """Low level register writing over I2C, writes one 8-bit value""" - with self._i2c as i2c: - i2c.write(bytes([register & 0xFF, value & 0xFF])) - # print("$%02X <= 0x%02X" % (register, value)) - - -class Adafruit_STMPE610_SPI(Adafruit_STMPE610): - """ - SPI driver for the STMPE610 Resistive Touch sensor. - """ - - def __init__(self, spi, cs, baudrate=1000000): - """ - Check the STMPE610 was found,Default clock rate 1000000 - can be changed with 'baudrate' - """ - import adafruit_bus_device.spi_device as spidev # pylint: disable=import-outside-toplevel - - self._spi = spidev.SPIDevice(spi, cs, baudrate=baudrate) - # Check device version. - version = self.get_version - if _STMPE_VERSION != version: - # if it fails try SPI MODE 1 -- that is what Arduino does - self._spi = spidev.SPIDevice( - spi, cs, baudrate=baudrate, polarity=0, phase=1 - ) - version = self.get_version - if _STMPE_VERSION != version: - raise RuntimeError( - "Failed to find STMPE610! Chip Version 0x%x. " - "If you are using the breakout, verify you are in SPI mode." - % version - ) - super().__init__() - - # pylint: disable=no-member - # Disable should be reconsidered when refactor can be tested. - def _read_register(self, register, length): - """Low level register reading over SPI, returns a list of values""" - register = (register | 0x80) & 0xFF # Read single, bit 7 high. - with self._spi as spi: - spi.write(bytearray([register])) - result = bytearray(length) - spi.readinto(result) - # print("$%02X => %s" % (register, [hex(i) for i in result])) - return result - - def _write_register_byte(self, register, value): - """Low level register writing over SPI, writes one 8-bit value""" - register &= 0x7F # Write, bit 7 low. - with self._spi as spi: - spi.write(bytes([register, value & 0xFF])) +# SPDX-FileCopyrightText: 2017 Jerry Needell for Adafruit Industries +# +# SPDX-License-Identifier: MIT +""" +`adafruit_stmpe610` +==================================================== +This is a CircuitPython Driver for the STMPE610 Resistive Touch sensor + +* Author(s): Jerry Needell + +Implementation Notes +-------------------- +**Hardware:** + +**Software and Dependencies:** + +* Adafruit CircuitPython firmware for the supported boards: + https://github.com/adafruit/circuitpython/releases +""" + +# imports + +import time +from micropython import const + + +__version__ = "1.2.7" +__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_STMPE610.git" + + +def map_range(x, in_min, in_max, out_min, out_max): + """ + Maps a value from one range to another. Values beyond the input minimum or + maximum will be limited to the minimum or maximum of the output range. + + :return: Returns value mapped to new range + :rtype: float + """ + in_range = in_max - in_min + in_delta = x - in_min + if in_range != 0: + mapped = in_delta / in_range + elif in_delta != 0: + mapped = in_delta + else: + mapped = 0.5 + mapped *= out_max - out_min + mapped += out_min + if out_min <= out_max: + return max(min(mapped, out_max), out_min) + return min(max(mapped, out_max), out_min) + + +_STMPE_ADDR = const(0x41) +_STMPE_VERSION = const(0x0811) + +_STMPE_SYS_CTRL1 = const(0x03) +_STMPE_SYS_CTRL1_RESET = const(0x02) +_STMPE_SYS_CTRL2 = const(0x04) + +_STMPE_TSC_CTRL = const(0x40) +_STMPE_TSC_CTRL_EN = const(0x01) +_STMPE_TSC_CTRL_XYZ = const(0x00) +_STMPE_TSC_CTRL_XY = const(0x02) + +_STMPE_INT_CTRL = const(0x09) +_STMPE_INT_CTRL_POL_HIGH = const(0x04) +_STMPE_INT_CTRL_POL_LOW = const(0x00) +_STMPE_INT_CTRL_EDGE = const(0x02) +_STMPE_INT_CTRL_LEVEL = const(0x00) +_STMPE_INT_CTRL_ENABLE = const(0x01) +_STMPE_INT_CTRL_DISABLE = const(0x00) + + +_STMPE_INT_EN = const(0x0A) +_STMPE_INT_EN_TOUCHDET = const(0x01) +_STMPE_INT_EN_FIFOTH = const(0x02) +_STMPE_INT_EN_FIFOOF = const(0x04) +_STMPE_INT_EN_FIFOFULL = const(0x08) +_STMPE_INT_EN_FIFOEMPTY = const(0x10) +_STMPE_INT_EN_ADC = const(0x40) +_STMPE_INT_EN_GPIO = const(0x80) + +_STMPE_INT_STA = const(0x0B) +_STMPE_INT_STA_TOUCHDET = const(0x01) + +_STMPE_ADC_CTRL1 = const(0x20) +_STMPE_ADC_CTRL1_12BIT = const(0x08) +_STMPE_ADC_CTRL1_10BIT = const(0x00) + +_STMPE_ADC_CTRL2 = const(0x21) +_STMPE_ADC_CTRL2_1_625MHZ = const(0x00) +_STMPE_ADC_CTRL2_3_25MHZ = const(0x01) +_STMPE_ADC_CTRL2_6_5MHZ = const(0x02) + +_STMPE_TSC_CFG = const(0x41) +_STMPE_TSC_CFG_1SAMPLE = const(0x00) +_STMPE_TSC_CFG_2SAMPLE = const(0x40) +_STMPE_TSC_CFG_4SAMPLE = const(0x80) +_STMPE_TSC_CFG_8SAMPLE = const(0xC0) +_STMPE_TSC_CFG_DELAY_10US = const(0x00) +_STMPE_TSC_CFG_DELAY_50US = const(0x08) +_STMPE_TSC_CFG_DELAY_100US = const(0x10) +_STMPE_TSC_CFG_DELAY_500US = const(0x18) +_STMPE_TSC_CFG_DELAY_1MS = const(0x20) +_STMPE_TSC_CFG_DELAY_5MS = const(0x28) +_STMPE_TSC_CFG_DELAY_10MS = const(0x30) +_STMPE_TSC_CFG_DELAY_50MS = const(0x38) +_STMPE_TSC_CFG_SETTLE_10US = const(0x00) +_STMPE_TSC_CFG_SETTLE_100US = const(0x01) +_STMPE_TSC_CFG_SETTLE_500US = const(0x02) +_STMPE_TSC_CFG_SETTLE_1MS = const(0x03) +_STMPE_TSC_CFG_SETTLE_5MS = const(0x04) +_STMPE_TSC_CFG_SETTLE_10MS = const(0x05) +_STMPE_TSC_CFG_SETTLE_50MS = const(0x06) +_STMPE_TSC_CFG_SETTLE_100MS = const(0x07) + +_STMPE_FIFO_TH = const(0x4A) + +_STMPE_FIFO_SIZE = const(0x4C) + +_STMPE_FIFO_STA = const(0x4B) +_STMPE_FIFO_STA_RESET = const(0x01) +_STMPE_FIFO_STA_OFLOW = const(0x80) +_STMPE_FIFO_STA_FULL = const(0x40) +_STMPE_FIFO_STA_EMPTY = const(0x20) +_STMPE_FIFO_STA_THTRIG = const(0x10) + +_STMPE_TSC_I_DRIVE = const(0x58) +_STMPE_TSC_I_DRIVE_20MA = const(0x00) +_STMPE_TSC_I_DRIVE_50MA = const(0x01) + +_STMPE_TSC_DATA_X = const(0x4D) +_STMPE_TSC_DATA_Y = const(0x4F) +_STMPE_TSC_FRACTION_Z = const(0x56) + +_STMPE_GPIO_SET_PIN = const(0x10) +_STMPE_GPIO_CLR_PIN = const(0x11) +_STMPE_GPIO_DIR = const(0x13) +_STMPE_GPIO_ALT_FUNCT = const(0x17) + + +class Adafruit_STMPE610: + """A class (driver) for the STMPE610 Resistive Touch controller used by the + 2.4" 320x240 TFT FeatherWing display (#3315), 3.5" 480x320 TFT FeatherWing + display (#3651), and the Resistive Touch Screen Controller - STMPE610 + breakout board (#1571). This class acts as a super class for the I2C and + SPI interface classes. + + This class was modified from the original to add the Displayio Button + compatible touch_point property to the existing functionality. + + See the examples folder for instantiation kwargs and properties.""" + + def __init__(self): + """Check the touchscreen calibration and display size kwargs from the + I2C or SPI interface class then reset the controller.""" + if not self._calib: + self._calib = ((0, 4095), (0, 4095)) + if not self._disp_size: + self._disp_size = (4095, 4095) + + if not self._disp_rotation in (0, 90, 180, 270): + raise ValueError("Display rotation value must be 0, 90, 180, or 270") + + self._write_register_byte(_STMPE_SYS_CTRL1, _STMPE_SYS_CTRL1_RESET) + time.sleep(0.001) + + self._write_register_byte(_STMPE_SYS_CTRL2, 0x0) # turn on clocks! + self._write_register_byte( + _STMPE_TSC_CTRL, _STMPE_TSC_CTRL_XYZ | _STMPE_TSC_CTRL_EN + ) # XYZ and enable! + self._write_register_byte(_STMPE_INT_EN, _STMPE_INT_EN_TOUCHDET) + self._write_register_byte( + _STMPE_ADC_CTRL1, _STMPE_ADC_CTRL1_10BIT | (0x6 << 4) + ) # 96 clocks per conversion + self._write_register_byte(_STMPE_ADC_CTRL2, _STMPE_ADC_CTRL2_6_5MHZ) + self._write_register_byte( + _STMPE_TSC_CFG, + _STMPE_TSC_CFG_4SAMPLE + | _STMPE_TSC_CFG_DELAY_1MS + | _STMPE_TSC_CFG_SETTLE_5MS, + ) + self._write_register_byte(_STMPE_TSC_FRACTION_Z, 0x6) + self._write_register_byte(_STMPE_FIFO_TH, 1) + self._write_register_byte(_STMPE_FIFO_STA, _STMPE_FIFO_STA_RESET) + self._write_register_byte(_STMPE_FIFO_STA, 0) # Unreset + self._write_register_byte(_STMPE_TSC_I_DRIVE, _STMPE_TSC_I_DRIVE_50MA) + self._write_register_byte(_STMPE_INT_STA, 0xFF) # Reset all ints + self._write_register_byte( + _STMPE_INT_CTRL, _STMPE_INT_CTRL_POL_HIGH | _STMPE_INT_CTRL_ENABLE + ) + + def read_data(self): + """Request next stored reading - return tuple containing (x,y,pressure).""" + d_1 = self._read_byte(0xD7) + d_2 = self._read_byte(0xD7) + d_3 = self._read_byte(0xD7) + d_4 = self._read_byte(0xD7) + x_loc = d_1 << 4 | d_2 >> 4 + y_loc = (d_2 & 0xF) << 8 | d_3 + pressure = d_4 + # Reset all ints (not sure what this does) + if self.buffer_empty: + self._write_register_byte(_STMPE_INT_STA, 0xFF) + return (x_loc, y_loc, pressure) + + def _read_byte(self, register): + """Read a byte register value and return it.""" + return self._read_register(register, 1)[0] + + def _read_register(self, register, length): + """Read an arbitrarily long register (specified by length number of + bytes) and return a bytearray of the retrieved data. + Subclasses MUST implement this!""" + raise NotImplementedError + + def _write_register_byte(self, register, value): + """Write a single byte register at the specified register address. + Subclasses MUST implement this!""" + raise NotImplementedError + + @property + def touches(self): + """Returns a list of touchpoint dicts, with 'x' and 'y' containing the + touch coordinates, and 'pressure'.""" + touchpoints = [] + while (len(touchpoints) < 4) and not self.buffer_empty: + (x_loc, y_loc, pressure) = self.read_data() + point = {"x": x_loc, "y": y_loc, "pressure": pressure} + touchpoints.append(point) + return touchpoints + + @property + def get_version(self): + """Read the version number from the sensor.""" + v_1 = self._read_byte(0) + v_2 = self._read_byte(1) + version = v_1 << 8 | v_2 + # print("version ",hex(version)) + return version + + @property + def touched(self): + """Report if any touches were detected.""" + touch = self._read_byte(_STMPE_TSC_CTRL) & 0x80 + return touch == 0x80 + + @property + def buffer_size(self): + """The amount of touch data in the buffer.""" + return self._read_byte(_STMPE_FIFO_SIZE) + + @property + def buffer_empty(self): + """Buffer empty status.""" + empty = self._read_byte(_STMPE_FIFO_STA) & _STMPE_FIFO_STA_EMPTY + return empty != 0 + + @property + def get_point(self): + """Read one touch from the buffer.""" + (x_loc, y_loc, pressure) = self.read_data() + point = {"x": x_loc, "y": y_loc, "pressure": pressure} + return point + + @property + def touch_point(self): + """Read latest touched point value and convert to calibration-adjusted + and rotated display coordinates. Commpatible with Displayio Button. + :return: x, y, pressure + rtype: int, int, int + """ + if not self.buffer_empty: + while not self.buffer_empty: + x_loc, y_loc, pressure = self.read_data() + # Swap touch axis range minimum and maximum if needed + if self._disp_rotation in (0, 180): + if self._touch_flip and self._touch_flip[0]: + x_c = (self._calib[0][1], self._calib[0][0]) + else: + x_c = (self._calib[0][0], self._calib[0][1]) + if self._touch_flip and self._touch_flip[1]: + y_c = (self._calib[1][1], self._calib[1][0]) + else: + y_c = (self._calib[1][0], self._calib[1][1]) + if self._disp_rotation in (90, 270): + if self._touch_flip[1]: + x_c = (self._calib[1][1], self._calib[1][0]) + else: + x_c = (self._calib[1][0], self._calib[1][1]) + if self._touch_flip[0]: + y_c = (self._calib[0][1], self._calib[0][0]) + else: + y_c = (self._calib[0][0], self._calib[0][1]) + # Adjust to calibration range; convert to display size and rotation + if self._disp_rotation == 0: + x = int(map_range(y_loc, x_c[0], x_c[1], 0, self._disp_size[0])) + y = int(map_range(x_loc, y_c[0], y_c[1], 0, self._disp_size[1])) + elif self._disp_rotation == 90: + x = int(map_range(x_loc, x_c[0], x_c[1], 0, self._disp_size[0])) + y = int(map_range(y_loc, y_c[0], y_c[1], self._disp_size[1], 0)) + elif self._disp_rotation == 180: + x = int(map_range(y_loc, x_c[0], x_c[1], self._disp_size[0], 0)) + y = int(map_range(x_loc, y_c[0], y_c[1], self._disp_size[1], 0)) + elif self._disp_rotation == 270: + x = int(map_range(x_loc, x_c[0], x_c[1], self._disp_size[0], 0)) + y = int(map_range(y_loc, y_c[0], y_c[1], 0, self._disp_size[1])) + return (x, y, pressure) + return None + + +class Adafruit_STMPE610_I2C(Adafruit_STMPE610): + """I2C interface class for the STMPE610 Resistive Touch sensor. + + :param i2c: I2C interface bus + :param int address: I2C address. Defaults to 0x41 + :param None, (int, int) calibration: touchscreen calibration tuple. + Defaults to None. + :param None, (int, int) size: display size tuple (width, height). + Defaults to None. + :param int disp_rotation: display rotation in degrees. Values allowed are + 0, 90, 180, and 270. Defaults to 0. + :param (bool, bool) touch_flip: swap touchscreen axis range minimum and + maximum values for (x, y) axes as referenced to display 0-degree rotation. + Defaults to (False, False). + + ** Quickstart: Importing and instantiating Adafruit_STMPE610_I2C** + + Import the Adafruit_STMPE610_I2C class and instantiate for the 2.4" TFT Wing + after instantiating the display: + + .. code-block:: python + + import adafruit_stmpe610 + ts = adafruit_stmpe610.Adafruit_STMPE610_I2C(board.I2C(), address=0x41, + calibration=((357, 3812), (390, 3555)), + size=(display.width, display.height), disp_rotation=display.rotation, + touch_flip=(False, False)) + + """ + def __init__( + self, + i2c, + address=_STMPE_ADDR, + calibration=None, + size=None, + disp_rotation=0, + touch_flip=(False, False), + ): + + self._calib = calibration + self._disp_size = size + self._disp_rotation = disp_rotation + self._touch_flip = touch_flip + + """Check that the STMPE610 was found.""" + import adafruit_bus_device.i2c_device as i2cdev # pylint: disable=import-outside-toplevel + + self._i2c = i2cdev.I2CDevice(i2c, address) + # Check device version. + version = self.get_version + if _STMPE_VERSION != version: + raise RuntimeError("Failed to find STMPE610! Chip Version 0x%x" % version) + super().__init__() + + def _read_register(self, register, length): + """Low level register reading over I2C, returns a list of values.""" + with self._i2c as i2c: + i2c.write(bytearray([register & 0xFF])) + result = bytearray(length) + i2c.readinto(result) + # print("$%02X => %s" % (register, [hex(i) for i in result])) + return result + + def _write_register_byte(self, register, value): + """Low level register writing over I2C, writes one 8-bit value.""" + with self._i2c as i2c: + i2c.write(bytes([register & 0xFF, value & 0xFF])) + # print("$%02X <= 0x%02X" % (register, value)) + + +class Adafruit_STMPE610_SPI(Adafruit_STMPE610): + """SPI interface class for the STMPE610 Resistive Touch sensor. + + :param spi: SPI interface bus + :param pin cs: touchscreen SPI interface chip select pin + :param int baudrate: SPI interface clock speed in Hz. + Defaults to 1000000 (1MHz). + :param None, (int, int) calibration: touchscreen calibration tuple. + Defaults to None. + :param None, (int, int) size: display size tuple (width, height). + Defaults to None. + :param int disp_rotation: display rotation in degrees. Values allowed are + 0, 90, 180, and 270. Defaults to 0. + :param (bool, bool) touch_flip: swap touchscreen axis range minimum and + maximum values for (x, y) axes as referenced to display 0-degree rotation. + Defaults to (False, False). + + ** Quickstart: Importing and instantiating Adafruit_STMPE610_I2C** + + Import the Adafruit_STMPE610_SPI class and instantiate for the 2.4" TFT Wing + after instantiating the display: + + .. code-block:: python + + import adafruit_stmpe610 + ts = adafruit_stmpe610.Adafruit_STMPE610_SPI(spi, cs=cs_pin, + baudrate=1000000, + calibration=((357, 3812), (390, 3555)), + size=(display.width, display.height), disp_rotation=display.rotation, + touch_flip=(False, False)) + + """ + + def __init__( + self, + spi, + cs, + baudrate=1000000, + calibration=None, + size=None, + disp_rotation=0, + touch_flip=(False, False), + ): + + self._calib = calibration + self._disp_size = size + self._disp_rotation = disp_rotation + self._touch_flip = touch_flip + + """Check that the STMPE610 was found.""" + import adafruit_bus_device.spi_device as spidev # pylint: disable=import-outside-toplevel + + self._spi = spidev.SPIDevice(spi, cs, baudrate=baudrate) + # Check device version. + version = self.get_version + if _STMPE_VERSION != version: + # If it fails try SPI MODE 1 -- that is what Arduino does + self._spi = spidev.SPIDevice( + spi, cs, baudrate=baudrate, polarity=0, phase=1 + ) + version = self.get_version + if _STMPE_VERSION != version: + raise RuntimeError( + "Failed to find STMPE610 controller! Chip Version 0x%x. " + "If you are using the breakout, verify you are in SPI mode." + % version + ) + super().__init__() + + # pylint: disable=no-member + # Disable should be reconsidered when refactor can be tested. + def _read_register(self, register, length): + """Low level register reading over SPI, returns a list of values.""" + register = (register | 0x80) & 0xFF # Read single byte, bit 7 high. + with self._spi as spi: + spi.write(bytearray([register])) + result = bytearray(length) + spi.readinto(result) + # print("$%02X => %s" % (register, [hex(i) for i in result])) + return result + + def _write_register_byte(self, register, value): + """Low level register writing over SPI, writes one 8-bit value.""" + register &= 0x7F # Write, bit 7 low. + with self._spi as spi: + spi.write(bytes([register, value & 0xFF])) From 11103fd5ec7b40a47c1efb5ba6f6610902f3b313 Mon Sep 17 00:00:00 2001 From: Cedar Grove Maker Studios Date: Thu, 20 Jan 2022 13:27:01 -0800 Subject: [PATCH 02/17] add button example and touch_calibrator module --- examples/stmpe610_button_demo.py | 87 ++++++++++++ examples/touch_calibrator_stmpe610.py | 188 ++++++++++++++++++++++++++ 2 files changed, 275 insertions(+) create mode 100755 examples/stmpe610_button_demo.py create mode 100755 examples/touch_calibrator_stmpe610.py diff --git a/examples/stmpe610_button_demo.py b/examples/stmpe610_button_demo.py new file mode 100755 index 0000000..bbf54fd --- /dev/null +++ b/examples/stmpe610_button_demo.py @@ -0,0 +1,87 @@ +# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries +# SPDX-License-Identifier: MIT +""" +Simple button demonstration/example. +STMPE610 touch controller with TFT FeatherWing Display +""" + +import board +import digitalio +import displayio +import terminalio +import time +import adafruit_stmpe610 +from adafruit_button import Button + +# --| Button Config |------------------------------------------------- +BUTTON_X = 50 +BUTTON_Y = 50 +BUTTON_WIDTH = 100 +BUTTON_HEIGHT = 50 +BUTTON_STYLE = Button.ROUNDRECT +BUTTON_FILL_COLOR = 0x00FFFF +BUTTON_OUTLINE_COLOR = 0xFF00FF +BUTTON_LABEL = "HELLO WORLD" +BUTTON_LABEL_COLOR = 0x000000 +# --| Button Config |------------------------------------------------- + +# Release any resources currently in use for the displays +displayio.release_displays() +disp_bus = displayio.FourWire(board.SPI(), command=board.D10, chip_select=board.D9, reset=None) + +# Instantiate the 2.4" 320x240 TFT FeatherWing (#3315). +from adafruit_ili9341 import ILI9341 +display = ILI9341(disp_bus, width=320, height=240) +_touch_flip = (False, False) + +"""# Instantiate the 3.5" 480x320 TFT FeatherWing (#3651). +from adafruit_hx8357 import HX8357 +display = HX8357(display_bus, width=480, height=320) +_touch_flip = (False, True)""" + +# Always set rotation before instantiating the touchscreen +display.rotation = 0 + +# Instantiate touchscreen +ts_cs = digitalio.DigitalInOut(board.D6) +ts = adafruit_stmpe610.Adafruit_STMPE610_SPI( + board.SPI(), + ts_cs, + calibration=((357, 3812), (390, 3555)), + size=(display.width, display.height), + disp_rotation=display.rotation, touch_flip=_touch_flip +) + +# Create the displayio group and show it +splash = displayio.Group() +display.show(splash) + +# Defiine the button +button = Button( + x=BUTTON_X, + y=BUTTON_Y, + width=BUTTON_WIDTH, + height=BUTTON_HEIGHT, + style=BUTTON_STYLE, + fill_color=BUTTON_FILL_COLOR, + outline_color=BUTTON_OUTLINE_COLOR, + label=BUTTON_LABEL, + label_font=terminalio.FONT, + label_color=BUTTON_LABEL_COLOR, +) + +# Add button to the displayio group +splash.append(button) + +# Loop and look for touches +while True: + p = ts.touch_point + if p: + if button.contains(p): + button.selected = True + # Perform a task related to the button press here + time.sleep(0.25) # Wait a bit so we can see the button color change + else: + button.selected = False # When touch moves outside of button + else: + button.selected = False # When button is released diff --git a/examples/touch_calibrator_stmpe610.py b/examples/touch_calibrator_stmpe610.py new file mode 100755 index 0000000..99647f3 --- /dev/null +++ b/examples/touch_calibrator_stmpe610.py @@ -0,0 +1,188 @@ +# SPDX-FileCopyrightText: 2022 Cedar Grove Maker Studios +# SPDX-License-Identifier: MIT + +""" +touch_calibrator_stmpe610.py 2022-01-20 v1.0 + +Author(s): JG for Cedar Grove Maker Studios + +On-screen touchscreen calibrator for TFT FeatherWing displays. + +When the test screen appears, use a stylus to swipe to the four edges +of the visible display area. As the screen is calibrated, the small red +square tracks the stylus tip (REPL_ONLY=False). Minimum and maximum +calibration values will display on the screen and in the REPL. The calibration +tuple can be copied and pasted into the calling code's touchscreen +instantiation statement. + +DISPLAY_ROTATION: Display rotation value in degrees. Only values of +None, 0, 90, 180, and 270 degrees are accepted. Defaults to None, the +previous orientation of the display. + +REPL_ONLY: If False, calibration values are shown graphically on the screen +and printed to the REPL. If True, the values are only printed to the REPL. +Default value is False. + +RAW_DATA: If True, measure and display the raw touchscreen values. If False, +display the touch value in screen coordinates; requires a previously measured +calibration tuple for screen coordinate conversion accuracy. +""" + +import board +import time +import digitalio +import displayio +import vectorio +from adafruit_bitmap_font import bitmap_font +from adafruit_display_text.label import Label +import adafruit_stmpe610 +from simpleio import map_range + +# Operational parameters: +DISPLAY_ROTATION = 0 # Specify 0, 90, 180, or 270 degrees +REPL_ONLY = False # True to disable graphics +RAW_DATA = True # Use touchscreen raw values; False to use display coordinates + +# Previously measured raw calibration tuple for display coordinate mode (RAW_DATA = False): +CALIBRATION = ((357, 3812), (390, 3555)) + +# A collection of colors used for graphic objects +class Colors: + BLUE_DK = 0x000060 # Screen fill + RED = 0xFF0000 # Boundary + WHITE = 0xFFFFFF # Text + +# Release any resources currently in use for the displays +displayio.release_displays() + +# Define the display's SPI bus connection +disp_bus = displayio.FourWire(board.SPI(), command=board.D10, chip_select=board.D9, reset=None) + +# Instantiate the 2.4" 320x240 TFT FeatherWing (#3315). +from adafruit_ili9341 import ILI9341 +display = ILI9341(disp_bus, width=320, height=240) +_touch_flip = (False, False) + +"""# Instantiate the 3.5" 480x320 TFT FeatherWing (#3651). +from adafruit_hx8357 import HX8357 +display = HX8357(display_bus, width=480, height=320) +_touch_flip = (False, True)""" + +# Check rotation value and update display. +# Always set rotation before instantiating the touchscreen. +if DISPLAY_ROTATION != None and DISPLAY_ROTATION in (0, 90, 180, 270): + display.rotation = DISPLAY_ROTATION +else: + print("Warning: invalid rotation value -- defalting to zero") + display.rotation = 0 + time.sleep(1) + +# Activate the display graphics unless REPL_ONLY=True. +if not REPL_ONLY: + display_group = displayio.Group() + display.show(display_group) + +# Instantiate touchscreen. +ts_cs = digitalio.DigitalInOut(board.D6) +if RAW_DATA: + # Display raw touchscreen values; calibration tuple not required. + ts = adafruit_stmpe610.Adafruit_STMPE610_SPI( + board.SPI(), ts_cs, disp_rotation=display.rotation, touch_flip=_touch_flip + ) +else: + # Display calibrated screen coordinates. + # Update the raw calibration tuple with previously measured values. + ts = adafruit_stmpe610.Adafruit_STMPE610_SPI(board.SPI(), ts_cs, calibration=CALIBRATION, + size=(display.width, display.height), disp_rotation=display.rotation, touch_flip=_touch_flip) + +# Define the graphic objects if REPL_ONLY = False. +if not REPL_ONLY: + # Define the text graphic objects + font_0 = bitmap_font.load_font("/fonts/OpenSans-9.bdf") + + coordinates = Label( + font=font_0, + text="calib: ((x_min, x_max), (y_min, y_max))", + color=Colors.WHITE, + ) + coordinates.anchor_point = (0.5, 0.5) + coordinates.anchored_position = (display.width // 2, display.height // 4) + + display_rotation = Label( + font=font_0, + text="rotation: " + str(display.rotation), + color=Colors.WHITE, + ) + display_rotation.anchor_point = (0.5, 0.5) + display_rotation.anchored_position = (display.width // 2, display.height // 4 - 30) + + # Define graphic objects for the screen fill, boundary, and touch pen. + target_palette = displayio.Palette(1) + target_palette[0] = Colors.BLUE_DK + screen_fill = vectorio.Rectangle( + pixel_shader=target_palette, + x=2, + y=2, + width=display.width - 4, + height=display.height - 4, + ) + + target_palette = displayio.Palette(1) + target_palette[0] = Colors.RED + boundary = vectorio.Rectangle( + pixel_shader=target_palette, + x=0, + y=0, + width=display.width, + height=display.height, + ) + + pen = vectorio.Rectangle( + pixel_shader=target_palette, + x=display.width // 2, + y=display.height // 2, + width=10, + height=10, + ) + + display_group.append(boundary) + display_group.append(screen_fill) + display_group.append(pen) + display_group.append(coordinates) + display_group.append(display_rotation) + +# Reset x and y values to raw or display size mid-point before measurement. +x = y = 0 +if RAW_DATA: + x_min = y_min = x_max = y_max = 4096 // 2 +else: + x_min = y_min = x_max = y_max = min(display.width, display.height) // 2 + +print("Touchscreen Calibrator") +print(" Use a stylus to swipe slightly beyond the") +print(" four edges of the visible display area.") +print(" ") +print(f" display rotation: {display.rotation} degrees") +print(" Calibration values follow:") +print(" ") + +while True: + time.sleep(0.100) + touch = ts.touch_point # Check for touch + if touch: + x = touch[0] # Raw touchscreen x value + y = touch[1] # Raw touchscreen y value + if not REPL_ONLY: + pen.x = int(round(map_range(x, x_min, x_max, 0, display.width), 0)) - 5 + pen.y = int(round(map_range(y, y_min, y_max, 0, display.height), 0)) - 5 + + # Remember minimum and maximum values for the calibration tuple. + x_min = min(x_min, touch[0]) + x_max = max(x_max, touch[0]) + y_min = min(y_min, touch[1]) + y_max = max(y_max, touch[1]) + + # Show the calibration tuple. + print(f"(({x_min}, {x_max}), ({y_min}, {y_max}))") + if not REPL_ONLY: + coordinates.text = f"calib: (({x_min}, {x_max}), ({y_min}, {y_max}))" From aa9d89ee18da7dd97c35536df28e539048e321d3 Mon Sep 17 00:00:00 2001 From: Cedar Grove Maker Studios Date: Thu, 20 Jan 2022 13:51:42 -0800 Subject: [PATCH 03/17] fix SPI display bus definition for 3.5" TFT display wing --- examples/stmpe610_button_demo.py | 2 +- examples/touch_calibrator_stmpe610.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/stmpe610_button_demo.py b/examples/stmpe610_button_demo.py index bbf54fd..87996b0 100755 --- a/examples/stmpe610_button_demo.py +++ b/examples/stmpe610_button_demo.py @@ -36,7 +36,7 @@ """# Instantiate the 3.5" 480x320 TFT FeatherWing (#3651). from adafruit_hx8357 import HX8357 -display = HX8357(display_bus, width=480, height=320) +display = HX8357(disp_bus, width=480, height=320) _touch_flip = (False, True)""" # Always set rotation before instantiating the touchscreen diff --git a/examples/touch_calibrator_stmpe610.py b/examples/touch_calibrator_stmpe610.py index 99647f3..227acf9 100755 --- a/examples/touch_calibrator_stmpe610.py +++ b/examples/touch_calibrator_stmpe610.py @@ -65,7 +65,7 @@ class Colors: """# Instantiate the 3.5" 480x320 TFT FeatherWing (#3651). from adafruit_hx8357 import HX8357 -display = HX8357(display_bus, width=480, height=320) +display = HX8357(disp_bus, width=480, height=320) _touch_flip = (False, True)""" # Check rotation value and update display. From 9f98e2b61111122d2d964013bff2b6b658841c59 Mon Sep 17 00:00:00 2001 From: Cedar Grove Maker Studios Date: Thu, 20 Jan 2022 16:59:55 -0800 Subject: [PATCH 04/17] add `touch_point` examples --- adafruit_stmpe610.py | 4 +-- examples/stmpe610_button_demo.py | 5 ++- examples/stmpe610_touch_point_paint_demo.py | 38 +++++++++++++++++++++ examples/stmpe610_touch_point_simpletest.py | 21 ++++++++++++ examples/touch_calibrator_stmpe610.py | 4 +-- 5 files changed, 67 insertions(+), 5 deletions(-) create mode 100755 examples/stmpe610_touch_point_paint_demo.py create mode 100755 examples/stmpe610_touch_point_simpletest.py diff --git a/adafruit_stmpe610.py b/adafruit_stmpe610.py index dcd9a7b..39e0344 100755 --- a/adafruit_stmpe610.py +++ b/adafruit_stmpe610.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2017 Jerry Needell for Adafruit Industries +# SPDX-FileCopyrightText: 2017, 2022 Jerry Needell for Adafruit Industries # # SPDX-License-Identifier: MIT """ @@ -6,7 +6,7 @@ ==================================================== This is a CircuitPython Driver for the STMPE610 Resistive Touch sensor -* Author(s): Jerry Needell +* Author(s): Jerry Needell, CedarGroveMakerStudios Implementation Notes -------------------- diff --git a/examples/stmpe610_button_demo.py b/examples/stmpe610_button_demo.py index 87996b0..c98c07c 100755 --- a/examples/stmpe610_button_demo.py +++ b/examples/stmpe610_button_demo.py @@ -1,8 +1,11 @@ -# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries +# SPDX-FileCopyrightText: 2022 ladyada for Adafruit Industries # SPDX-License-Identifier: MIT """ Simple button demonstration/example. STMPE610 touch controller with TFT FeatherWing Display + +Author(s): ladyada, CedarGroveMakerStudios + """ import board diff --git a/examples/stmpe610_touch_point_paint_demo.py b/examples/stmpe610_touch_point_paint_demo.py new file mode 100755 index 0000000..6ac74eb --- /dev/null +++ b/examples/stmpe610_touch_point_paint_demo.py @@ -0,0 +1,38 @@ +# SPDX-FileCopyrightText: 2022 CedarGroveMakerStudios for Adafruit Industries +# SPDX-License-Identifier: MIT + +""" +Simple painting demo that draws on an Adafruit 2.4" TFT FeatherWing +display (#3315) with the STMPE610 resistive touch controller. +""" + +import board +import digitalio +import displayio +from adafruit_rgb_display import ili9341, color565 +import adafruit_stmpe610 + +# Release any resources currently in use for the display +displayio.release_displays() + +# Instantiate the 2.4" 320x240 TFT FeatherWing Display(#3315). +cs_pin = digitalio.DigitalInOut(board.D9) +dc_pin = digitalio.DigitalInOut(board.D10) +display = ili9341.ILI9341(board.SPI(), cs=cs_pin, dc=dc_pin) + +print(display.width, display.height) + +# Fill the screen with black! +display.fill(color565(0, 0, 0)) + +# Instantiate the touchpad +ts_cs_pin = digitalio.DigitalInOut(board.D6) +ts = adafruit_stmpe610.Adafruit_STMPE610_SPI(board.SPI(), ts_cs_pin, calibration=((350, 3500), (350, 3500)), size=(display.width, display.height), disp_rotation = 90, touch_flip=(True, True)) + +while True: + point = ts.touch_point + if point: + # Display the touched point + x = point[0] + y = point[1] + display.fill_rectangle(x - 2, y - 2, 4, 4, color565(255, 0, 0)) diff --git a/examples/stmpe610_touch_point_simpletest.py b/examples/stmpe610_touch_point_simpletest.py new file mode 100755 index 0000000..d7c88d0 --- /dev/null +++ b/examples/stmpe610_touch_point_simpletest.py @@ -0,0 +1,21 @@ +# SPDX-FileCopyrightText: 2022 CedarGroveMakerStudios for Adafruit Industries +# SPDX-License-Identifier: MIT + +""" +Simple print-to-REPL demo using the STMPE610 resistive touch controller. +""" + +import board +import digitalio +import adafruit_stmpe610 + +# Instantiate the touchpad +ts_cs_pin = digitalio.DigitalInOut(board.D6) +ts = adafruit_stmpe610.Adafruit_STMPE610_SPI(board.SPI(), ts_cs_pin) + +print("Go Ahead - Touch the Screen - Make My Day!") +print("(x, y, pressure)") +while True: + point = ts.touch_point + if point: + print(point) diff --git a/examples/touch_calibrator_stmpe610.py b/examples/touch_calibrator_stmpe610.py index 227acf9..a017eb1 100755 --- a/examples/touch_calibrator_stmpe610.py +++ b/examples/touch_calibrator_stmpe610.py @@ -1,10 +1,10 @@ -# SPDX-FileCopyrightText: 2022 Cedar Grove Maker Studios +# SPDX-FileCopyrightText: 2022 CedarGroveMakerStudios for Adafruit Industries # SPDX-License-Identifier: MIT """ touch_calibrator_stmpe610.py 2022-01-20 v1.0 -Author(s): JG for Cedar Grove Maker Studios +Author(s): CedarGroveMakerStudios On-screen touchscreen calibrator for TFT FeatherWing displays. From 8426dcb39ae2db88919f056176cc95effad7315b Mon Sep 17 00:00:00 2001 From: Cedar Grove Maker Studios Date: Thu, 20 Jan 2022 17:07:01 -0800 Subject: [PATCH 05/17] formatted with black --- adafruit_stmpe610.py | 1 + examples/stmpe610_button_demo.py | 8 ++++++-- examples/stmpe610_touch_point_paint_demo.py | 11 ++++++++--- examples/touch_calibrator_stmpe610.py | 16 +++++++++++++--- 4 files changed, 28 insertions(+), 8 deletions(-) diff --git a/adafruit_stmpe610.py b/adafruit_stmpe610.py index 39e0344..a69bd02 100755 --- a/adafruit_stmpe610.py +++ b/adafruit_stmpe610.py @@ -339,6 +339,7 @@ class Adafruit_STMPE610_I2C(Adafruit_STMPE610): touch_flip=(False, False)) """ + def __init__( self, i2c, diff --git a/examples/stmpe610_button_demo.py b/examples/stmpe610_button_demo.py index c98c07c..a84480f 100755 --- a/examples/stmpe610_button_demo.py +++ b/examples/stmpe610_button_demo.py @@ -30,10 +30,13 @@ # Release any resources currently in use for the displays displayio.release_displays() -disp_bus = displayio.FourWire(board.SPI(), command=board.D10, chip_select=board.D9, reset=None) +disp_bus = displayio.FourWire( + board.SPI(), command=board.D10, chip_select=board.D9, reset=None +) # Instantiate the 2.4" 320x240 TFT FeatherWing (#3315). from adafruit_ili9341 import ILI9341 + display = ILI9341(disp_bus, width=320, height=240) _touch_flip = (False, False) @@ -52,7 +55,8 @@ ts_cs, calibration=((357, 3812), (390, 3555)), size=(display.width, display.height), - disp_rotation=display.rotation, touch_flip=_touch_flip + disp_rotation=display.rotation, + touch_flip=_touch_flip, ) # Create the displayio group and show it diff --git a/examples/stmpe610_touch_point_paint_demo.py b/examples/stmpe610_touch_point_paint_demo.py index 6ac74eb..aadf017 100755 --- a/examples/stmpe610_touch_point_paint_demo.py +++ b/examples/stmpe610_touch_point_paint_demo.py @@ -20,14 +20,19 @@ dc_pin = digitalio.DigitalInOut(board.D10) display = ili9341.ILI9341(board.SPI(), cs=cs_pin, dc=dc_pin) -print(display.width, display.height) - # Fill the screen with black! display.fill(color565(0, 0, 0)) # Instantiate the touchpad ts_cs_pin = digitalio.DigitalInOut(board.D6) -ts = adafruit_stmpe610.Adafruit_STMPE610_SPI(board.SPI(), ts_cs_pin, calibration=((350, 3500), (350, 3500)), size=(display.width, display.height), disp_rotation = 90, touch_flip=(True, True)) +ts = adafruit_stmpe610.Adafruit_STMPE610_SPI( + board.SPI(), + ts_cs_pin, + calibration=((350, 3500), (350, 3500)), + size=(display.width, display.height), + disp_rotation=90, + touch_flip=(True, True), +) while True: point = ts.touch_point diff --git a/examples/touch_calibrator_stmpe610.py b/examples/touch_calibrator_stmpe610.py index a017eb1..ffaa19a 100755 --- a/examples/touch_calibrator_stmpe610.py +++ b/examples/touch_calibrator_stmpe610.py @@ -52,14 +52,18 @@ class Colors: RED = 0xFF0000 # Boundary WHITE = 0xFFFFFF # Text + # Release any resources currently in use for the displays displayio.release_displays() # Define the display's SPI bus connection -disp_bus = displayio.FourWire(board.SPI(), command=board.D10, chip_select=board.D9, reset=None) +disp_bus = displayio.FourWire( + board.SPI(), command=board.D10, chip_select=board.D9, reset=None +) # Instantiate the 2.4" 320x240 TFT FeatherWing (#3315). from adafruit_ili9341 import ILI9341 + display = ILI9341(disp_bus, width=320, height=240) _touch_flip = (False, False) @@ -92,8 +96,14 @@ class Colors: else: # Display calibrated screen coordinates. # Update the raw calibration tuple with previously measured values. - ts = adafruit_stmpe610.Adafruit_STMPE610_SPI(board.SPI(), ts_cs, calibration=CALIBRATION, - size=(display.width, display.height), disp_rotation=display.rotation, touch_flip=_touch_flip) + ts = adafruit_stmpe610.Adafruit_STMPE610_SPI( + board.SPI(), + ts_cs, + calibration=CALIBRATION, + size=(display.width, display.height), + disp_rotation=display.rotation, + touch_flip=_touch_flip, + ) # Define the graphic objects if REPL_ONLY = False. if not REPL_ONLY: From 68a10372cf40f6e4d955d532282c872c751298b8 Mon Sep 17 00:00:00 2001 From: Cedar Grove Maker Studios Date: Thu, 20 Jan 2022 18:11:30 -0800 Subject: [PATCH 06/17] fix pylint errors --- adafruit_stmpe610.py | 946 +++++++++++++------------- examples/stmpe610_button_demo.py | 187 +++-- examples/touch_calibrator_stmpe610.py | 13 +- 3 files changed, 576 insertions(+), 570 deletions(-) diff --git a/adafruit_stmpe610.py b/adafruit_stmpe610.py index a69bd02..566e7e0 100755 --- a/adafruit_stmpe610.py +++ b/adafruit_stmpe610.py @@ -1,469 +1,477 @@ -# SPDX-FileCopyrightText: 2017, 2022 Jerry Needell for Adafruit Industries -# -# SPDX-License-Identifier: MIT -""" -`adafruit_stmpe610` -==================================================== -This is a CircuitPython Driver for the STMPE610 Resistive Touch sensor - -* Author(s): Jerry Needell, CedarGroveMakerStudios - -Implementation Notes --------------------- -**Hardware:** - -**Software and Dependencies:** - -* Adafruit CircuitPython firmware for the supported boards: - https://github.com/adafruit/circuitpython/releases -""" - -# imports - -import time -from micropython import const - - -__version__ = "1.2.7" -__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_STMPE610.git" - - -def map_range(x, in_min, in_max, out_min, out_max): - """ - Maps a value from one range to another. Values beyond the input minimum or - maximum will be limited to the minimum or maximum of the output range. - - :return: Returns value mapped to new range - :rtype: float - """ - in_range = in_max - in_min - in_delta = x - in_min - if in_range != 0: - mapped = in_delta / in_range - elif in_delta != 0: - mapped = in_delta - else: - mapped = 0.5 - mapped *= out_max - out_min - mapped += out_min - if out_min <= out_max: - return max(min(mapped, out_max), out_min) - return min(max(mapped, out_max), out_min) - - -_STMPE_ADDR = const(0x41) -_STMPE_VERSION = const(0x0811) - -_STMPE_SYS_CTRL1 = const(0x03) -_STMPE_SYS_CTRL1_RESET = const(0x02) -_STMPE_SYS_CTRL2 = const(0x04) - -_STMPE_TSC_CTRL = const(0x40) -_STMPE_TSC_CTRL_EN = const(0x01) -_STMPE_TSC_CTRL_XYZ = const(0x00) -_STMPE_TSC_CTRL_XY = const(0x02) - -_STMPE_INT_CTRL = const(0x09) -_STMPE_INT_CTRL_POL_HIGH = const(0x04) -_STMPE_INT_CTRL_POL_LOW = const(0x00) -_STMPE_INT_CTRL_EDGE = const(0x02) -_STMPE_INT_CTRL_LEVEL = const(0x00) -_STMPE_INT_CTRL_ENABLE = const(0x01) -_STMPE_INT_CTRL_DISABLE = const(0x00) - - -_STMPE_INT_EN = const(0x0A) -_STMPE_INT_EN_TOUCHDET = const(0x01) -_STMPE_INT_EN_FIFOTH = const(0x02) -_STMPE_INT_EN_FIFOOF = const(0x04) -_STMPE_INT_EN_FIFOFULL = const(0x08) -_STMPE_INT_EN_FIFOEMPTY = const(0x10) -_STMPE_INT_EN_ADC = const(0x40) -_STMPE_INT_EN_GPIO = const(0x80) - -_STMPE_INT_STA = const(0x0B) -_STMPE_INT_STA_TOUCHDET = const(0x01) - -_STMPE_ADC_CTRL1 = const(0x20) -_STMPE_ADC_CTRL1_12BIT = const(0x08) -_STMPE_ADC_CTRL1_10BIT = const(0x00) - -_STMPE_ADC_CTRL2 = const(0x21) -_STMPE_ADC_CTRL2_1_625MHZ = const(0x00) -_STMPE_ADC_CTRL2_3_25MHZ = const(0x01) -_STMPE_ADC_CTRL2_6_5MHZ = const(0x02) - -_STMPE_TSC_CFG = const(0x41) -_STMPE_TSC_CFG_1SAMPLE = const(0x00) -_STMPE_TSC_CFG_2SAMPLE = const(0x40) -_STMPE_TSC_CFG_4SAMPLE = const(0x80) -_STMPE_TSC_CFG_8SAMPLE = const(0xC0) -_STMPE_TSC_CFG_DELAY_10US = const(0x00) -_STMPE_TSC_CFG_DELAY_50US = const(0x08) -_STMPE_TSC_CFG_DELAY_100US = const(0x10) -_STMPE_TSC_CFG_DELAY_500US = const(0x18) -_STMPE_TSC_CFG_DELAY_1MS = const(0x20) -_STMPE_TSC_CFG_DELAY_5MS = const(0x28) -_STMPE_TSC_CFG_DELAY_10MS = const(0x30) -_STMPE_TSC_CFG_DELAY_50MS = const(0x38) -_STMPE_TSC_CFG_SETTLE_10US = const(0x00) -_STMPE_TSC_CFG_SETTLE_100US = const(0x01) -_STMPE_TSC_CFG_SETTLE_500US = const(0x02) -_STMPE_TSC_CFG_SETTLE_1MS = const(0x03) -_STMPE_TSC_CFG_SETTLE_5MS = const(0x04) -_STMPE_TSC_CFG_SETTLE_10MS = const(0x05) -_STMPE_TSC_CFG_SETTLE_50MS = const(0x06) -_STMPE_TSC_CFG_SETTLE_100MS = const(0x07) - -_STMPE_FIFO_TH = const(0x4A) - -_STMPE_FIFO_SIZE = const(0x4C) - -_STMPE_FIFO_STA = const(0x4B) -_STMPE_FIFO_STA_RESET = const(0x01) -_STMPE_FIFO_STA_OFLOW = const(0x80) -_STMPE_FIFO_STA_FULL = const(0x40) -_STMPE_FIFO_STA_EMPTY = const(0x20) -_STMPE_FIFO_STA_THTRIG = const(0x10) - -_STMPE_TSC_I_DRIVE = const(0x58) -_STMPE_TSC_I_DRIVE_20MA = const(0x00) -_STMPE_TSC_I_DRIVE_50MA = const(0x01) - -_STMPE_TSC_DATA_X = const(0x4D) -_STMPE_TSC_DATA_Y = const(0x4F) -_STMPE_TSC_FRACTION_Z = const(0x56) - -_STMPE_GPIO_SET_PIN = const(0x10) -_STMPE_GPIO_CLR_PIN = const(0x11) -_STMPE_GPIO_DIR = const(0x13) -_STMPE_GPIO_ALT_FUNCT = const(0x17) - - -class Adafruit_STMPE610: - """A class (driver) for the STMPE610 Resistive Touch controller used by the - 2.4" 320x240 TFT FeatherWing display (#3315), 3.5" 480x320 TFT FeatherWing - display (#3651), and the Resistive Touch Screen Controller - STMPE610 - breakout board (#1571). This class acts as a super class for the I2C and - SPI interface classes. - - This class was modified from the original to add the Displayio Button - compatible touch_point property to the existing functionality. - - See the examples folder for instantiation kwargs and properties.""" - - def __init__(self): - """Check the touchscreen calibration and display size kwargs from the - I2C or SPI interface class then reset the controller.""" - if not self._calib: - self._calib = ((0, 4095), (0, 4095)) - if not self._disp_size: - self._disp_size = (4095, 4095) - - if not self._disp_rotation in (0, 90, 180, 270): - raise ValueError("Display rotation value must be 0, 90, 180, or 270") - - self._write_register_byte(_STMPE_SYS_CTRL1, _STMPE_SYS_CTRL1_RESET) - time.sleep(0.001) - - self._write_register_byte(_STMPE_SYS_CTRL2, 0x0) # turn on clocks! - self._write_register_byte( - _STMPE_TSC_CTRL, _STMPE_TSC_CTRL_XYZ | _STMPE_TSC_CTRL_EN - ) # XYZ and enable! - self._write_register_byte(_STMPE_INT_EN, _STMPE_INT_EN_TOUCHDET) - self._write_register_byte( - _STMPE_ADC_CTRL1, _STMPE_ADC_CTRL1_10BIT | (0x6 << 4) - ) # 96 clocks per conversion - self._write_register_byte(_STMPE_ADC_CTRL2, _STMPE_ADC_CTRL2_6_5MHZ) - self._write_register_byte( - _STMPE_TSC_CFG, - _STMPE_TSC_CFG_4SAMPLE - | _STMPE_TSC_CFG_DELAY_1MS - | _STMPE_TSC_CFG_SETTLE_5MS, - ) - self._write_register_byte(_STMPE_TSC_FRACTION_Z, 0x6) - self._write_register_byte(_STMPE_FIFO_TH, 1) - self._write_register_byte(_STMPE_FIFO_STA, _STMPE_FIFO_STA_RESET) - self._write_register_byte(_STMPE_FIFO_STA, 0) # Unreset - self._write_register_byte(_STMPE_TSC_I_DRIVE, _STMPE_TSC_I_DRIVE_50MA) - self._write_register_byte(_STMPE_INT_STA, 0xFF) # Reset all ints - self._write_register_byte( - _STMPE_INT_CTRL, _STMPE_INT_CTRL_POL_HIGH | _STMPE_INT_CTRL_ENABLE - ) - - def read_data(self): - """Request next stored reading - return tuple containing (x,y,pressure).""" - d_1 = self._read_byte(0xD7) - d_2 = self._read_byte(0xD7) - d_3 = self._read_byte(0xD7) - d_4 = self._read_byte(0xD7) - x_loc = d_1 << 4 | d_2 >> 4 - y_loc = (d_2 & 0xF) << 8 | d_3 - pressure = d_4 - # Reset all ints (not sure what this does) - if self.buffer_empty: - self._write_register_byte(_STMPE_INT_STA, 0xFF) - return (x_loc, y_loc, pressure) - - def _read_byte(self, register): - """Read a byte register value and return it.""" - return self._read_register(register, 1)[0] - - def _read_register(self, register, length): - """Read an arbitrarily long register (specified by length number of - bytes) and return a bytearray of the retrieved data. - Subclasses MUST implement this!""" - raise NotImplementedError - - def _write_register_byte(self, register, value): - """Write a single byte register at the specified register address. - Subclasses MUST implement this!""" - raise NotImplementedError - - @property - def touches(self): - """Returns a list of touchpoint dicts, with 'x' and 'y' containing the - touch coordinates, and 'pressure'.""" - touchpoints = [] - while (len(touchpoints) < 4) and not self.buffer_empty: - (x_loc, y_loc, pressure) = self.read_data() - point = {"x": x_loc, "y": y_loc, "pressure": pressure} - touchpoints.append(point) - return touchpoints - - @property - def get_version(self): - """Read the version number from the sensor.""" - v_1 = self._read_byte(0) - v_2 = self._read_byte(1) - version = v_1 << 8 | v_2 - # print("version ",hex(version)) - return version - - @property - def touched(self): - """Report if any touches were detected.""" - touch = self._read_byte(_STMPE_TSC_CTRL) & 0x80 - return touch == 0x80 - - @property - def buffer_size(self): - """The amount of touch data in the buffer.""" - return self._read_byte(_STMPE_FIFO_SIZE) - - @property - def buffer_empty(self): - """Buffer empty status.""" - empty = self._read_byte(_STMPE_FIFO_STA) & _STMPE_FIFO_STA_EMPTY - return empty != 0 - - @property - def get_point(self): - """Read one touch from the buffer.""" - (x_loc, y_loc, pressure) = self.read_data() - point = {"x": x_loc, "y": y_loc, "pressure": pressure} - return point - - @property - def touch_point(self): - """Read latest touched point value and convert to calibration-adjusted - and rotated display coordinates. Commpatible with Displayio Button. - :return: x, y, pressure - rtype: int, int, int - """ - if not self.buffer_empty: - while not self.buffer_empty: - x_loc, y_loc, pressure = self.read_data() - # Swap touch axis range minimum and maximum if needed - if self._disp_rotation in (0, 180): - if self._touch_flip and self._touch_flip[0]: - x_c = (self._calib[0][1], self._calib[0][0]) - else: - x_c = (self._calib[0][0], self._calib[0][1]) - if self._touch_flip and self._touch_flip[1]: - y_c = (self._calib[1][1], self._calib[1][0]) - else: - y_c = (self._calib[1][0], self._calib[1][1]) - if self._disp_rotation in (90, 270): - if self._touch_flip[1]: - x_c = (self._calib[1][1], self._calib[1][0]) - else: - x_c = (self._calib[1][0], self._calib[1][1]) - if self._touch_flip[0]: - y_c = (self._calib[0][1], self._calib[0][0]) - else: - y_c = (self._calib[0][0], self._calib[0][1]) - # Adjust to calibration range; convert to display size and rotation - if self._disp_rotation == 0: - x = int(map_range(y_loc, x_c[0], x_c[1], 0, self._disp_size[0])) - y = int(map_range(x_loc, y_c[0], y_c[1], 0, self._disp_size[1])) - elif self._disp_rotation == 90: - x = int(map_range(x_loc, x_c[0], x_c[1], 0, self._disp_size[0])) - y = int(map_range(y_loc, y_c[0], y_c[1], self._disp_size[1], 0)) - elif self._disp_rotation == 180: - x = int(map_range(y_loc, x_c[0], x_c[1], self._disp_size[0], 0)) - y = int(map_range(x_loc, y_c[0], y_c[1], self._disp_size[1], 0)) - elif self._disp_rotation == 270: - x = int(map_range(x_loc, x_c[0], x_c[1], self._disp_size[0], 0)) - y = int(map_range(y_loc, y_c[0], y_c[1], 0, self._disp_size[1])) - return (x, y, pressure) - return None - - -class Adafruit_STMPE610_I2C(Adafruit_STMPE610): - """I2C interface class for the STMPE610 Resistive Touch sensor. - - :param i2c: I2C interface bus - :param int address: I2C address. Defaults to 0x41 - :param None, (int, int) calibration: touchscreen calibration tuple. - Defaults to None. - :param None, (int, int) size: display size tuple (width, height). - Defaults to None. - :param int disp_rotation: display rotation in degrees. Values allowed are - 0, 90, 180, and 270. Defaults to 0. - :param (bool, bool) touch_flip: swap touchscreen axis range minimum and - maximum values for (x, y) axes as referenced to display 0-degree rotation. - Defaults to (False, False). - - ** Quickstart: Importing and instantiating Adafruit_STMPE610_I2C** - - Import the Adafruit_STMPE610_I2C class and instantiate for the 2.4" TFT Wing - after instantiating the display: - - .. code-block:: python - - import adafruit_stmpe610 - ts = adafruit_stmpe610.Adafruit_STMPE610_I2C(board.I2C(), address=0x41, - calibration=((357, 3812), (390, 3555)), - size=(display.width, display.height), disp_rotation=display.rotation, - touch_flip=(False, False)) - - """ - - def __init__( - self, - i2c, - address=_STMPE_ADDR, - calibration=None, - size=None, - disp_rotation=0, - touch_flip=(False, False), - ): - - self._calib = calibration - self._disp_size = size - self._disp_rotation = disp_rotation - self._touch_flip = touch_flip - - """Check that the STMPE610 was found.""" - import adafruit_bus_device.i2c_device as i2cdev # pylint: disable=import-outside-toplevel - - self._i2c = i2cdev.I2CDevice(i2c, address) - # Check device version. - version = self.get_version - if _STMPE_VERSION != version: - raise RuntimeError("Failed to find STMPE610! Chip Version 0x%x" % version) - super().__init__() - - def _read_register(self, register, length): - """Low level register reading over I2C, returns a list of values.""" - with self._i2c as i2c: - i2c.write(bytearray([register & 0xFF])) - result = bytearray(length) - i2c.readinto(result) - # print("$%02X => %s" % (register, [hex(i) for i in result])) - return result - - def _write_register_byte(self, register, value): - """Low level register writing over I2C, writes one 8-bit value.""" - with self._i2c as i2c: - i2c.write(bytes([register & 0xFF, value & 0xFF])) - # print("$%02X <= 0x%02X" % (register, value)) - - -class Adafruit_STMPE610_SPI(Adafruit_STMPE610): - """SPI interface class for the STMPE610 Resistive Touch sensor. - - :param spi: SPI interface bus - :param pin cs: touchscreen SPI interface chip select pin - :param int baudrate: SPI interface clock speed in Hz. - Defaults to 1000000 (1MHz). - :param None, (int, int) calibration: touchscreen calibration tuple. - Defaults to None. - :param None, (int, int) size: display size tuple (width, height). - Defaults to None. - :param int disp_rotation: display rotation in degrees. Values allowed are - 0, 90, 180, and 270. Defaults to 0. - :param (bool, bool) touch_flip: swap touchscreen axis range minimum and - maximum values for (x, y) axes as referenced to display 0-degree rotation. - Defaults to (False, False). - - ** Quickstart: Importing and instantiating Adafruit_STMPE610_I2C** - - Import the Adafruit_STMPE610_SPI class and instantiate for the 2.4" TFT Wing - after instantiating the display: - - .. code-block:: python - - import adafruit_stmpe610 - ts = adafruit_stmpe610.Adafruit_STMPE610_SPI(spi, cs=cs_pin, - baudrate=1000000, - calibration=((357, 3812), (390, 3555)), - size=(display.width, display.height), disp_rotation=display.rotation, - touch_flip=(False, False)) - - """ - - def __init__( - self, - spi, - cs, - baudrate=1000000, - calibration=None, - size=None, - disp_rotation=0, - touch_flip=(False, False), - ): - - self._calib = calibration - self._disp_size = size - self._disp_rotation = disp_rotation - self._touch_flip = touch_flip - - """Check that the STMPE610 was found.""" - import adafruit_bus_device.spi_device as spidev # pylint: disable=import-outside-toplevel - - self._spi = spidev.SPIDevice(spi, cs, baudrate=baudrate) - # Check device version. - version = self.get_version - if _STMPE_VERSION != version: - # If it fails try SPI MODE 1 -- that is what Arduino does - self._spi = spidev.SPIDevice( - spi, cs, baudrate=baudrate, polarity=0, phase=1 - ) - version = self.get_version - if _STMPE_VERSION != version: - raise RuntimeError( - "Failed to find STMPE610 controller! Chip Version 0x%x. " - "If you are using the breakout, verify you are in SPI mode." - % version - ) - super().__init__() - - # pylint: disable=no-member - # Disable should be reconsidered when refactor can be tested. - def _read_register(self, register, length): - """Low level register reading over SPI, returns a list of values.""" - register = (register | 0x80) & 0xFF # Read single byte, bit 7 high. - with self._spi as spi: - spi.write(bytearray([register])) - result = bytearray(length) - spi.readinto(result) - # print("$%02X => %s" % (register, [hex(i) for i in result])) - return result - - def _write_register_byte(self, register, value): - """Low level register writing over SPI, writes one 8-bit value.""" - register &= 0x7F # Write, bit 7 low. - with self._spi as spi: - spi.write(bytes([register, value & 0xFF])) +# SPDX-FileCopyrightText: 2017, 2022 Jerry Needell for Adafruit Industries +# +# SPDX-License-Identifier: MIT +""" +`adafruit_stmpe610` +==================================================== +This is a CircuitPython Driver for the STMPE610 Resistive Touch sensor + +* Author(s): Jerry Needell, CedarGroveMakerStudios + +Implementation Notes +-------------------- +**Hardware:** + +**Software and Dependencies:** + +* Adafruit CircuitPython firmware for the supported boards: + https://github.com/adafruit/circuitpython/releases +""" + +import time +from micropython import const + + +__version__ = "1.2.7" +__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_STMPE610.git" + + +def map_range(x, in_min, in_max, out_min, out_max): + """ + Maps a value from one range to another. Values beyond the input minimum or + maximum will be limited to the minimum or maximum of the output range. + + :return: Returns value mapped to new range + :rtype: float + """ + in_range = in_max - in_min + in_delta = x - in_min + if in_range != 0: + mapped = in_delta / in_range + elif in_delta != 0: + mapped = in_delta + else: + mapped = 0.5 + mapped *= out_max - out_min + mapped += out_min + if out_min <= out_max: + return max(min(mapped, out_max), out_min) + return min(max(mapped, out_max), out_min) + + +_STMPE_ADDR = const(0x41) +_STMPE_VERSION = const(0x0811) + +_STMPE_SYS_CTRL1 = const(0x03) +_STMPE_SYS_CTRL1_RESET = const(0x02) +_STMPE_SYS_CTRL2 = const(0x04) + +_STMPE_TSC_CTRL = const(0x40) +_STMPE_TSC_CTRL_EN = const(0x01) +_STMPE_TSC_CTRL_XYZ = const(0x00) +_STMPE_TSC_CTRL_XY = const(0x02) + +_STMPE_INT_CTRL = const(0x09) +_STMPE_INT_CTRL_POL_HIGH = const(0x04) +_STMPE_INT_CTRL_POL_LOW = const(0x00) +_STMPE_INT_CTRL_EDGE = const(0x02) +_STMPE_INT_CTRL_LEVEL = const(0x00) +_STMPE_INT_CTRL_ENABLE = const(0x01) +_STMPE_INT_CTRL_DISABLE = const(0x00) + + +_STMPE_INT_EN = const(0x0A) +_STMPE_INT_EN_TOUCHDET = const(0x01) +_STMPE_INT_EN_FIFOTH = const(0x02) +_STMPE_INT_EN_FIFOOF = const(0x04) +_STMPE_INT_EN_FIFOFULL = const(0x08) +_STMPE_INT_EN_FIFOEMPTY = const(0x10) +_STMPE_INT_EN_ADC = const(0x40) +_STMPE_INT_EN_GPIO = const(0x80) + +_STMPE_INT_STA = const(0x0B) +_STMPE_INT_STA_TOUCHDET = const(0x01) + +_STMPE_ADC_CTRL1 = const(0x20) +_STMPE_ADC_CTRL1_12BIT = const(0x08) +_STMPE_ADC_CTRL1_10BIT = const(0x00) + +_STMPE_ADC_CTRL2 = const(0x21) +_STMPE_ADC_CTRL2_1_625MHZ = const(0x00) +_STMPE_ADC_CTRL2_3_25MHZ = const(0x01) +_STMPE_ADC_CTRL2_6_5MHZ = const(0x02) + +_STMPE_TSC_CFG = const(0x41) +_STMPE_TSC_CFG_1SAMPLE = const(0x00) +_STMPE_TSC_CFG_2SAMPLE = const(0x40) +_STMPE_TSC_CFG_4SAMPLE = const(0x80) +_STMPE_TSC_CFG_8SAMPLE = const(0xC0) +_STMPE_TSC_CFG_DELAY_10US = const(0x00) +_STMPE_TSC_CFG_DELAY_50US = const(0x08) +_STMPE_TSC_CFG_DELAY_100US = const(0x10) +_STMPE_TSC_CFG_DELAY_500US = const(0x18) +_STMPE_TSC_CFG_DELAY_1MS = const(0x20) +_STMPE_TSC_CFG_DELAY_5MS = const(0x28) +_STMPE_TSC_CFG_DELAY_10MS = const(0x30) +_STMPE_TSC_CFG_DELAY_50MS = const(0x38) +_STMPE_TSC_CFG_SETTLE_10US = const(0x00) +_STMPE_TSC_CFG_SETTLE_100US = const(0x01) +_STMPE_TSC_CFG_SETTLE_500US = const(0x02) +_STMPE_TSC_CFG_SETTLE_1MS = const(0x03) +_STMPE_TSC_CFG_SETTLE_5MS = const(0x04) +_STMPE_TSC_CFG_SETTLE_10MS = const(0x05) +_STMPE_TSC_CFG_SETTLE_50MS = const(0x06) +_STMPE_TSC_CFG_SETTLE_100MS = const(0x07) + +_STMPE_FIFO_TH = const(0x4A) + +_STMPE_FIFO_SIZE = const(0x4C) + +_STMPE_FIFO_STA = const(0x4B) +_STMPE_FIFO_STA_RESET = const(0x01) +_STMPE_FIFO_STA_OFLOW = const(0x80) +_STMPE_FIFO_STA_FULL = const(0x40) +_STMPE_FIFO_STA_EMPTY = const(0x20) +_STMPE_FIFO_STA_THTRIG = const(0x10) + +_STMPE_TSC_I_DRIVE = const(0x58) +_STMPE_TSC_I_DRIVE_20MA = const(0x00) +_STMPE_TSC_I_DRIVE_50MA = const(0x01) + +_STMPE_TSC_DATA_X = const(0x4D) +_STMPE_TSC_DATA_Y = const(0x4F) +_STMPE_TSC_FRACTION_Z = const(0x56) + +_STMPE_GPIO_SET_PIN = const(0x10) +_STMPE_GPIO_CLR_PIN = const(0x11) +_STMPE_GPIO_DIR = const(0x13) +_STMPE_GPIO_ALT_FUNCT = const(0x17) + + +class Adafruit_STMPE610: + """A class (driver) for the STMPE610 Resistive Touch controller used by the + 2.4" 320x240 TFT FeatherWing display (#3315), 3.5" 480x320 TFT FeatherWing + display (#3651), and the Resistive Touch Screen Controller - STMPE610 + breakout board (#1571). This class acts as a super class for the I2C and + SPI interface classes. + + This class was modified from the original to add the Displayio Button + compatible touch_point property to the existing functionality. + + See the examples folder for instantiation kwargs and properties.""" + + def __init__(self): + """Reset the controller.""" + self._write_register_byte(_STMPE_SYS_CTRL1, _STMPE_SYS_CTRL1_RESET) + time.sleep(0.001) + + self._write_register_byte(_STMPE_SYS_CTRL2, 0x0) # turn on clocks! + self._write_register_byte( + _STMPE_TSC_CTRL, _STMPE_TSC_CTRL_XYZ | _STMPE_TSC_CTRL_EN + ) # XYZ and enable! + self._write_register_byte(_STMPE_INT_EN, _STMPE_INT_EN_TOUCHDET) + self._write_register_byte( + _STMPE_ADC_CTRL1, _STMPE_ADC_CTRL1_10BIT | (0x6 << 4) + ) # 96 clocks per conversion + self._write_register_byte(_STMPE_ADC_CTRL2, _STMPE_ADC_CTRL2_6_5MHZ) + self._write_register_byte( + _STMPE_TSC_CFG, + _STMPE_TSC_CFG_4SAMPLE + | _STMPE_TSC_CFG_DELAY_1MS + | _STMPE_TSC_CFG_SETTLE_5MS, + ) + self._write_register_byte(_STMPE_TSC_FRACTION_Z, 0x6) + self._write_register_byte(_STMPE_FIFO_TH, 1) + self._write_register_byte(_STMPE_FIFO_STA, _STMPE_FIFO_STA_RESET) + self._write_register_byte(_STMPE_FIFO_STA, 0) # Unreset + self._write_register_byte(_STMPE_TSC_I_DRIVE, _STMPE_TSC_I_DRIVE_50MA) + self._write_register_byte(_STMPE_INT_STA, 0xFF) # Reset all ints + self._write_register_byte( + _STMPE_INT_CTRL, _STMPE_INT_CTRL_POL_HIGH | _STMPE_INT_CTRL_ENABLE + ) + + def read_data(self): + """Request next stored reading - return tuple containing (x,y,pressure).""" + d_1 = self._read_byte(0xD7) + d_2 = self._read_byte(0xD7) + d_3 = self._read_byte(0xD7) + d_4 = self._read_byte(0xD7) + x_loc = d_1 << 4 | d_2 >> 4 + y_loc = (d_2 & 0xF) << 8 | d_3 + pressure = d_4 + # Reset all ints (not sure what this does) + if self.buffer_empty: + self._write_register_byte(_STMPE_INT_STA, 0xFF) + return (x_loc, y_loc, pressure) + + def _read_byte(self, register): + """Read a byte register value and return it.""" + return self._read_register(register, 1)[0] + + def _read_register(self, register, length): + """Read an arbitrarily long register (specified by length number of + bytes) and return a bytearray of the retrieved data. + Subclasses MUST implement this!""" + raise NotImplementedError + + def _write_register_byte(self, register, value): + """Write a single byte register at the specified register address. + Subclasses MUST implement this!""" + raise NotImplementedError + + @property + def touches(self): + """Returns a list of touchpoint dicts, with 'x' and 'y' containing the + touch coordinates, and 'pressure'.""" + touchpoints = [] + while (len(touchpoints) < 4) and not self.buffer_empty: + (x_loc, y_loc, pressure) = self.read_data() + point = {"x": x_loc, "y": y_loc, "pressure": pressure} + touchpoints.append(point) + return touchpoints + + @property + def get_version(self): + """Read the version number from the sensor.""" + v_1 = self._read_byte(0) + v_2 = self._read_byte(1) + version = v_1 << 8 | v_2 + # print("version ",hex(version)) + return version + + @property + def touched(self): + """Report if any touches were detected.""" + touch = self._read_byte(_STMPE_TSC_CTRL) & 0x80 + return touch == 0x80 + + @property + def buffer_size(self): + """The amount of touch data in the buffer.""" + return self._read_byte(_STMPE_FIFO_SIZE) + + @property + def buffer_empty(self): + """Buffer empty status.""" + empty = self._read_byte(_STMPE_FIFO_STA) & _STMPE_FIFO_STA_EMPTY + return empty != 0 + + @property + def get_point(self): + """Read one touch from the buffer.""" + (x_loc, y_loc, pressure) = self.read_data() + point = {"x": x_loc, "y": y_loc, "pressure": pressure} + return point + + @property + def touch_point(self): + """Read latest touched point value and convert to calibration-adjusted + and rotated display coordinates. Commpatible with Displayio Button. + :return: x, y, pressure + rtype: int, int, int + """ + if not self.buffer_empty: + while not self.buffer_empty: + x_loc, y_loc, pressure = self.read_data() + # Swap touch axis range minimum and maximum if needed + # pylint: disable=too-many-branches + if self._disp_rotation in (0, 180): + if self._touch_flip and self._touch_flip[0]: + x_c = (self._calib[0][1], self._calib[0][0]) + else: + x_c = (self._calib[0][0], self._calib[0][1]) + if self._touch_flip and self._touch_flip[1]: + y_c = (self._calib[1][1], self._calib[1][0]) + else: + y_c = (self._calib[1][0], self._calib[1][1]) + if self._disp_rotation in (90, 270): + if self._touch_flip[1]: + x_c = (self._calib[1][1], self._calib[1][0]) + else: + x_c = (self._calib[1][0], self._calib[1][1]) + if self._touch_flip[0]: + y_c = (self._calib[0][1], self._calib[0][0]) + else: + y_c = (self._calib[0][0], self._calib[0][1]) + # Adjust to calibration range; convert to display size and rotation + if self._disp_rotation == 0: + x = int(map_range(y_loc, x_c[0], x_c[1], 0, self._disp_size[0])) + y = int(map_range(x_loc, y_c[0], y_c[1], 0, self._disp_size[1])) + elif self._disp_rotation == 90: + x = int(map_range(x_loc, x_c[0], x_c[1], 0, self._disp_size[0])) + y = int(map_range(y_loc, y_c[0], y_c[1], self._disp_size[1], 0)) + elif self._disp_rotation == 180: + x = int(map_range(y_loc, x_c[0], x_c[1], self._disp_size[0], 0)) + y = int(map_range(x_loc, y_c[0], y_c[1], self._disp_size[1], 0)) + elif self._disp_rotation == 270: + x = int(map_range(x_loc, x_c[0], x_c[1], self._disp_size[0], 0)) + y = int(map_range(y_loc, y_c[0], y_c[1], 0, self._disp_size[1])) + return (x, y, pressure) + return None + + +class Adafruit_STMPE610_I2C(Adafruit_STMPE610): + """I2C interface class for the STMPE610 Resistive Touch sensor. + + :param i2c: I2C interface bus + :param int address: I2C address. Defaults to 0x41 + :param None, (int, int) calibration: touchscreen calibration tuple. + Defaults to None. + :param None, (int, int) size: display size tuple (width, height). + Defaults to None. + :param int disp_rotation: display rotation in degrees. Values allowed are + 0, 90, 180, and 270. Defaults to 0. + :param (bool, bool) touch_flip: swap touchscreen axis range minimum and + maximum values for (x, y) axes as referenced to display 0-degree rotation. + Defaults to (False, False). + + ** Quickstart: Importing and instantiating Adafruit_STMPE610_I2C** + + Import the Adafruit_STMPE610_I2C class and instantiate for the 2.4" TFT Wing + after instantiating the display: + + .. code-block:: python + + import adafruit_stmpe610 + ts = adafruit_stmpe610.Adafruit_STMPE610_I2C(board.I2C(), address=0x41, + calibration=((357, 3812), (390, 3555)), + size=(display.width, display.height), disp_rotation=display.rotation, + touch_flip=(False, False)) + + """ + + def __init__( # pylint: disable=too-many-arguments + self, + i2c, + address=_STMPE_ADDR, + calibration=None, + size=None, + disp_rotation=0, + touch_flip=(False, False), + ): + + self._calib = calibration + self._disp_size = size + self._disp_rotation = disp_rotation + self._touch_flip = touch_flip + + """Check the touchscreen calibration and display size kwargs.""" + if not self._calib: + self._calib = ((0, 4095), (0, 4095)) + if not self._disp_size: + self._disp_size = (4095, 4095) + + if not self._disp_rotation in (0, 90, 180, 270): + raise ValueError("Display rotation value must be 0, 90, 180, or 270") + + """Check that the STMPE610 was found.""" + import adafruit_bus_device.i2c_device as i2cdev # pylint: disable=import-outside-toplevel + + self._i2c = i2cdev.I2CDevice(i2c, address) + # Check device version. + version = self.get_version + if _STMPE_VERSION != version: + raise RuntimeError("Failed to find STMPE610! Chip Version 0x%x" % version) + super().__init__() + + def _read_register(self, register, length): + """Low level register reading over I2C, returns a list of values.""" + with self._i2c as i2c: + i2c.write(bytearray([register & 0xFF])) + result = bytearray(length) + i2c.readinto(result) + # print("$%02X => %s" % (register, [hex(i) for i in result])) + return result + + def _write_register_byte(self, register, value): + """Low level register writing over I2C, writes one 8-bit value.""" + with self._i2c as i2c: + i2c.write(bytes([register & 0xFF, value & 0xFF])) + # print("$%02X <= 0x%02X" % (register, value)) + + +class Adafruit_STMPE610_SPI(Adafruit_STMPE610): + """SPI interface class for the STMPE610 Resistive Touch sensor. + + :param spi: SPI interface bus + :param pin cs: touchscreen SPI interface chip select pin + :param int baudrate: SPI interface clock speed in Hz. + Defaults to 1000000 (1MHz). + :param None, (int, int) calibration: touchscreen calibration tuple. + Defaults to None. + :param None, (int, int) size: display size tuple (width, height). + Defaults to None. + :param int disp_rotation: display rotation in degrees. Values allowed are + 0, 90, 180, and 270. Defaults to 0. + :param (bool, bool) touch_flip: swap touchscreen axis range minimum and + maximum values for (x, y) axes as referenced to display 0-degree rotation. + Defaults to (False, False). + + ** Quickstart: Importing and instantiating Adafruit_STMPE610_I2C** + + Import the Adafruit_STMPE610_SPI class and instantiate for the 2.4" TFT Wing + after instantiating the display: + + .. code-block:: python + + import adafruit_stmpe610 + ts = adafruit_stmpe610.Adafruit_STMPE610_SPI(spi, cs=cs_pin, + baudrate=1000000, + calibration=((357, 3812), (390, 3555)), + size=(display.width, display.height), disp_rotation=display.rotation, + touch_flip=(False, False)) + + """ + + def __init__( # pylint: disable=too-many-arguments + self, + spi, + cs, + baudrate=1000000, + calibration=None, + size=None, + disp_rotation=0, + touch_flip=(False, False), + ): + + self._calib = calibration + self._disp_size = size + self._disp_rotation = disp_rotation + self._touch_flip = touch_flip + + """Check the touchscreen calibration and display size kwargs.""" + if not self._calib: + self._calib = ((0, 4095), (0, 4095)) + if not self._disp_size: + self._disp_size = (4095, 4095) + + if not self._disp_rotation in (0, 90, 180, 270): + raise ValueError("Display rotation value must be 0, 90, 180, or 270") + + """Check that the STMPE610 was found.""" + import adafruit_bus_device.spi_device as spidev # pylint: disable=import-outside-toplevel + + self._spi = spidev.SPIDevice(spi, cs, baudrate=baudrate) + # Check device version. + version = self.get_version + if _STMPE_VERSION != version: + # If it fails try SPI MODE 1 -- that is what Arduino does + self._spi = spidev.SPIDevice( + spi, cs, baudrate=baudrate, polarity=0, phase=1 + ) + version = self.get_version + if _STMPE_VERSION != version: + raise RuntimeError( + "Failed to find STMPE610 controller! Chip Version 0x%x. " + "If you are using the breakout, verify you are in SPI mode." + % version + ) + super().__init__() + + # pylint: disable=no-member + # Disable should be reconsidered when refactor can be tested. + def _read_register(self, register, length): + """Low level register reading over SPI, returns a list of values.""" + register = (register | 0x80) & 0xFF # Read single byte, bit 7 high. + with self._spi as spi: + spi.write(bytearray([register])) + result = bytearray(length) + spi.readinto(result) + # print("$%02X => %s" % (register, [hex(i) for i in result])) + return result + + def _write_register_byte(self, register, value): + """Low level register writing over SPI, writes one 8-bit value.""" + register &= 0x7F # Write, bit 7 low. + with self._spi as spi: + spi.write(bytes([register, value & 0xFF])) diff --git a/examples/stmpe610_button_demo.py b/examples/stmpe610_button_demo.py index a84480f..0d6aaed 100755 --- a/examples/stmpe610_button_demo.py +++ b/examples/stmpe610_button_demo.py @@ -1,94 +1,93 @@ -# SPDX-FileCopyrightText: 2022 ladyada for Adafruit Industries -# SPDX-License-Identifier: MIT -""" -Simple button demonstration/example. -STMPE610 touch controller with TFT FeatherWing Display - -Author(s): ladyada, CedarGroveMakerStudios - -""" - -import board -import digitalio -import displayio -import terminalio -import time -import adafruit_stmpe610 -from adafruit_button import Button - -# --| Button Config |------------------------------------------------- -BUTTON_X = 50 -BUTTON_Y = 50 -BUTTON_WIDTH = 100 -BUTTON_HEIGHT = 50 -BUTTON_STYLE = Button.ROUNDRECT -BUTTON_FILL_COLOR = 0x00FFFF -BUTTON_OUTLINE_COLOR = 0xFF00FF -BUTTON_LABEL = "HELLO WORLD" -BUTTON_LABEL_COLOR = 0x000000 -# --| Button Config |------------------------------------------------- - -# Release any resources currently in use for the displays -displayio.release_displays() -disp_bus = displayio.FourWire( - board.SPI(), command=board.D10, chip_select=board.D9, reset=None -) - -# Instantiate the 2.4" 320x240 TFT FeatherWing (#3315). -from adafruit_ili9341 import ILI9341 - -display = ILI9341(disp_bus, width=320, height=240) -_touch_flip = (False, False) - -"""# Instantiate the 3.5" 480x320 TFT FeatherWing (#3651). -from adafruit_hx8357 import HX8357 -display = HX8357(disp_bus, width=480, height=320) -_touch_flip = (False, True)""" - -# Always set rotation before instantiating the touchscreen -display.rotation = 0 - -# Instantiate touchscreen -ts_cs = digitalio.DigitalInOut(board.D6) -ts = adafruit_stmpe610.Adafruit_STMPE610_SPI( - board.SPI(), - ts_cs, - calibration=((357, 3812), (390, 3555)), - size=(display.width, display.height), - disp_rotation=display.rotation, - touch_flip=_touch_flip, -) - -# Create the displayio group and show it -splash = displayio.Group() -display.show(splash) - -# Defiine the button -button = Button( - x=BUTTON_X, - y=BUTTON_Y, - width=BUTTON_WIDTH, - height=BUTTON_HEIGHT, - style=BUTTON_STYLE, - fill_color=BUTTON_FILL_COLOR, - outline_color=BUTTON_OUTLINE_COLOR, - label=BUTTON_LABEL, - label_font=terminalio.FONT, - label_color=BUTTON_LABEL_COLOR, -) - -# Add button to the displayio group -splash.append(button) - -# Loop and look for touches -while True: - p = ts.touch_point - if p: - if button.contains(p): - button.selected = True - # Perform a task related to the button press here - time.sleep(0.25) # Wait a bit so we can see the button color change - else: - button.selected = False # When touch moves outside of button - else: - button.selected = False # When button is released +# SPDX-FileCopyrightText: 2022 ladyada for Adafruit Industries +# SPDX-License-Identifier: MIT +""" +Simple button demonstration/example. +STMPE610 touch controller with TFT FeatherWing Display + +Author(s): ladyada, CedarGroveMakerStudios + +""" + +import time +import board +import digitalio +import displayio +import terminalio +#from adafruit_hx8357 import HX8357 +from adafruit_ili9341 import ILI9341 +from adafruit_button import Button +import adafruit_stmpe610 + +# --| Button Config |------------------------------------------------- +BUTTON_X = 50 +BUTTON_Y = 50 +BUTTON_WIDTH = 100 +BUTTON_HEIGHT = 50 +BUTTON_STYLE = Button.ROUNDRECT +BUTTON_FILL_COLOR = 0x00FFFF +BUTTON_OUTLINE_COLOR = 0xFF00FF +BUTTON_LABEL = "HELLO WORLD" +BUTTON_LABEL_COLOR = 0x000000 +# --| Button Config |------------------------------------------------- + +# Release any resources currently in use for the displays +displayio.release_displays() +disp_bus = displayio.FourWire( + board.SPI(), command=board.D10, chip_select=board.D9, reset=None +) + +# Instantiate the 2.4" 320x240 TFT FeatherWing (#3315). +display = ILI9341(disp_bus, width=320, height=240) +_touch_flip = (False, False) + +"""# Instantiate the 3.5" 480x320 TFT FeatherWing (#3651). +display = HX8357(disp_bus, width=480, height=320) +_touch_flip = (False, True)""" + +# Always set rotation before instantiating the touchscreen +display.rotation = 0 + +# Instantiate touchscreen +ts_cs = digitalio.DigitalInOut(board.D6) +ts = adafruit_stmpe610.Adafruit_STMPE610_SPI( + board.SPI(), + ts_cs, + calibration=((357, 3812), (390, 3555)), + size=(display.width, display.height), + disp_rotation=display.rotation, + touch_flip=_touch_flip, +) + +# Create the displayio group and show it +splash = displayio.Group() +display.show(splash) + +# Defiine the button +button = Button( + x=BUTTON_X, + y=BUTTON_Y, + width=BUTTON_WIDTH, + height=BUTTON_HEIGHT, + style=BUTTON_STYLE, + fill_color=BUTTON_FILL_COLOR, + outline_color=BUTTON_OUTLINE_COLOR, + label=BUTTON_LABEL, + label_font=terminalio.FONT, + label_color=BUTTON_LABEL_COLOR, +) + +# Add button to the displayio group +splash.append(button) + +# Loop and look for touches +while True: + p = ts.touch_point + if p: + if button.contains(p): + button.selected = True + # Perform a task related to the button press here + time.sleep(0.25) # Wait a bit so we can see the button color change + else: + button.selected = False # When touch moves outside of button + else: + button.selected = False # When button is released diff --git a/examples/touch_calibrator_stmpe610.py b/examples/touch_calibrator_stmpe610.py index ffaa19a..fdff65d 100755 --- a/examples/touch_calibrator_stmpe610.py +++ b/examples/touch_calibrator_stmpe610.py @@ -28,15 +28,17 @@ calibration tuple for screen coordinate conversion accuracy. """ -import board import time +import board import digitalio import displayio import vectorio from adafruit_bitmap_font import bitmap_font from adafruit_display_text.label import Label -import adafruit_stmpe610 +#from adafruit_hx8357 import HX8357 +from adafruit_ili9341 import ILI9341 from simpleio import map_range +import adafruit_stmpe610 # Operational parameters: DISPLAY_ROTATION = 0 # Specify 0, 90, 180, or 270 degrees @@ -51,7 +53,7 @@ class Colors: BLUE_DK = 0x000060 # Screen fill RED = 0xFF0000 # Boundary WHITE = 0xFFFFFF # Text - + # Release any resources currently in use for the displays displayio.release_displays() @@ -62,19 +64,16 @@ class Colors: ) # Instantiate the 2.4" 320x240 TFT FeatherWing (#3315). -from adafruit_ili9341 import ILI9341 - display = ILI9341(disp_bus, width=320, height=240) _touch_flip = (False, False) """# Instantiate the 3.5" 480x320 TFT FeatherWing (#3651). -from adafruit_hx8357 import HX8357 display = HX8357(disp_bus, width=480, height=320) _touch_flip = (False, True)""" # Check rotation value and update display. # Always set rotation before instantiating the touchscreen. -if DISPLAY_ROTATION != None and DISPLAY_ROTATION in (0, 90, 180, 270): +if DISPLAY_ROTATION is not None and DISPLAY_ROTATION in (0, 90, 180, 270): display.rotation = DISPLAY_ROTATION else: print("Warning: invalid rotation value -- defalting to zero") From 329ad2b524c2beb07feb9f6565503db0a9d3f499 Mon Sep 17 00:00:00 2001 From: Cedar Grove Maker Studios Date: Thu, 20 Jan 2022 18:19:06 -0800 Subject: [PATCH 07/17] fix pylint errors --- adafruit_stmpe610.py | 10 +++++----- examples/touch_calibrator_stmpe610.py | 17 ++++++++--------- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/adafruit_stmpe610.py b/adafruit_stmpe610.py index 566e7e0..29b71c8 100755 --- a/adafruit_stmpe610.py +++ b/adafruit_stmpe610.py @@ -345,16 +345,16 @@ def __init__( # pylint: disable=too-many-arguments self._disp_rotation = disp_rotation self._touch_flip = touch_flip - """Check the touchscreen calibration and display size kwargs.""" + # Check the touchscreen calibration and display size kwargs. if not self._calib: self._calib = ((0, 4095), (0, 4095)) if not self._disp_size: self._disp_size = (4095, 4095) - if not self._disp_rotation in (0, 90, 180, 270): + if self._disp_rotation not in (0, 90, 180, 270): raise ValueError("Display rotation value must be 0, 90, 180, or 270") - """Check that the STMPE610 was found.""" + # Check that the STMPE610 was found. import adafruit_bus_device.i2c_device as i2cdev # pylint: disable=import-outside-toplevel self._i2c = i2cdev.I2CDevice(i2c, address) @@ -429,7 +429,7 @@ def __init__( # pylint: disable=too-many-arguments self._disp_rotation = disp_rotation self._touch_flip = touch_flip - """Check the touchscreen calibration and display size kwargs.""" + # Check the touchscreen calibration and display size kwargs. if not self._calib: self._calib = ((0, 4095), (0, 4095)) if not self._disp_size: @@ -438,7 +438,7 @@ def __init__( # pylint: disable=too-many-arguments if not self._disp_rotation in (0, 90, 180, 270): raise ValueError("Display rotation value must be 0, 90, 180, or 270") - """Check that the STMPE610 was found.""" + # Check that the STMPE610 was found. import adafruit_bus_device.spi_device as spidev # pylint: disable=import-outside-toplevel self._spi = spidev.SPIDevice(spi, cs, baudrate=baudrate) diff --git a/examples/touch_calibrator_stmpe610.py b/examples/touch_calibrator_stmpe610.py index fdff65d..13ed2b4 100755 --- a/examples/touch_calibrator_stmpe610.py +++ b/examples/touch_calibrator_stmpe610.py @@ -49,11 +49,10 @@ CALIBRATION = ((357, 3812), (390, 3555)) # A collection of colors used for graphic objects -class Colors: - BLUE_DK = 0x000060 # Screen fill - RED = 0xFF0000 # Boundary - WHITE = 0xFFFFFF # Text - +BLUE_DK = 0x000060 # Screen fill +RED = 0xFF0000 # Boundary +WHITE = 0xFFFFFF # Text + # Release any resources currently in use for the displays displayio.release_displays() @@ -112,7 +111,7 @@ class Colors: coordinates = Label( font=font_0, text="calib: ((x_min, x_max), (y_min, y_max))", - color=Colors.WHITE, + color=WHITE, ) coordinates.anchor_point = (0.5, 0.5) coordinates.anchored_position = (display.width // 2, display.height // 4) @@ -120,14 +119,14 @@ class Colors: display_rotation = Label( font=font_0, text="rotation: " + str(display.rotation), - color=Colors.WHITE, + color=WHITE, ) display_rotation.anchor_point = (0.5, 0.5) display_rotation.anchored_position = (display.width // 2, display.height // 4 - 30) # Define graphic objects for the screen fill, boundary, and touch pen. target_palette = displayio.Palette(1) - target_palette[0] = Colors.BLUE_DK + target_palette[0] = BLUE_DK screen_fill = vectorio.Rectangle( pixel_shader=target_palette, x=2, @@ -137,7 +136,7 @@ class Colors: ) target_palette = displayio.Palette(1) - target_palette[0] = Colors.RED + target_palette[0] = RED boundary = vectorio.Rectangle( pixel_shader=target_palette, x=0, From cdd15828190b292976065fed5143c4a6e020f4be Mon Sep 17 00:00:00 2001 From: Cedar Grove Maker Studios Date: Thu, 20 Jan 2022 18:25:27 -0800 Subject: [PATCH 08/17] fix pylint errors --- adafruit_stmpe610.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/adafruit_stmpe610.py b/adafruit_stmpe610.py index 29b71c8..54e5a7a 100755 --- a/adafruit_stmpe610.py +++ b/adafruit_stmpe610.py @@ -254,7 +254,7 @@ def get_point(self): return point @property - def touch_point(self): + def touch_point(self): # pylint: disable=too-many-branches """Read latest touched point value and convert to calibration-adjusted and rotated display coordinates. Commpatible with Displayio Button. :return: x, y, pressure @@ -264,7 +264,6 @@ def touch_point(self): while not self.buffer_empty: x_loc, y_loc, pressure = self.read_data() # Swap touch axis range minimum and maximum if needed - # pylint: disable=too-many-branches if self._disp_rotation in (0, 180): if self._touch_flip and self._touch_flip[0]: x_c = (self._calib[0][1], self._calib[0][0]) @@ -435,7 +434,7 @@ def __init__( # pylint: disable=too-many-arguments if not self._disp_size: self._disp_size = (4095, 4095) - if not self._disp_rotation in (0, 90, 180, 270): + if self._disp_rotation not in (0, 90, 180, 270): raise ValueError("Display rotation value must be 0, 90, 180, or 270") # Check that the STMPE610 was found. From 75ed29f3e896788b70acb3a8f0d0f94d3e1309a9 Mon Sep 17 00:00:00 2001 From: Cedar Grove Maker Studios Date: Thu, 20 Jan 2022 21:21:38 -0800 Subject: [PATCH 09/17] fix pylint errors --- adafruit_stmpe610.py | 139 ++++++++++++++++++-------- examples/touch_calibrator_stmpe610.py | 3 +- 2 files changed, 97 insertions(+), 45 deletions(-) diff --git a/adafruit_stmpe610.py b/adafruit_stmpe610.py index 54e5a7a..77c9710 100755 --- a/adafruit_stmpe610.py +++ b/adafruit_stmpe610.py @@ -254,49 +254,8 @@ def get_point(self): return point @property - def touch_point(self): # pylint: disable=too-many-branches - """Read latest touched point value and convert to calibration-adjusted - and rotated display coordinates. Commpatible with Displayio Button. - :return: x, y, pressure - rtype: int, int, int - """ - if not self.buffer_empty: - while not self.buffer_empty: - x_loc, y_loc, pressure = self.read_data() - # Swap touch axis range minimum and maximum if needed - if self._disp_rotation in (0, 180): - if self._touch_flip and self._touch_flip[0]: - x_c = (self._calib[0][1], self._calib[0][0]) - else: - x_c = (self._calib[0][0], self._calib[0][1]) - if self._touch_flip and self._touch_flip[1]: - y_c = (self._calib[1][1], self._calib[1][0]) - else: - y_c = (self._calib[1][0], self._calib[1][1]) - if self._disp_rotation in (90, 270): - if self._touch_flip[1]: - x_c = (self._calib[1][1], self._calib[1][0]) - else: - x_c = (self._calib[1][0], self._calib[1][1]) - if self._touch_flip[0]: - y_c = (self._calib[0][1], self._calib[0][0]) - else: - y_c = (self._calib[0][0], self._calib[0][1]) - # Adjust to calibration range; convert to display size and rotation - if self._disp_rotation == 0: - x = int(map_range(y_loc, x_c[0], x_c[1], 0, self._disp_size[0])) - y = int(map_range(x_loc, y_c[0], y_c[1], 0, self._disp_size[1])) - elif self._disp_rotation == 90: - x = int(map_range(x_loc, x_c[0], x_c[1], 0, self._disp_size[0])) - y = int(map_range(y_loc, y_c[0], y_c[1], self._disp_size[1], 0)) - elif self._disp_rotation == 180: - x = int(map_range(y_loc, x_c[0], x_c[1], self._disp_size[0], 0)) - y = int(map_range(x_loc, y_c[0], y_c[1], self._disp_size[1], 0)) - elif self._disp_rotation == 270: - x = int(map_range(x_loc, x_c[0], x_c[1], self._disp_size[0], 0)) - y = int(map_range(y_loc, y_c[0], y_c[1], 0, self._disp_size[1])) - return (x, y, pressure) - return None + def test_text(self): + return self._test class Adafruit_STMPE610_I2C(Adafruit_STMPE610): @@ -363,6 +322,52 @@ def __init__( # pylint: disable=too-many-arguments raise RuntimeError("Failed to find STMPE610! Chip Version 0x%x" % version) super().__init__() + @property + def touch_point(self): # pylint: disable=too-many-branches + """Read latest touched point value and convert to calibration-adjusted + and rotated display coordinates. Commpatible with Displayio Button. + :return: x, y, pressure + rtype: int, int, int + """ + if not self.buffer_empty: + while not self.buffer_empty: + x_loc, y_loc, pressure = self.read_data() + # Swap touch axis range minimum and maximum if needed + if self._disp_rotation in (0, 180): + if self._touch_flip and self._touch_flip[0]: + x_c = (self._calib[0][1], self._calib[0][0]) + else: + x_c = (self._calib[0][0], self._calib[0][1]) + if self._touch_flip and self._touch_flip[1]: + y_c = (self._calib[1][1], self._calib[1][0]) + else: + y_c = (self._calib[1][0], self._calib[1][1]) + if self._disp_rotation in (90, 270): + if self._touch_flip[1]: + x_c = (self._calib[1][1], self._calib[1][0]) + else: + x_c = (self._calib[1][0], self._calib[1][1]) + if self._touch_flip[0]: + y_c = (self._calib[0][1], self._calib[0][0]) + else: + y_c = (self._calib[0][0], self._calib[0][1]) + # Adjust to calibration range; convert to display size and rotation + if self._disp_rotation == 0: + x = int(map_range(y_loc, x_c[0], x_c[1], 0, self._disp_size[0])) + y = int(map_range(x_loc, y_c[0], y_c[1], 0, self._disp_size[1])) + elif self._disp_rotation == 90: + x = int(map_range(x_loc, x_c[0], x_c[1], 0, self._disp_size[0])) + y = int(map_range(y_loc, y_c[0], y_c[1], self._disp_size[1], 0)) + elif self._disp_rotation == 180: + x = int(map_range(y_loc, x_c[0], x_c[1], self._disp_size[0], 0)) + y = int(map_range(x_loc, y_c[0], y_c[1], self._disp_size[1], 0)) + elif self._disp_rotation == 270: + x = int(map_range(x_loc, x_c[0], x_c[1], self._disp_size[0], 0)) + y = int(map_range(y_loc, y_c[0], y_c[1], 0, self._disp_size[1])) + return (x, y, pressure) + return None + + def _read_register(self, register, length): """Low level register reading over I2C, returns a list of values.""" with self._i2c as i2c: @@ -372,6 +377,7 @@ def _read_register(self, register, length): # print("$%02X => %s" % (register, [hex(i) for i in result])) return result + def _write_register_byte(self, register, value): """Low level register writing over I2C, writes one 8-bit value.""" with self._i2c as i2c: @@ -457,6 +463,52 @@ def __init__( # pylint: disable=too-many-arguments ) super().__init__() + @property + def touch_point(self): # pylint: disable=too-many-branches + """Read latest touched point value and convert to calibration-adjusted + and rotated display coordinates. Commpatible with Displayio Button. + :return: x, y, pressure + rtype: int, int, int + """ + if not self.buffer_empty: + while not self.buffer_empty: + x_loc, y_loc, pressure = self.read_data() + # Swap touch axis range minimum and maximum if needed + if self._disp_rotation in (0, 180): + if self._touch_flip and self._touch_flip[0]: + x_c = (self._calib[0][1], self._calib[0][0]) + else: + x_c = (self._calib[0][0], self._calib[0][1]) + if self._touch_flip and self._touch_flip[1]: + y_c = (self._calib[1][1], self._calib[1][0]) + else: + y_c = (self._calib[1][0], self._calib[1][1]) + if self._disp_rotation in (90, 270): + if self._touch_flip[1]: + x_c = (self._calib[1][1], self._calib[1][0]) + else: + x_c = (self._calib[1][0], self._calib[1][1]) + if self._touch_flip[0]: + y_c = (self._calib[0][1], self._calib[0][0]) + else: + y_c = (self._calib[0][0], self._calib[0][1]) + # Adjust to calibration range; convert to display size and rotation + if self._disp_rotation == 0: + x = int(map_range(y_loc, x_c[0], x_c[1], 0, self._disp_size[0])) + y = int(map_range(x_loc, y_c[0], y_c[1], 0, self._disp_size[1])) + elif self._disp_rotation == 90: + x = int(map_range(x_loc, x_c[0], x_c[1], 0, self._disp_size[0])) + y = int(map_range(y_loc, y_c[0], y_c[1], self._disp_size[1], 0)) + elif self._disp_rotation == 180: + x = int(map_range(y_loc, x_c[0], x_c[1], self._disp_size[0], 0)) + y = int(map_range(x_loc, y_c[0], y_c[1], self._disp_size[1], 0)) + elif self._disp_rotation == 270: + x = int(map_range(x_loc, x_c[0], x_c[1], self._disp_size[0], 0)) + y = int(map_range(y_loc, y_c[0], y_c[1], 0, self._disp_size[1])) + return (x, y, pressure) + return None + + # pylint: disable=no-member # Disable should be reconsidered when refactor can be tested. def _read_register(self, register, length): @@ -469,6 +521,7 @@ def _read_register(self, register, length): # print("$%02X => %s" % (register, [hex(i) for i in result])) return result + def _write_register_byte(self, register, value): """Low level register writing over SPI, writes one 8-bit value.""" register &= 0x7F # Write, bit 7 low. diff --git a/examples/touch_calibrator_stmpe610.py b/examples/touch_calibrator_stmpe610.py index 13ed2b4..e6081ef 100755 --- a/examples/touch_calibrator_stmpe610.py +++ b/examples/touch_calibrator_stmpe610.py @@ -41,7 +41,7 @@ import adafruit_stmpe610 # Operational parameters: -DISPLAY_ROTATION = 0 # Specify 0, 90, 180, or 270 degrees +DISPLAY_ROTATION = 270 # Specify 0, 90, 180, or 270 degrees REPL_ONLY = False # True to disable graphics RAW_DATA = True # Use touchscreen raw values; False to use display coordinates @@ -53,7 +53,6 @@ RED = 0xFF0000 # Boundary WHITE = 0xFFFFFF # Text - # Release any resources currently in use for the displays displayio.release_displays() From a9f61ac403ac34a283285c60ceb344496c41673b Mon Sep 17 00:00:00 2001 From: Cedar Grove Maker Studios Date: Thu, 20 Jan 2022 21:26:18 -0800 Subject: [PATCH 10/17] fix pylint error --- adafruit_stmpe610.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/adafruit_stmpe610.py b/adafruit_stmpe610.py index 77c9710..be67c19 100755 --- a/adafruit_stmpe610.py +++ b/adafruit_stmpe610.py @@ -253,10 +253,6 @@ def get_point(self): point = {"x": x_loc, "y": y_loc, "pressure": pressure} return point - @property - def test_text(self): - return self._test - class Adafruit_STMPE610_I2C(Adafruit_STMPE610): """I2C interface class for the STMPE610 Resistive Touch sensor. From fb2ce9bdbae2db50ad9dcfe89e54df9b836fb5c7 Mon Sep 17 00:00:00 2001 From: Cedar Grove Maker Studios Date: Thu, 20 Jan 2022 21:31:19 -0800 Subject: [PATCH 11/17] formatted with black --- adafruit_stmpe610.py | 8 ++------ examples/stmpe610_button_demo.py | 3 ++- examples/touch_calibrator_stmpe610.py | 5 +++-- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/adafruit_stmpe610.py b/adafruit_stmpe610.py index be67c19..a0e1343 100755 --- a/adafruit_stmpe610.py +++ b/adafruit_stmpe610.py @@ -319,7 +319,7 @@ def __init__( # pylint: disable=too-many-arguments super().__init__() @property - def touch_point(self): # pylint: disable=too-many-branches + def touch_point(self): # pylint: disable=too-many-branches """Read latest touched point value and convert to calibration-adjusted and rotated display coordinates. Commpatible with Displayio Button. :return: x, y, pressure @@ -363,7 +363,6 @@ def touch_point(self): # pylint: disable=too-many-branches return (x, y, pressure) return None - def _read_register(self, register, length): """Low level register reading over I2C, returns a list of values.""" with self._i2c as i2c: @@ -373,7 +372,6 @@ def _read_register(self, register, length): # print("$%02X => %s" % (register, [hex(i) for i in result])) return result - def _write_register_byte(self, register, value): """Low level register writing over I2C, writes one 8-bit value.""" with self._i2c as i2c: @@ -460,7 +458,7 @@ def __init__( # pylint: disable=too-many-arguments super().__init__() @property - def touch_point(self): # pylint: disable=too-many-branches + def touch_point(self): # pylint: disable=too-many-branches """Read latest touched point value and convert to calibration-adjusted and rotated display coordinates. Commpatible with Displayio Button. :return: x, y, pressure @@ -504,7 +502,6 @@ def touch_point(self): # pylint: disable=too-many-branches return (x, y, pressure) return None - # pylint: disable=no-member # Disable should be reconsidered when refactor can be tested. def _read_register(self, register, length): @@ -517,7 +514,6 @@ def _read_register(self, register, length): # print("$%02X => %s" % (register, [hex(i) for i in result])) return result - def _write_register_byte(self, register, value): """Low level register writing over SPI, writes one 8-bit value.""" register &= 0x7F # Write, bit 7 low. diff --git a/examples/stmpe610_button_demo.py b/examples/stmpe610_button_demo.py index 0d6aaed..db3c71c 100755 --- a/examples/stmpe610_button_demo.py +++ b/examples/stmpe610_button_demo.py @@ -13,7 +13,8 @@ import digitalio import displayio import terminalio -#from adafruit_hx8357 import HX8357 + +# from adafruit_hx8357 import HX8357 from adafruit_ili9341 import ILI9341 from adafruit_button import Button import adafruit_stmpe610 diff --git a/examples/touch_calibrator_stmpe610.py b/examples/touch_calibrator_stmpe610.py index e6081ef..47a77d6 100755 --- a/examples/touch_calibrator_stmpe610.py +++ b/examples/touch_calibrator_stmpe610.py @@ -35,13 +35,14 @@ import vectorio from adafruit_bitmap_font import bitmap_font from adafruit_display_text.label import Label -#from adafruit_hx8357 import HX8357 + +# from adafruit_hx8357 import HX8357 from adafruit_ili9341 import ILI9341 from simpleio import map_range import adafruit_stmpe610 # Operational parameters: -DISPLAY_ROTATION = 270 # Specify 0, 90, 180, or 270 degrees +DISPLAY_ROTATION = 0 # Specify 0, 90, 180, or 270 degrees REPL_ONLY = False # True to disable graphics RAW_DATA = True # Use touchscreen raw values; False to use display coordinates From 78f1b5200767fd243785dd015eed23f9bfcf34e4 Mon Sep 17 00:00:00 2001 From: Cedar Grove Maker Studios Date: Fri, 21 Jan 2022 09:59:17 -0800 Subject: [PATCH 12/17] replace font with terminalio.FONT --- examples/touch_calibrator_stmpe610.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/examples/touch_calibrator_stmpe610.py b/examples/touch_calibrator_stmpe610.py index 47a77d6..0cd5bf3 100755 --- a/examples/touch_calibrator_stmpe610.py +++ b/examples/touch_calibrator_stmpe610.py @@ -2,7 +2,7 @@ # SPDX-License-Identifier: MIT """ -touch_calibrator_stmpe610.py 2022-01-20 v1.0 +touch_calibrator_stmpe610.py 2022-01-20 v1.1 Author(s): CedarGroveMakerStudios @@ -33,10 +33,9 @@ import digitalio import displayio import vectorio -from adafruit_bitmap_font import bitmap_font +import terminalio from adafruit_display_text.label import Label - -# from adafruit_hx8357 import HX8357 +#from adafruit_hx8357 import HX8357 from adafruit_ili9341 import ILI9341 from simpleio import map_range import adafruit_stmpe610 @@ -106,7 +105,7 @@ # Define the graphic objects if REPL_ONLY = False. if not REPL_ONLY: # Define the text graphic objects - font_0 = bitmap_font.load_font("/fonts/OpenSans-9.bdf") + font_0 = terminalio.FONT coordinates = Label( font=font_0, From 8940ef917ed2515a5cc5f142aa65938de6228b48 Mon Sep 17 00:00:00 2001 From: Cedar Grove Maker Studios Date: Fri, 21 Jan 2022 10:03:05 -0800 Subject: [PATCH 13/17] formatted with black --- examples/touch_calibrator_stmpe610.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/touch_calibrator_stmpe610.py b/examples/touch_calibrator_stmpe610.py index 0cd5bf3..7f90348 100755 --- a/examples/touch_calibrator_stmpe610.py +++ b/examples/touch_calibrator_stmpe610.py @@ -35,7 +35,8 @@ import vectorio import terminalio from adafruit_display_text.label import Label -#from adafruit_hx8357 import HX8357 + +# from adafruit_hx8357 import HX8357 from adafruit_ili9341 import ILI9341 from simpleio import map_range import adafruit_stmpe610 From dd0030a8756f1f050bafa2c845526c3ea0d13ea8 Mon Sep 17 00:00:00 2001 From: Cedar Grove Maker Studios Date: Fri, 21 Jan 2022 21:58:57 -0800 Subject: [PATCH 14/17] improve useage instructions --- examples/touch_calibrator_stmpe610.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/examples/touch_calibrator_stmpe610.py b/examples/touch_calibrator_stmpe610.py index 7f90348..1377bb6 100755 --- a/examples/touch_calibrator_stmpe610.py +++ b/examples/touch_calibrator_stmpe610.py @@ -2,7 +2,7 @@ # SPDX-License-Identifier: MIT """ -touch_calibrator_stmpe610.py 2022-01-20 v1.1 +touch_calibrator_stmpe610.py 2022-01-21 v1.1 Author(s): CedarGroveMakerStudios @@ -15,6 +15,10 @@ tuple can be copied and pasted into the calling code's touchscreen instantiation statement. +NOTE: When instantiating the STMPE610 controller, enter the 0-degree display +rotation raw touch calibration value regardless of screen rotation value. +The controller code will automatically adjust the calibration as needed. + DISPLAY_ROTATION: Display rotation value in degrees. Only values of None, 0, 90, 180, and 270 degrees are accepted. Defaults to None, the previous orientation of the display. @@ -42,11 +46,14 @@ import adafruit_stmpe610 # Operational parameters: -DISPLAY_ROTATION = 0 # Specify 0, 90, 180, or 270 degrees +# Specify 0, 90, 180, or 270 degrees; +# use 0 for instantiation calibration tuple. +DISPLAY_ROTATION = 0 REPL_ONLY = False # True to disable graphics RAW_DATA = True # Use touchscreen raw values; False to use display coordinates -# Previously measured raw calibration tuple for display coordinate mode (RAW_DATA = False): +# Previously measured raw calibration tuple for +# display coordinate mode (RAW_DATA = False): CALIBRATION = ((357, 3812), (390, 3555)) # A collection of colors used for graphic objects From 5a3ec100e7258811c78b78aca1fc4091a112abdc Mon Sep 17 00:00:00 2001 From: Cedar Grove Maker Studios Date: Sat, 22 Jan 2022 11:49:50 -0800 Subject: [PATCH 15/17] update automatic version; add hardware information --- adafruit_stmpe610.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/adafruit_stmpe610.py b/adafruit_stmpe610.py index a0e1343..36dd975 100755 --- a/adafruit_stmpe610.py +++ b/adafruit_stmpe610.py @@ -12,6 +12,13 @@ -------------------- **Hardware:** +* 2.4" 320x240 TFT FeatherWing display + https://www.adafruit.com/product/3315 +* 3.5" 480x320 TFT FeatherWing display + https://www.adafruit.com/product/3651 +# Resistive Touch Screen Controller - STMPE610 breakout board + https://www.adafruit.com/product/1571 (discontinued) + **Software and Dependencies:** * Adafruit CircuitPython firmware for the supported boards: @@ -22,7 +29,7 @@ from micropython import const -__version__ = "1.2.7" +__version__ = "0.0.0-auto.0" __repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_STMPE610.git" From f9daa2b5fefd3e28fa5bd899d53acf9f91be5c64 Mon Sep 17 00:00:00 2001 From: Cedar Grove Maker Studios Date: Sat, 22 Jan 2022 11:56:33 -0800 Subject: [PATCH 16/17] fix documentaton --- adafruit_stmpe610.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/adafruit_stmpe610.py b/adafruit_stmpe610.py index 36dd975..723b818 100755 --- a/adafruit_stmpe610.py +++ b/adafruit_stmpe610.py @@ -12,11 +12,9 @@ -------------------- **Hardware:** -* 2.4" 320x240 TFT FeatherWing display - https://www.adafruit.com/product/3315 -* 3.5" 480x320 TFT FeatherWing display - https://www.adafruit.com/product/3651 -# Resistive Touch Screen Controller - STMPE610 breakout board +* 2.4" 320x240 TFT FeatherWing display: https://www.adafruit.com/product/3315 +* 3.5" 480x320 TFT FeatherWing display: https://www.adafruit.com/product/3651 +# Resistive Touch Screen Controller - STMPE610 breakout board: https://www.adafruit.com/product/1571 (discontinued) **Software and Dependencies:** From 841c153a03d8dbfefd4573bcf55cc7bf9a20cf00 Mon Sep 17 00:00:00 2001 From: Cedar Grove Maker Studios Date: Sat, 22 Jan 2022 12:04:31 -0800 Subject: [PATCH 17/17] fix documentation --- adafruit_stmpe610.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/adafruit_stmpe610.py b/adafruit_stmpe610.py index 723b818..d72eb89 100755 --- a/adafruit_stmpe610.py +++ b/adafruit_stmpe610.py @@ -14,7 +14,7 @@ * 2.4" 320x240 TFT FeatherWing display: https://www.adafruit.com/product/3315 * 3.5" 480x320 TFT FeatherWing display: https://www.adafruit.com/product/3651 -# Resistive Touch Screen Controller - STMPE610 breakout board: +* Resistive Touch Screen Controller - STMPE610 breakout board: https://www.adafruit.com/product/1571 (discontinued) **Software and Dependencies:**