mirror of
https://github.com/letscontrolit/ESPEasy.git
synced 2026-09-12 09:36:59 +00:00
Merge pull request #5067 from tonhuisman/feature/P123-add-support-for-more-touchscreen-types
[P123] Add support for GT911, CST820, CST226, AXS15231 and CHSC5816 touch screens
This commit is contained in:
@@ -232,17 +232,37 @@
|
||||
:red:`Internal`","
|
||||
Run I2C scanner to find connected I2C chips. Output will be sent to the serial port.
|
||||
|
||||
``I2Cscanner``
|
||||
``I2Cscanner[,1]``
|
||||
|
||||
Added: 2024-06-14:
|
||||
With the optional debug argument ``1`` provided, the returned I2C status (error) code will be listed for *all* tested I2C addresses.
|
||||
|
||||
Added: 2024-06-14:
|
||||
Scan is performed at the Low I2C speed configured (default 100 kHz). When having an I2C multiplexer configured, all channels of the multiplexer will also be scanned.
|
||||
|
||||
Example output:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
4500043 : Info : Command: i2cscanner
|
||||
>i2cscanner
|
||||
Standard I2C bus
|
||||
I2C : Found 0x3c
|
||||
I2C : Found 0x40
|
||||
I2C : Found 0x5a
|
||||
|
||||
>i2cscanner,1
|
||||
Standard I2C bus
|
||||
I2C : Error 2 at 0x01
|
||||
I2C : Error 2 at 0x02
|
||||
I2C : Error 2 at 0x03
|
||||
...
|
||||
I2C : Error 2 at 0x3f
|
||||
I2C : Found 0x40
|
||||
I2C : Error 2 at 0x41
|
||||
...
|
||||
I2C : Error 2 at 0x7e
|
||||
I2C : Error 2 at 0x7f
|
||||
|
||||
"
|
||||
"
|
||||
Inc","
|
||||
|
||||
@@ -24,9 +24,9 @@ Used libraries: |P123_usedlibraries|
|
||||
Supported hardware
|
||||
------------------
|
||||
|
||||
Some displays are available with a touch overlay mounted on top of the visible side of the display. There's a choice of resistive and capacitive touch overlays. The FT62x6 series of touch overlays are of the Capacitive kind, being very easy to interact with, comparable to modern smartphones, where you can use a finger for the interaction. (Resistive touch overlays usually require a special pen to be used, or pressed with a finger-nail, to get a response.)
|
||||
Some displays are available with a touch overlay mounted on top of the visible side of the display. There's a choice of resistive and capacitive touch overlays. The I2C touch overlays supported in this plugin are of the Capacitive kind, being very easy to interact with, comparable to modern smartphones, where you can use a finger for the interaction. (Resistive touch overlays usually require a special pen to be used, or pressed with a finger-nail, to get a response.)
|
||||
|
||||
The FT62x6 touch overlay (or touch screen), can be found on several displays, f.e. some M5Stack devices and the WT32-SC01 display unit.
|
||||
The supported touch overlays (or touch screens), can be found on several displays, f.e. some M5Stack devices, the WT32-SC01 display unit and the LilyGO LILY Pi ESP32 unit.
|
||||
|
||||
Device configuration
|
||||
--------------------
|
||||
@@ -59,7 +59,39 @@ The configured display will be used to draw the objects, if any, that can be con
|
||||
|
||||
* **Display Color-depth**: If the display settings have been retrieved successfully, this setting can not be changed, but will be used from the display. This value is used to select the correct color mappings for displaying the Objects.
|
||||
|
||||
* **Touch minimum pressure**: This setting determines the relative pressure or sensitivity of the touch display. Lower values make it more sensitive. The range is 0 to 255.
|
||||
* **Touch minimum pressure**: This setting determines the relative pressure or sensitivity of the FT62x6 touch displays. Lower values make it more sensitive. The range is 0 to 255. Only applicable for the FT62x6 controller.
|
||||
|
||||
* **Touchscreen Type (Address)**: Select the type of touchscreen installed, available options:
|
||||
|
||||
.. image:: P123_TouchscreenTypeOptions.png
|
||||
|
||||
* *FT62x6 (0x38)*: Focaltech FT62x6/FT63x6/FT52x6 touchscreen controller family. Default selection.
|
||||
|
||||
* *GT911 (0x5D)*: GT911 touchscreen controller, default address.
|
||||
|
||||
* *GT911 (0x14)*: GT911 touchscreen controller, alternate address.
|
||||
|
||||
* *CST820 (0x15)*: CST816/CST820 touchscreen controller family.
|
||||
|
||||
* *CST226 (0x5A)*: CST226 touchscreen controller. (Not yet tested on real hardware)
|
||||
|
||||
* *AXS15231 (0x3B)*: AXS15231 touchscreen controller. (Not yet tested on real hardware)
|
||||
|
||||
* *CHSC5816 (0x2E)*: CHSC5816 touchscreen controller. (Not yet tested on real hardware)
|
||||
|
||||
* *Auto-detect*: Select this option to have the plugin auto-detect the used touchscreen controller. This auto-detect is mostly based on an I2C device being available at the shown addresses, so might get confused if a non-touchscreen I2C device at one of these addresses is installed.
|
||||
|
||||
|
|
||||
|
||||
* **Interrupt pin**: Select the GPIO that is connected to the IRQ connection of a GT911 touchscreen controller. The IRQ pin is only used for detection & address configuration, combined with the **Reset pin**, if available and configured. Only used for GT911 controller.
|
||||
|
||||
* **Reset pin**: Select the GPIO that is connected to the Reset connection of the touchscreen controller. When set, this will be used to reset the controller during initialization. (See the Warning below). Do not set this GPIO setting if the RST pin is shared with another device, like on a WT32 SC01 Plus, where the display and touch controllers use the same GPIO pin. **Only** set the RST pin on the display configuration, and give that Display task a **lower task number** than the touch screen, as the touchscreen task will try to display defined objects on the connected Display device!
|
||||
|
||||
.. note:: The **Interrupt** and **Reset** GPIO pins are optional. Interrupt is only used by the GT911 controller during initialization.
|
||||
|
||||
.. warning:: Some devices that have the reset pin connected, initially set that GPIO to low/0, causing the touch controller not to start, and it won't even show up on the I2C Scan. This can be solved by setting the involved GPIO pin to **Output High** on the :ref:`Hardware_page`.
|
||||
|
||||
.. warning:: During testing we found that specifically the CST816 touchscreen controller, whiel working as expected, **doesn't** show up in an I2C Scan. This also implies they can't be auto-detected, and have to be set explicitly.
|
||||
|
||||
.. include:: Touch_Configuration.repl
|
||||
|
||||
@@ -70,8 +102,7 @@ Change log
|
||||
.. versionadded:: 2.0
|
||||
...
|
||||
|
||||
|added|
|
||||
Initial release version.
|
||||
|added| 2024-06-05 Initial release version.
|
||||
|
||||
|
||||
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 34 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 35 KiB |
@@ -90,20 +90,26 @@ Build set: :yellow:`COLLECTION A`
|
||||
":ref:`P004_page`","P004"
|
||||
":ref:`P005_page`","P005"
|
||||
":ref:`P006_page`","P006"
|
||||
":ref:`P007_page`","P007"
|
||||
":ref:`P008_page`","P008"
|
||||
":ref:`P009_page`","P009"
|
||||
":ref:`P010_page`","P010"
|
||||
":ref:`P011_page`","P011"
|
||||
":ref:`P012_page`","P012"
|
||||
":ref:`P013_page`","P013"
|
||||
":ref:`P014_page`","P014"
|
||||
":ref:`P015_page`","P015"
|
||||
":ref:`P017_page`","P017"
|
||||
":ref:`P018_page`","P018"
|
||||
":ref:`P019_page`","P019"
|
||||
":ref:`P020_page`","P020"
|
||||
":ref:`P021_page`","P021"
|
||||
":ref:`P022_page`","P022"
|
||||
":ref:`P023_page`","P023"
|
||||
":ref:`P024_page`","P024"
|
||||
":ref:`P025_page`","P025"
|
||||
":ref:`P026_page`","P026"
|
||||
":ref:`P027_page`","P027"
|
||||
":ref:`P028_page`","P028"
|
||||
":ref:`P029_page`","P029"
|
||||
":ref:`P031_page`","P031"
|
||||
@@ -114,6 +120,9 @@ Build set: :yellow:`COLLECTION A`
|
||||
":ref:`P037_page`","P037"
|
||||
":ref:`P038_page`","P038"
|
||||
":ref:`P039_page`","P039"
|
||||
":ref:`P040_page`","P040"
|
||||
":ref:`P041_page`","P041"
|
||||
":ref:`P042_page`","P042"
|
||||
":ref:`P043_page`","P043"
|
||||
":ref:`P044_page`","P044"
|
||||
":ref:`P045_page`","P045"
|
||||
@@ -522,20 +531,26 @@ Build set: :yellow:`COLLECTION E`
|
||||
":ref:`P004_page`","P004"
|
||||
":ref:`P005_page`","P005"
|
||||
":ref:`P006_page`","P006"
|
||||
":ref:`P007_page`","P007"
|
||||
":ref:`P008_page`","P008"
|
||||
":ref:`P009_page`","P009"
|
||||
":ref:`P010_page`","P010"
|
||||
":ref:`P011_page`","P011"
|
||||
":ref:`P012_page`","P012"
|
||||
":ref:`P013_page`","P013"
|
||||
":ref:`P014_page`","P014"
|
||||
":ref:`P015_page`","P015"
|
||||
":ref:`P017_page`","P017"
|
||||
":ref:`P018_page`","P018"
|
||||
":ref:`P019_page`","P019"
|
||||
":ref:`P020_page`","P020"
|
||||
":ref:`P021_page`","P021"
|
||||
":ref:`P022_page`","P022"
|
||||
":ref:`P023_page`","P023"
|
||||
":ref:`P024_page`","P024"
|
||||
":ref:`P025_page`","P025"
|
||||
":ref:`P026_page`","P026"
|
||||
":ref:`P027_page`","P027"
|
||||
":ref:`P028_page`","P028"
|
||||
":ref:`P029_page`","P029"
|
||||
":ref:`P031_page`","P031"
|
||||
@@ -546,6 +561,9 @@ Build set: :yellow:`COLLECTION E`
|
||||
":ref:`P037_page`","P037"
|
||||
":ref:`P038_page`","P038"
|
||||
":ref:`P039_page`","P039"
|
||||
":ref:`P040_page`","P040"
|
||||
":ref:`P041_page`","P041"
|
||||
":ref:`P042_page`","P042"
|
||||
":ref:`P043_page`","P043"
|
||||
":ref:`P044_page`","P044"
|
||||
":ref:`P045_page`","P045"
|
||||
@@ -976,6 +994,7 @@ Build set: :yellow:`DISPLAY`
|
||||
":ref:`P104_page`","P104"
|
||||
":ref:`P109_page`","P109"
|
||||
":ref:`P116_page`","P116"
|
||||
":ref:`P123_page`","P123"
|
||||
":ref:`P137_page`","P137"
|
||||
":ref:`P138_page`","P138"
|
||||
":ref:`P141_page`","P141"
|
||||
@@ -1096,6 +1115,9 @@ Build set: :yellow:`IR`
|
||||
":ref:`P004_page`","P004"
|
||||
":ref:`P005_page`","P005"
|
||||
":ref:`P006_page`","P006"
|
||||
":ref:`P007_page`","P007"
|
||||
":ref:`P008_page`","P008"
|
||||
":ref:`P009_page`","P009"
|
||||
":ref:`P010_page`","P010"
|
||||
":ref:`P011_page`","P011"
|
||||
":ref:`P012_page`","P012"
|
||||
@@ -1103,14 +1125,17 @@ Build set: :yellow:`IR`
|
||||
":ref:`P014_page`","P014"
|
||||
":ref:`P015_page`","P015"
|
||||
":ref:`P016_page`","P016"
|
||||
":ref:`P017_page`","P017"
|
||||
":ref:`P018_page`","P018"
|
||||
":ref:`P019_page`","P019"
|
||||
":ref:`P020_page`","P020"
|
||||
":ref:`P021_page`","P021"
|
||||
":ref:`P022_page`","P022"
|
||||
":ref:`P023_page`","P023"
|
||||
":ref:`P024_page`","P024"
|
||||
":ref:`P025_page`","P025"
|
||||
":ref:`P026_page`","P026"
|
||||
":ref:`P027_page`","P027"
|
||||
":ref:`P028_page`","P028"
|
||||
":ref:`P029_page`","P029"
|
||||
":ref:`P031_page`","P031"
|
||||
@@ -1122,6 +1147,9 @@ Build set: :yellow:`IR`
|
||||
":ref:`P037_page`","P037"
|
||||
":ref:`P038_page`","P038"
|
||||
":ref:`P039_page`","P039"
|
||||
":ref:`P040_page`","P040"
|
||||
":ref:`P041_page`","P041"
|
||||
":ref:`P042_page`","P042"
|
||||
":ref:`P043_page`","P043"
|
||||
":ref:`P044_page`","P044"
|
||||
":ref:`P049_page`","P049"
|
||||
@@ -1236,20 +1264,26 @@ Build set: :yellow:`NEOPIXEL`
|
||||
":ref:`P004_page`","P004"
|
||||
":ref:`P005_page`","P005"
|
||||
":ref:`P006_page`","P006"
|
||||
":ref:`P007_page`","P007"
|
||||
":ref:`P008_page`","P008"
|
||||
":ref:`P009_page`","P009"
|
||||
":ref:`P010_page`","P010"
|
||||
":ref:`P011_page`","P011"
|
||||
":ref:`P012_page`","P012"
|
||||
":ref:`P013_page`","P013"
|
||||
":ref:`P014_page`","P014"
|
||||
":ref:`P015_page`","P015"
|
||||
":ref:`P017_page`","P017"
|
||||
":ref:`P018_page`","P018"
|
||||
":ref:`P019_page`","P019"
|
||||
":ref:`P020_page`","P020"
|
||||
":ref:`P021_page`","P021"
|
||||
":ref:`P022_page`","P022"
|
||||
":ref:`P023_page`","P023"
|
||||
":ref:`P024_page`","P024"
|
||||
":ref:`P025_page`","P025"
|
||||
":ref:`P026_page`","P026"
|
||||
":ref:`P027_page`","P027"
|
||||
":ref:`P028_page`","P028"
|
||||
":ref:`P029_page`","P029"
|
||||
":ref:`P031_page`","P031"
|
||||
@@ -1260,6 +1294,7 @@ Build set: :yellow:`NEOPIXEL`
|
||||
":ref:`P037_page`","P037"
|
||||
":ref:`P038_page`","P038"
|
||||
":ref:`P039_page`","P039"
|
||||
":ref:`P040_page`","P040"
|
||||
":ref:`P041_page`","P041"
|
||||
":ref:`P042_page`","P042"
|
||||
":ref:`P043_page`","P043"
|
||||
@@ -1421,6 +1456,7 @@ Build set: :yellow:`MAX`
|
||||
":ref:`P120_page`","P120"
|
||||
":ref:`P121_page`","P121"
|
||||
":ref:`P122_page`","P122"
|
||||
":ref:`P123_page`","P123"
|
||||
":ref:`P124_page`","P124"
|
||||
":ref:`P125_page`","P125"
|
||||
":ref:`P126_page`","P126"
|
||||
|
||||
@@ -37,18 +37,18 @@
|
||||
.. |P122_compileinfo| replace:: `.`
|
||||
.. |P122_usedlibraries| replace:: `I2C`
|
||||
|
||||
.. |P123_name| replace:: :cyan:`FT62x6`
|
||||
.. |P123_name| replace:: :cyan:`I2C Touchscreens`
|
||||
.. |P123_type| replace:: :cyan:`Touch`
|
||||
.. |P123_typename| replace:: :cyan:`Touch - FT62x6`
|
||||
.. |P123_typename| replace:: :cyan:`Touch - I2C Touchscreens`
|
||||
.. |P123_porttype| replace:: `.`
|
||||
.. |P123_status| replace:: :yellow:`DISPLAY`
|
||||
.. |P123_github| replace:: P123_FT62x6Touch.ino
|
||||
.. _P123_github: https://github.com/letscontrolit/ESPEasy/blob/mega/src/_P123_FT62x6Touch.ino
|
||||
.. |P123_github| replace:: P123_I2CTouch.ino
|
||||
.. _P123_github: https://github.com/letscontrolit/ESPEasy/blob/mega/src/_P123_I2CTouch.ino
|
||||
.. |P123_usedby| replace:: `.`
|
||||
.. |P123_shortinfo| replace:: `FT62x6 Display capacitive touch overlay`
|
||||
.. |P123_shortinfo| replace:: `I2C capacitive touchscreen overlays`
|
||||
.. |P123_maintainer| replace:: `tonhuisman`
|
||||
.. |P123_compileinfo| replace:: `.`
|
||||
.. |P123_usedlibraries| replace:: `Adafruit_FT6206_Library (modified)`
|
||||
.. |P123_usedlibraries| replace:: `BitBank bb_captouch library (modified)`
|
||||
|
||||
.. |P124_name| replace:: :cyan:`MultiRelay`
|
||||
.. |P124_type| replace:: :cyan:`Output`
|
||||
|
||||
@@ -1,313 +0,0 @@
|
||||
/*!
|
||||
* @file Adafruit_FT6206.cpp
|
||||
*
|
||||
* @mainpage Adafruit FT2606 Library
|
||||
*
|
||||
* @section intro_sec Introduction
|
||||
*
|
||||
* This is a library for the Adafruit Capacitive Touch Screens
|
||||
*
|
||||
* ----> http://www.adafruit.com/products/1947
|
||||
*
|
||||
* Adjustment: To avoid a conflict with the XPT2048 library, TS_Point struct is renamed to FT_Point
|
||||
*
|
||||
* Check out the links above for our tutorials and wiring diagrams
|
||||
* This chipset uses I2C to communicate
|
||||
*
|
||||
* Adafruit invests time and resources providing this open source code,
|
||||
* please support Adafruit and open-source hardware by purchasing
|
||||
* products from Adafruit!
|
||||
*
|
||||
* @section author Author
|
||||
*
|
||||
* Written by Limor Fried/Ladyada for Adafruit Industries.
|
||||
*
|
||||
* @section license License
|
||||
|
||||
* MIT license, all text above must be included in any redistribution
|
||||
*/
|
||||
|
||||
#include "Arduino.h"
|
||||
#include <Adafruit_FT6206.h>
|
||||
#include <Wire.h>
|
||||
|
||||
#if defined(__SAM3X8E__)
|
||||
#define Wire Wire1
|
||||
#endif
|
||||
|
||||
//#define FT6206_DEBUG
|
||||
//#define I2C_DEBUG
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Instantiates a new FT6206 class
|
||||
*/
|
||||
/**************************************************************************/
|
||||
// I2C, no address adjustments or pins
|
||||
Adafruit_FT6206::Adafruit_FT6206() { touches = 0; }
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Setups the I2C interface and hardware, identifies if chip is found
|
||||
@param thresh Optional threshhold-for-touch value, default is
|
||||
FT6206_DEFAULT_THRESSHOLD but you can try changing it if your screen is
|
||||
too/not sensitive.
|
||||
@returns True if an FT6206 is found, false on any failure
|
||||
*/
|
||||
/**************************************************************************/
|
||||
boolean Adafruit_FT6206::begin(uint8_t thresh) {
|
||||
// Wire.begin();
|
||||
|
||||
#ifdef FT6206_DEBUG
|
||||
Serial.print("Vend ID: 0x");
|
||||
Serial.println(readRegister8(FT62XX_REG_VENDID), HEX);
|
||||
Serial.print("Chip ID: 0x");
|
||||
Serial.println(readRegister8(FT62XX_REG_CHIPID), HEX);
|
||||
Serial.print("Firm V: ");
|
||||
Serial.println(readRegister8(FT62XX_REG_FIRMVERS));
|
||||
Serial.print("Point Rate Hz: ");
|
||||
Serial.println(readRegister8(FT62XX_REG_POINTRATE));
|
||||
Serial.print("Thresh: ");
|
||||
Serial.println(readRegister8(FT62XX_REG_THRESHHOLD));
|
||||
|
||||
// dump all registers
|
||||
for (int16_t i = 0; i < 0x10; i++) {
|
||||
Serial.print("I2C $");
|
||||
Serial.print(i, HEX);
|
||||
Serial.print(" = 0x");
|
||||
Serial.println(readRegister8(i), HEX);
|
||||
}
|
||||
#endif
|
||||
|
||||
// change threshhold to be higher/lower
|
||||
writeRegister8(FT62XX_REG_THRESHHOLD, thresh);
|
||||
|
||||
if (readRegister8(FT62XX_REG_VENDID) != FT62XX_VENDID) {
|
||||
return false;
|
||||
}
|
||||
_id = readRegister8(FT62XX_REG_CHIPID);
|
||||
if ((_id != FT6206_CHIPID) && (_id != FT6236_CHIPID) &&
|
||||
(_id != FT6236U_CHIPID) && (_id != FT5316_CHIPID)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Determines if there are any touches detected
|
||||
@returns Number of touches detected, can be 0, 1 or 2
|
||||
*/
|
||||
/**************************************************************************/
|
||||
uint8_t Adafruit_FT6206::touched(void) {
|
||||
if (_id == FT5316_CHIPID) {
|
||||
uint8_t val = readRegister8(FT62XX_REG_MODE);
|
||||
if (val) {
|
||||
// wrong mode
|
||||
val = 0;
|
||||
writeRegister8(FT62XX_REG_MODE, val);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t n = readRegister8(FT62XX_REG_NUMTOUCHES);
|
||||
if (n > 2) {
|
||||
n = 0;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Queries the chip and retrieves a point data
|
||||
@param n The # index (0 or 1) to the points we can detect. In theory we can
|
||||
detect 2 points but we've found that you should only use this for
|
||||
single-touch since the two points cant share the same half of the screen.
|
||||
@returns {@link FT_Point} object that has the x and y coordinets set. If the
|
||||
z coordinate is 0 it means the point is not touched. If z is 1, it is
|
||||
currently touched.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
FT_Point Adafruit_FT6206::getPoint(uint8_t n) {
|
||||
readData();
|
||||
if ((touches == 0) || (n > 1)) {
|
||||
return FT_Point(0, 0, 0);
|
||||
} else {
|
||||
return FT_Point(touchX[n], touchY[n], 1);
|
||||
}
|
||||
}
|
||||
|
||||
/************ lower level i/o **************/
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Reads the bulk of data from captouch chip. Fill in {@link touches},
|
||||
{@link touchX}, {@link touchY} and {@link touchID} with results
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void Adafruit_FT6206::readData(void) {
|
||||
|
||||
uint8_t i2cdat[16];
|
||||
Wire.beginTransmission(FT62XX_ADDR);
|
||||
Wire.write((byte)0);
|
||||
Wire.endTransmission();
|
||||
|
||||
Wire.requestFrom((byte)FT62XX_ADDR, (byte)16);
|
||||
for (uint8_t i = 0; i < 16; i++)
|
||||
i2cdat[i] = Wire.read();
|
||||
|
||||
#ifdef FT6206_DEBUG
|
||||
for (int16_t i = 0; i < 16; i++) {
|
||||
Serial.print("I2C $");
|
||||
Serial.print(i, HEX);
|
||||
Serial.print(" = 0x");
|
||||
Serial.println(i2cdat[i], HEX);
|
||||
}
|
||||
#endif
|
||||
|
||||
touches = i2cdat[0x02];
|
||||
if ((touches > 2) || (touches == 0)) {
|
||||
touches = 0;
|
||||
}
|
||||
|
||||
#ifdef FT6206_DEBUG
|
||||
Serial.print("# Touches: ");
|
||||
Serial.println(touches);
|
||||
|
||||
for (uint8_t i = 0; i < 16; i++) {
|
||||
Serial.print("0x");
|
||||
Serial.print(i2cdat[i], HEX);
|
||||
Serial.print(" ");
|
||||
}
|
||||
Serial.println();
|
||||
if (i2cdat[0x01] != 0x00) {
|
||||
Serial.print("Gesture #");
|
||||
Serial.println(i2cdat[0x01]);
|
||||
}
|
||||
#endif
|
||||
|
||||
for (uint8_t i = 0; i < 2; i++) {
|
||||
touchX[i] = i2cdat[0x03 + i * 6] & 0x0F;
|
||||
touchX[i] <<= 8;
|
||||
touchX[i] |= i2cdat[0x04 + i * 6];
|
||||
touchY[i] = i2cdat[0x05 + i * 6] & 0x0F;
|
||||
touchY[i] <<= 8;
|
||||
touchY[i] |= i2cdat[0x06 + i * 6];
|
||||
touchID[i] = i2cdat[0x05 + i * 6] >> 4;
|
||||
}
|
||||
|
||||
#ifdef FT6206_DEBUG
|
||||
Serial.println();
|
||||
for (uint8_t i = 0; i < touches; i++) {
|
||||
Serial.print("ID #");
|
||||
Serial.print(touchID[i]);
|
||||
Serial.print("\t(");
|
||||
Serial.print(touchX[i]);
|
||||
Serial.print(", ");
|
||||
Serial.print(touchY[i]);
|
||||
Serial.print(") ");
|
||||
}
|
||||
Serial.println();
|
||||
#endif
|
||||
}
|
||||
|
||||
uint8_t Adafruit_FT6206::readRegister8(uint8_t reg) {
|
||||
uint8_t x;
|
||||
// use i2c
|
||||
Wire.beginTransmission(FT62XX_ADDR);
|
||||
Wire.write((byte)reg);
|
||||
Wire.endTransmission();
|
||||
|
||||
Wire.requestFrom((byte)FT62XX_ADDR, (byte)1);
|
||||
x = Wire.read();
|
||||
|
||||
#ifdef I2C_DEBUG
|
||||
Serial.print("$");
|
||||
Serial.print(reg, HEX);
|
||||
Serial.print(": 0x");
|
||||
Serial.println(x, HEX);
|
||||
#endif
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
void Adafruit_FT6206::writeRegister8(uint8_t reg, uint8_t val) {
|
||||
// use i2c
|
||||
Wire.beginTransmission(FT62XX_ADDR);
|
||||
Wire.write((byte)reg);
|
||||
Wire.write((byte)val);
|
||||
Wire.endTransmission();
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
// DONT DO THIS - REALLY - IT DOESNT WORK
|
||||
void Adafruit_FT6206::autoCalibrate(void) {
|
||||
writeRegister8(FT06_REG_MODE, FT6206_REG_FACTORYMODE);
|
||||
delay(100);
|
||||
//Serial.println("Calibrating...");
|
||||
writeRegister8(FT6206_REG_CALIBRATE, 4);
|
||||
delay(300);
|
||||
for (uint8_t i = 0; i < 100; i++) {
|
||||
uint8_t temp;
|
||||
temp = readRegister8(FT6206_REG_MODE);
|
||||
Serial.println(temp, HEX);
|
||||
//return to normal mode, calibration finish
|
||||
if (0x0 == ((temp & 0x70) >> 4))
|
||||
break;
|
||||
}
|
||||
delay(200);
|
||||
//Serial.println("Calibrated");
|
||||
delay(300);
|
||||
writeRegister8(FT6206_REG_MODE, FT6206_REG_FACTORYMODE);
|
||||
delay(100);
|
||||
writeRegister8(FT6206_REG_CALIBRATE, 5);
|
||||
delay(300);
|
||||
writeRegister8(FT6206_REG_MODE, FT6206_REG_WORKMODE);
|
||||
delay(300);
|
||||
}
|
||||
*/
|
||||
|
||||
/****************/
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Instantiates a new FT6206 class with x, y and z set to 0 by default
|
||||
*/
|
||||
/**************************************************************************/
|
||||
FT_Point::FT_Point(void) { x = y = z = 0; }
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Instantiates a new FT6206 class with x, y and z set by params.
|
||||
@param _x The X coordinate
|
||||
@param _y The Y coordinate
|
||||
@param _z The Z coordinate
|
||||
*/
|
||||
/**************************************************************************/
|
||||
|
||||
FT_Point::FT_Point(int16_t _x, int16_t _y, int16_t _z) {
|
||||
x = _x;
|
||||
y = _y;
|
||||
z = _z;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Simple == comparator for two FT_Point objects
|
||||
@returns True if x, y and z are the same for both points, False otherwise.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
bool FT_Point::operator==(FT_Point p1) {
|
||||
return ((p1.x == x) && (p1.y == y) && (p1.z == z));
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Simple != comparator for two FT_Point objects
|
||||
@returns False if x, y and z are the same for both points, True otherwise.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
bool FT_Point::operator!=(FT_Point p1) {
|
||||
return ((p1.x != x) || (p1.y != y) || (p1.z != z));
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
/*!
|
||||
* @file Adafruit_FT6206.h
|
||||
*/
|
||||
|
||||
#ifndef ADAFRUIT_FT6206_LIBRARY
|
||||
#define ADAFRUIT_FT6206_LIBRARY
|
||||
|
||||
#include "Arduino.h"
|
||||
#include <Wire.h>
|
||||
|
||||
#define FT62XX_ADDR 0x38 //!< I2C address
|
||||
#define FT62XX_G_FT5201ID 0xA8 //!< FocalTech's panel ID
|
||||
#define FT62XX_REG_NUMTOUCHES 0x02 //!< Number of touch points
|
||||
|
||||
#define FT62XX_NUM_X 0x33 //!< Touch X position
|
||||
#define FT62XX_NUM_Y 0x34 //!< Touch Y position
|
||||
|
||||
#define FT62XX_REG_MODE 0x00 //!< Device mode, either WORKING or FACTORY
|
||||
#define FT62XX_REG_CALIBRATE 0x02 //!< Calibrate mode
|
||||
#define FT62XX_REG_WORKMODE 0x00 //!< Work mode
|
||||
#define FT62XX_REG_FACTORYMODE 0x40 //!< Factory mode
|
||||
#define FT62XX_REG_THRESHHOLD 0x80 //!< Threshold for touch detection
|
||||
#define FT62XX_REG_POINTRATE 0x88 //!< Point rate
|
||||
#define FT62XX_REG_FIRMVERS 0xA6 //!< Firmware version
|
||||
#define FT62XX_REG_CHIPID 0xA3 //!< Chip selecting
|
||||
#define FT62XX_REG_VENDID 0xA8 //!< FocalTech's panel ID
|
||||
|
||||
#define FT62XX_VENDID 0x11 //!< FocalTech's vendor ID
|
||||
#define FT6206_CHIPID 0x06 //!< Chip selecting
|
||||
#define FT6236_CHIPID 0x36 //!< Chip selecting
|
||||
#define FT6236U_CHIPID 0x64 //!< Chip selecting
|
||||
#define FT5316_CHIPID 0x0A //!< Chip selecting
|
||||
|
||||
// calibrated for Adafruit 2.8" ctp screen
|
||||
#define FT62XX_DEFAULT_THRESHOLD 128 //!< Default threshold for touch detection
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Helper class that stores a TouchScreen Point with x, y, and z
|
||||
coordinates, for easy math/comparison
|
||||
*/
|
||||
/**************************************************************************/
|
||||
class FT_Point {
|
||||
public:
|
||||
FT_Point(void);
|
||||
FT_Point(int16_t x, int16_t y, int16_t z);
|
||||
|
||||
bool operator==(FT_Point);
|
||||
bool operator!=(FT_Point);
|
||||
|
||||
int16_t x; /*!< X coordinate */
|
||||
int16_t y; /*!< Y coordinate */
|
||||
int16_t z; /*!< Z coordinate (often used for pressure) */
|
||||
};
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Class that stores state and functions for interacting with FT6206
|
||||
capacitive touch chips
|
||||
*/
|
||||
/**************************************************************************/
|
||||
class Adafruit_FT6206 {
|
||||
public:
|
||||
Adafruit_FT6206(void);
|
||||
boolean begin(uint8_t thresh = FT62XX_DEFAULT_THRESHOLD);
|
||||
uint8_t touched(void);
|
||||
FT_Point getPoint(uint8_t n = 0);
|
||||
|
||||
// void autoCalibrate(void);
|
||||
|
||||
private:
|
||||
void writeRegister8(uint8_t reg, uint8_t val);
|
||||
uint8_t readRegister8(uint8_t reg);
|
||||
|
||||
void readData(void);
|
||||
uint8_t touches;
|
||||
uint8_t _id = 0;
|
||||
uint16_t touchX[2], touchY[2], touchID[2];
|
||||
};
|
||||
|
||||
#endif // ADAFRUIT_FT6206_LIBRARY
|
||||
@@ -1,17 +0,0 @@
|
||||
# Adafruit_FT6206 Library [](https://github.com/adafruit/Adafruit_FT6206_Library/actions)[](http://adafruit.github.io/Adafruit_FT6206_Library/html/index.html)
|
||||
|
||||
<img src="https://cdn-shop.adafruit.com/970x728/1947-05.jpg" height="300"/>
|
||||
|
||||
This is a library for the Adafruit FT6206-Based capacitive touch screens and displays:
|
||||
* https://www.adafruit.com/products/1947
|
||||
* https://www.adafruit.com/product/1651
|
||||
|
||||
Also supports FT6236 chips (and maybe other compatible chips!)
|
||||
|
||||
Check out the links above for our tutorials and wiring diagrams. This chip uses I2C to communicate
|
||||
|
||||
Adafruit invests time and resources providing this open source code, please support Adafruit and open-source hardware by purchasing products from Adafruit!
|
||||
|
||||
Written by Limor Fried/Ladyada for Adafruit Industries.
|
||||
MIT license, all text above must be included in any redistribution
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
name=Adafruit FT6206 ESPEasy
|
||||
version=1.0.6
|
||||
author=Adafruit
|
||||
maintainer=Adafruit <info@adafruit.com>
|
||||
sentence=Arduino library for FT6206-based Capacitive touch screen adjusted for use in ESPEasy
|
||||
paragraph=Arduino library for FT6206-based Capacitive touch screen adjusted for use in ESPEasy
|
||||
category=Display
|
||||
url=https://github.com/adafruit/Adafruit_FT6206_Library
|
||||
architectures=*
|
||||
depends=Adafruit GFX Library
|
||||
@@ -0,0 +1,204 @@
|
||||
Copyright 2020 BitBank Software, Inc. All rights reserved.
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
BitBank Capacitive Touch Sensor Library<br>
|
||||
---------------------------------------
|
||||
Copyright (c) 2023 BitBank Software, Inc.<br>
|
||||
Written by Larry Bank<br>
|
||||
email: bitbank@pobox.com<br>
|
||||
<br>
|
||||
There are a growing list of development boards which include LCDs with capacitive touch plates on them. These are overwhelmingly controlled by different versions of the ESP32 MCU. The boards normally only utilize GOODiX and FocalTech capacitive touch controllers and this library supports the CST820, GT911 and FT6x36 in a generic way. Each has different capabilities and usually come pre-programmed for the specific pixel width and height of the target application. A feature supported by this library that may not be present in the device you're using is the touch area and pressure values. Some of their controllers also have built-in gesture detection. The common features of the controllers is that they will generate an interrupt signal when a touch event is occurring. This library allows you to request the latest touch information and it returns the number of active touch points (0-5) along with the coordinates (and pressure/area of each if available). The sensor type and address is auto-detected when calling the init() method. The only info that must be correctly supplied to the library are the GPIO pins used for the SDA/SCL/INT/RESET signals. Once initialized, repeatedly call getSamples() to test for and read any touch samples available.<br>
|
||||
|
||||
There are only 3 methods exposed by the class:<br>
|
||||
init() - detects if a supported CT controller is available and initializes it<br>
|
||||
getSamples() - returns touch points if available<br>
|
||||
sensorType() - returns an enumerated value of the sensor detected<>
|
||||
Here is the TOUCHINFO structure filled by the getSamples() method:<br>
|
||||
```
|
||||
typedef struct _fttouchinfo
|
||||
{
|
||||
int count;
|
||||
uint16_t x[5], y[5];
|
||||
uint8_t pressure[5], area[5];
|
||||
} TOUCHINFO;
|
||||
```
|
||||
|
||||
If you find this code useful, please consider becoming a sponsor or sending a donation.
|
||||
|
||||
[](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=SR4F44J2UR8S4)
|
||||
|
||||
|
||||
@@ -0,0 +1,138 @@
|
||||
#include <bb_captouch.h>
|
||||
//#include <OneBitDisplay.h>
|
||||
#include <bb_spi_lcd.h>
|
||||
#include <bb_scd41.h>
|
||||
#include <Wire.h>
|
||||
|
||||
//ONE_BIT_DISPLAY obd;
|
||||
SCD41 co2;
|
||||
|
||||
//#define CYD_128C
|
||||
//#define LILYGO_S3_PRO
|
||||
#define LILYGO_S3_LONG
|
||||
|
||||
#ifdef LILYGO_S3_LONG
|
||||
#define TOUCH_SDA 15
|
||||
#define TOUCH_SCL 10
|
||||
#define TOUCH_INT 11
|
||||
// reset is 16, but it's shared with the LCD
|
||||
#define TOUCH_RST -1
|
||||
#define LCD DISPLAY_T_DISPLAY_S3_LONG
|
||||
#endif
|
||||
|
||||
#ifdef LILYGO_S3_PRO
|
||||
#define TOUCH_SDA 5
|
||||
#define TOUCH_SCL 6
|
||||
#define TOUCH_INT 7
|
||||
#define TOUCH_RST 13
|
||||
#define LCD DISPLAY_T_DISPLAY_S3_PRO
|
||||
#endif
|
||||
|
||||
#ifdef CYD_28C
|
||||
// These defines are for a low cost 2.8" ESP32 LCD board with the GT911 touch controller
|
||||
#define TOUCH_SDA 33
|
||||
#define TOUCH_SCL 32
|
||||
#define TOUCH_INT 21
|
||||
#define TOUCH_RST 25
|
||||
#define LCD DISPLAY_CYD
|
||||
#endif
|
||||
|
||||
#ifdef CYD_128C
|
||||
// These defines are for a low cost 1.28" ESP32-C3 round LCD board with the CST816D touch controller
|
||||
#define TOUCH_SDA 4
|
||||
#define TOUCH_SCL 5
|
||||
#define TOUCH_INT 0
|
||||
#define TOUCH_RST 1
|
||||
#define QWIIC_SDA 21
|
||||
#define QWIIC_SCL 20
|
||||
#define LCD DISPLAY_CYD_128
|
||||
#endif
|
||||
|
||||
#ifdef ARDUINO_M5STACK_CORES3
|
||||
#define TOUCH_SDA 12
|
||||
#define TOUCH_SCL 11
|
||||
#define TOUCH_INT -1
|
||||
#define TOUCH_RST -1
|
||||
#define LCD DISPLAY_M5STACK_CORES3
|
||||
#endif // CORES3
|
||||
|
||||
BBCapTouch bbct;
|
||||
BB_SPI_LCD lcd;
|
||||
int iWidth, iHeight;
|
||||
|
||||
const char *szNames[] = {"Unknown", "FT6x36", "GT911", "CST820", "CST226", "AXS15231"};
|
||||
void setup() {
|
||||
|
||||
Serial.begin(115200);
|
||||
while (!Serial) {};
|
||||
lcd.begin(LCD);
|
||||
Serial.println("Starting...");
|
||||
// obd.setI2CPins(QWIIC_SDA, QWIIC_SCL);
|
||||
// obd.setBitBang(true);
|
||||
// obd.I2Cbegin(OLED_128x64);
|
||||
// obd.fillScreen(OBD_WHITE);
|
||||
// obd.setFont(FONT_12x16);
|
||||
// obd.println("QWIIC OLED");
|
||||
iWidth = lcd.width();
|
||||
iHeight = lcd.height();
|
||||
Serial.printf("LCD size = %dx%d\n", iWidth, iHeight);
|
||||
lcd.fillScreen(TFT_BLACK);
|
||||
lcd.setTextColor(TFT_GREEN, TFT_BLACK);
|
||||
lcd.setFont(FONT_8x8);
|
||||
lcd.setCursor(0, 0);
|
||||
lcd.println("CYD Touch Test");
|
||||
delay(1000);
|
||||
Wire.end();
|
||||
//Wire1.end();
|
||||
bbct.init(TOUCH_SDA, TOUCH_SCL, TOUCH_RST, TOUCH_INT);
|
||||
int iType = bbct.sensorType();
|
||||
Serial.printf("Sensor type = %s\n", szNames[iType]);
|
||||
#ifdef OLD_STUFF
|
||||
if (co2.init(QWIIC_SDA, QWIIC_SCL, 1, 100000) == SCD41_SUCCESS) {
|
||||
// Serial.println("Found SCD41 sensor!");
|
||||
co2.start(); // start sampling mode
|
||||
lcd.println("SCD41 found!");
|
||||
} else { // can't find the sensor, stop
|
||||
lcd.println("SCD41 sensor not found");
|
||||
lcd.println("Check your connections");
|
||||
lcd.println("\nstopping...");
|
||||
while (1) {};
|
||||
} // no sensor connected or some error
|
||||
#endif
|
||||
} /* setup() */
|
||||
|
||||
void loop() {
|
||||
#ifndef OLD_STUFF
|
||||
int i;
|
||||
TOUCHINFO ti;
|
||||
|
||||
while (1) {
|
||||
if (bbct.getSamples(&ti)) {
|
||||
for (int i=0; i<ti.count; i++){
|
||||
Serial.print("Touch ");Serial.print(i+1);Serial.print(": ");;
|
||||
Serial.print(" x: ");Serial.print(ti.x[i]);
|
||||
Serial.print(" y: ");Serial.print(ti.y[i]);
|
||||
Serial.print(" size: ");Serial.println(ti.area[i]);
|
||||
Serial.println(' ');
|
||||
lcd.fillCircle(iWidth-1-ti.y[i], ti.x[i], 3, (i == 0) ? TFT_BLUE : TFT_RED);
|
||||
} // for each touch point
|
||||
} // if touch event happened
|
||||
} // while (1)
|
||||
#else
|
||||
char szTemp[64];
|
||||
int i, iCO2;
|
||||
|
||||
delay(5000); // 5 seconds per reading
|
||||
// The SCD41 takes 5 seconds to return a sample in this mode
|
||||
co2.getSample();
|
||||
iCO2 = co2.co2();
|
||||
lcd.setCursor(0, 100);
|
||||
lcd.println(iCO2);
|
||||
sprintf(szTemp, "Temperature %dC ", co2.temperature());
|
||||
lcd.println(co2.temperature());
|
||||
lcd.println(szTemp);
|
||||
sprintf(szTemp, "Humidity %d%%", co2.humidity());
|
||||
lcd.println(co2.humidity());
|
||||
lcd.println(szTemp);
|
||||
#endif
|
||||
} /* loop() */
|
||||
@@ -0,0 +1,11 @@
|
||||
name=bb_captouch
|
||||
version=1.1.1
|
||||
author=Larry Bank
|
||||
maintainer=Larry Bank, Ton Huisman
|
||||
sentence=Capacitive touch sensor library for FT6x36 and GT911 I2C devices. Adjusted for ESPEasy use.
|
||||
paragraph=ESP32 specific code supports 1 to 5 point touch on the FT6x36 and GT911 sensors. It auto-detects the address and sensor type.
|
||||
category=Communication
|
||||
url=https://github.com/bitbank2/bb_captouch
|
||||
architectures=esp32,esp8266
|
||||
includes=bb_captouch.h
|
||||
depends=
|
||||
@@ -0,0 +1,454 @@
|
||||
//
|
||||
// BitBank Capactive Touch Sensor Library
|
||||
// Written by Larry Bank
|
||||
//
|
||||
// Copyright 2023 BitBank Software, Inc. All Rights Reserved.
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// ===========================================================================
|
||||
|
||||
#include "bb_captouch.h"
|
||||
|
||||
void BBCapTouch::reset(int iRST) {
|
||||
pinMode(iRST, OUTPUT);
|
||||
digitalWrite(iRST, LOW);
|
||||
delay(100);
|
||||
digitalWrite(iRST, HIGH);
|
||||
delay(100);
|
||||
} /* reset() */
|
||||
|
||||
//
|
||||
// Initialize the library
|
||||
// It only needs to initialize the I2C interface; the chip is ready // ESPEasy: I2C is already ready
|
||||
//
|
||||
int BBCapTouch::init(int iSDA, int iSCL, int iRST, int iINT, uint32_t u32Speed) {
|
||||
if (_iType != CT_TYPE_UNKNOWN) { return CT_SUCCESS; } // Already set, exit
|
||||
|
||||
// Wire.begin(iSDA, iSCL); // this is specific to ESP32 MCUs // ESPEasy doesn't allow this
|
||||
// Wire.setClock(u32Speed);
|
||||
#ifdef ESP32
|
||||
unsigned long orgTimeout = Wire.getTimeout();
|
||||
Wire.setTimeout(100);
|
||||
#endif // ifdef ESP32
|
||||
|
||||
_iType = CT_TYPE_UNKNOWN;
|
||||
|
||||
if (I2CTest(AXS15231_ADDR)) {
|
||||
_iType = CT_TYPE_AXS15231;
|
||||
_iAddr = AXS15231_ADDR;
|
||||
|
||||
if (iRST != -1) {
|
||||
reset(iRST);
|
||||
}
|
||||
} // AXS15231
|
||||
else if (I2CTest(CST226_ADDR)) { // CST226
|
||||
_iType = CT_TYPE_CST226;
|
||||
_iAddr = CST226_ADDR;
|
||||
|
||||
if (iINT != -1) {
|
||||
pinMode(iINT, INPUT);
|
||||
}
|
||||
|
||||
if (iRST != -1) {
|
||||
reset(iRST);
|
||||
}
|
||||
} // CST226
|
||||
|
||||
if (I2CTest(GT911_ADDR1) || I2CTest(GT911_ADDR2)) { // GT911
|
||||
_iType = CT_TYPE_GT911;
|
||||
}
|
||||
|
||||
if (_iType == CT_TYPE_GT911) { // reset the sensor to start it
|
||||
if ((-1 != iRST) && (-1 != iINT)) {
|
||||
pinMode(iRST, OUTPUT);
|
||||
pinMode(iINT, OUTPUT);
|
||||
digitalWrite(iINT, LOW);
|
||||
digitalWrite(iRST, LOW);
|
||||
delay(5);
|
||||
digitalWrite(iINT, LOW); // set I2C addr to ADDR1
|
||||
delay(1);
|
||||
digitalWrite(iRST, HIGH); // when it comes out of reset, it samples INT
|
||||
delay(10);
|
||||
digitalWrite(iINT, LOW);
|
||||
delay(50);
|
||||
pinMode(iINT, INPUT);
|
||||
}
|
||||
|
||||
// double check the I2C addr in case it changed
|
||||
if (I2CTest(GT911_ADDR1)) {
|
||||
_iAddr = GT911_ADDR1;
|
||||
} else if (I2CTest(GT911_ADDR2)) {
|
||||
_iAddr = GT911_ADDR2;
|
||||
}
|
||||
} // GT911
|
||||
else if (I2CTest(FT6X36_ADDR)) { // FT62x6
|
||||
// Check Vendor ID and get Chip ID
|
||||
uint8_t ucTemp[1]{};
|
||||
I2CReadRegister(FT6X36_ADDR, TOUCH_REG_VENDID, ucTemp, 1); // Check the Vendor ID reg
|
||||
|
||||
if (ucTemp[0] != FT62XX_VENDID) {
|
||||
return CT_ERROR;
|
||||
}
|
||||
I2CReadRegister(FT6X36_ADDR, TOUCH_REG_CHIPID, ucTemp, 1); // read the Chip ID reg
|
||||
_id = ucTemp[0]; // Chip ID only read to be used for FT5316
|
||||
|
||||
_iType = CT_TYPE_FT6X36;
|
||||
_iAddr = FT6X36_ADDR;
|
||||
|
||||
if (iRST != -1) {
|
||||
reset(iRST);
|
||||
}
|
||||
|
||||
if (_thresh > -1) {
|
||||
uint8_t ucsetThresh[2] = { 0x80, (uint8_t)_thresh }; // 0x80 = FT62XX_REG_THRESHOLD
|
||||
I2CWrite(_iAddr, (uint8_t *)ucsetThresh, 2);
|
||||
}
|
||||
} // FT62x6
|
||||
else if (I2CTest(CST820_ADDR)) { // CST820
|
||||
_iType = CT_TYPE_CST820;
|
||||
_iAddr = CST820_ADDR;
|
||||
|
||||
if (iRST != -1) {
|
||||
reset(iRST);
|
||||
}
|
||||
} // CST820
|
||||
else if (I2CTest(CHSC5816_ADDR)) { // CHSC5816
|
||||
_iType = CT_TYPE_CHSC5816;
|
||||
_iAddr = CHSC5816_ADDR;
|
||||
|
||||
if (iRST != -1) {
|
||||
reset(iRST);
|
||||
}
|
||||
} // CHSC5816
|
||||
#ifdef ESP32
|
||||
Wire.setTimeout(orgTimeout); // ESPEasy: Restore original I2C timeout
|
||||
#endif // ifdef ESP32
|
||||
|
||||
if (CT_TYPE_UNKNOWN == _iType) {
|
||||
return CT_ERROR; // no device found
|
||||
}
|
||||
return CT_SUCCESS;
|
||||
} /* init() */
|
||||
|
||||
//
|
||||
// Test if an I2C device is monitoring an address
|
||||
// return true if it responds, false if no response
|
||||
//
|
||||
bool BBCapTouch::I2CTest(uint8_t u8Addr) {
|
||||
// Check if a device acknowledges the address.
|
||||
Wire.beginTransmission(u8Addr);
|
||||
return Wire.endTransmission(true) == 0;
|
||||
} /* I2CTest() */
|
||||
|
||||
//
|
||||
// Write I2C data
|
||||
// quits if a NACK is received and returns 0
|
||||
// otherwise returns the number of bytes written
|
||||
//
|
||||
int BBCapTouch::I2CWrite(uint8_t u8Addr, uint8_t *pData, int iLen) {
|
||||
int rc = 0;
|
||||
|
||||
Wire.beginTransmission(u8Addr);
|
||||
Wire.write(pData, (uint8_t)iLen);
|
||||
rc = !Wire.endTransmission();
|
||||
return rc;
|
||||
} /* I2CWrite() */
|
||||
|
||||
//
|
||||
// Read N bytes starting at a specific 16-bit I2C register
|
||||
//
|
||||
int BBCapTouch::I2CReadRegister16(uint8_t u8Addr, uint16_t u16Register, uint8_t *pData, int iLen) {
|
||||
int i = 0;
|
||||
|
||||
Wire.beginTransmission(u8Addr);
|
||||
Wire.write((uint8_t)(u16Register >> 8)); // high byte
|
||||
Wire.write((uint8_t)u16Register); // low byte
|
||||
Wire.endTransmission();
|
||||
Wire.requestFrom(u8Addr, (uint8_t)iLen);
|
||||
|
||||
while (Wire.available() && i < iLen) {
|
||||
pData[i++] = Wire.read();
|
||||
}
|
||||
return i;
|
||||
} /* I2CReadRegister16() */
|
||||
|
||||
//
|
||||
// Read N bytes starting at a specific I2C internal register
|
||||
// returns 1 for success, 0 for error
|
||||
//
|
||||
int BBCapTouch::I2CReadRegister(uint8_t u8Addr, uint8_t u8Register, uint8_t *pData, int iLen) {
|
||||
int i = 0;
|
||||
|
||||
Wire.beginTransmission(u8Addr);
|
||||
Wire.write(u8Register);
|
||||
Wire.endTransmission();
|
||||
Wire.requestFrom(u8Addr, (uint8_t)iLen);
|
||||
|
||||
// i = Wire.readBytes(pData, iLen);
|
||||
while (Wire.available() && i < iLen) {
|
||||
pData[i++] = Wire.read();
|
||||
}
|
||||
return i;
|
||||
} /* I2CReadRegister() */
|
||||
|
||||
//
|
||||
// Read N bytes
|
||||
//
|
||||
int BBCapTouch::I2CRead(uint8_t u8Addr, uint8_t *pData, int iLen) {
|
||||
int i = 0;
|
||||
|
||||
Wire.requestFrom(u8Addr, (uint8_t)iLen);
|
||||
|
||||
while (Wire.available() && i < iLen) {
|
||||
pData[i++] = Wire.read();
|
||||
}
|
||||
return i;
|
||||
} /* I2CRead() */
|
||||
|
||||
//
|
||||
// Private function to rotate touch samples if the user
|
||||
// specified a new display orientation
|
||||
//
|
||||
void BBCapTouch::fixSamples(TOUCHINFO *pTI) {
|
||||
int i, x, y;
|
||||
|
||||
for (i = 0; i < pTI->count; ++i) {
|
||||
switch (_iOrientation) {
|
||||
case 90:
|
||||
x = pTI->y[i];
|
||||
y = _iWidth - 1 - pTI->x[i];
|
||||
pTI->x[i] = x;
|
||||
pTI->y[i] = y;
|
||||
break;
|
||||
case 180:
|
||||
pTI->x[i] = _iWidth - 1 - pTI->x[i];
|
||||
pTI->y[i] = _iHeight - 1 - pTI->y[i];
|
||||
break;
|
||||
case 270:
|
||||
x = _iHeight - 1 - pTI->y[i];
|
||||
y = pTI->x[i];
|
||||
pTI->x[i] = x;
|
||||
pTI->y[i] = y;
|
||||
break;
|
||||
default: // do nothing
|
||||
break;
|
||||
}
|
||||
}
|
||||
} /* fixSamples() */
|
||||
|
||||
//
|
||||
// Read the touch points
|
||||
// returns 0 (none), 1 if touch points are available
|
||||
// The point count and info is returned in the TOUCHINFO structure
|
||||
//
|
||||
int BBCapTouch::getSamples(TOUCHINFO *pTI) {
|
||||
uint8_t c, *s, ucTemp[32];
|
||||
int i, j, rc;
|
||||
|
||||
if (!pTI) {
|
||||
return 0;
|
||||
}
|
||||
pTI->count = 0;
|
||||
|
||||
if (_iType == CT_TYPE_AXS15231) { // AXS15231
|
||||
uint8_t ucReadCMD[8] = { 0xb5, 0xab, 0xa5, 0x5a, 0, 0, 0, 0x8 };
|
||||
I2CWrite(_iAddr, (uint8_t *)ucReadCMD, 8);
|
||||
I2CRead(_iAddr, ucTemp, 14); // read up to 2 touch points
|
||||
c = ucTemp[1]; // number of touch points
|
||||
|
||||
if ((c == 0) || (c > 2) || (ucTemp[0] != 0)) { return 0; }
|
||||
pTI->count = c;
|
||||
j = 0; // buffer offset
|
||||
|
||||
for (i = 0; i < c; i++) {
|
||||
pTI->x[i] = ((ucTemp[j + 2] & 0xf) << 8) + ucTemp[j + 3];
|
||||
pTI->y[i] = ((ucTemp[j + 4] & 0xf) << 8) + ucTemp[j + 5];
|
||||
pTI->area[i] = 1;
|
||||
j += 6;
|
||||
}
|
||||
|
||||
if (_iOrientation != 0) { fixSamples(pTI); }
|
||||
return c > 0;
|
||||
} // AXS15231
|
||||
|
||||
if (_iType == CT_TYPE_CST226) { // CST226
|
||||
i = I2CReadRegister(_iAddr, 0, ucTemp, 28); // read the whole block of regs
|
||||
|
||||
if ((ucTemp[0] == 0x83) && (ucTemp[1] == 0x17) && (ucTemp[5] == 0x80)) {
|
||||
// home button pressed
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ucTemp[6] != 0xab) { return 0; }
|
||||
|
||||
if (ucTemp[0] == 0xab) { return 0; }
|
||||
|
||||
if (ucTemp[5] == 0x80) { return 0; }
|
||||
c = ucTemp[5] & 0x7f;
|
||||
|
||||
if ((c > 5) || (c == 0)) { // invalid point count
|
||||
ucTemp[0] = 0;
|
||||
ucTemp[1] = 0xab;
|
||||
I2CWrite(_iAddr, ucTemp, 2); // reset
|
||||
return 0;
|
||||
}
|
||||
|
||||
pTI->count = c;
|
||||
j = 0;
|
||||
|
||||
for (i = 0; i < c; i++) {
|
||||
pTI->x[i] = (uint16_t)((ucTemp[j + 1] << 4) | ((ucTemp[j + 3] >> 4) & 0xf));
|
||||
pTI->y[i] = (uint16_t)((ucTemp[j + 2] << 4) | (ucTemp[j + 3] & 0xf));
|
||||
pTI->pressure[i] = ucTemp[j + 4];
|
||||
j = (i == 0) ? (j + 7) : (j + 5);
|
||||
}
|
||||
|
||||
if (_iOrientation != 0) { fixSamples(pTI); }
|
||||
return c > 0;
|
||||
} // CST226
|
||||
|
||||
if (_iType == CT_TYPE_CST820) { // CST820
|
||||
I2CReadRegister(_iAddr, CST820_TOUCH_REGS + 1, ucTemp, 1); // read touch count
|
||||
|
||||
if ((ucTemp[0] < 1) || (ucTemp[0] > 5)) { // something went wrong
|
||||
return 0;
|
||||
}
|
||||
|
||||
pTI->count = ucTemp[0];
|
||||
I2CReadRegister(_iAddr, CST820_TOUCH_REGS + 2, ucTemp, pTI->count * 6);
|
||||
s = ucTemp;
|
||||
|
||||
for (i = 0; i < pTI->count; i++) {
|
||||
pTI->x[i] = ((s[0] & 0xf) << 8) | s[1];
|
||||
pTI->y[i] = ((s[2] & 0xf) << 8) | s[3];
|
||||
pTI->area[i] = 1; // no data available
|
||||
s += 6;
|
||||
}
|
||||
|
||||
if (_iOrientation != 0) { fixSamples(pTI); }
|
||||
return 1;
|
||||
} // CST820
|
||||
|
||||
if (_iType == CT_TYPE_FT6X36) { // FT62x6
|
||||
if (_id == FT5316_CHIPID) {
|
||||
I2CReadRegister(_iAddr, TOUCH_REG_MODE, ucTemp, 1); // Handle specific issue
|
||||
|
||||
if (ucTemp[0]) {
|
||||
// wrong mode
|
||||
ucTemp[0] = TOUCH_REG_MODE;
|
||||
ucTemp[1] = 0;
|
||||
I2CWrite(_iAddr, ucTemp, 2);
|
||||
}
|
||||
}
|
||||
rc = I2CReadRegister(_iAddr, TOUCH_REG_STATUS, ucTemp, 1); // read touch status
|
||||
|
||||
if (rc == 0) { // something went wrong
|
||||
return 0;
|
||||
}
|
||||
i = ucTemp[0]; // number of touch points available
|
||||
|
||||
if (i > 0) { // get data, max. 2 points
|
||||
rc = I2CReadRegister(_iAddr, TOUCH_REG_XH, ucTemp, 6 * i); // read X+Y position(s)
|
||||
|
||||
if (((ucTemp[0] & 0x40) == 0) && ((ucTemp[2] & 0xf0) != 0xf0)) { // finger is down
|
||||
pTI->x[0] = ((ucTemp[0] & 0xf) << 8) | ucTemp[1];
|
||||
pTI->y[0] = ((ucTemp[2] & 0xf) << 8) | ucTemp[3];
|
||||
|
||||
// get touch pressure and area
|
||||
pTI->pressure[0] = ucTemp[4];
|
||||
pTI->area[0] = ucTemp[5];
|
||||
pTI->count++;
|
||||
}
|
||||
|
||||
if (i > 1) { // get second point
|
||||
if (((ucTemp[6] & 0x40) == 0) && ((ucTemp[8] & 0xf0) != 0xf0)) { // finger is down
|
||||
pTI->x[1] = ((ucTemp[6] & 0xf) << 8) | ucTemp[7];
|
||||
pTI->y[1] = ((ucTemp[8] & 0xf) << 8) | ucTemp[9];
|
||||
|
||||
// get touch pressure and area
|
||||
pTI->pressure[1] = ucTemp[10];
|
||||
pTI->area[1] = ucTemp[11];
|
||||
pTI->count++;
|
||||
}
|
||||
}
|
||||
} // if touch points available
|
||||
|
||||
if (_iOrientation != 0) { fixSamples(pTI); }
|
||||
return i > 0;
|
||||
} // FT62x6
|
||||
else if (_iType == CT_TYPE_GT911) { // GT911
|
||||
I2CReadRegister16(_iAddr, GT911_POINT_INFO, ucTemp, 1); // get number of touch points
|
||||
i = ucTemp[0] & 0xf; // number of touches
|
||||
|
||||
if ((i <= 5) && ucTemp[0] & 0x80) { // if buffer status is good + >= 1 touch points
|
||||
ucTemp[0] = (uint8_t)(GT911_POINT_INFO >> 8);
|
||||
ucTemp[1] = (uint8_t)GT911_POINT_INFO;
|
||||
ucTemp[2] = 0; // clear touch info for next time
|
||||
I2CWrite(_iAddr, ucTemp, 3);
|
||||
|
||||
pTI->count = i;
|
||||
|
||||
for (int j = 0; j < i; j++) { // read each touch point block
|
||||
I2CReadRegister16(_iAddr, GT911_POINT_1 + (j * 8), ucTemp, 7);
|
||||
pTI->x[j] = ucTemp[1] + (ucTemp[2] << 8);
|
||||
pTI->y[j] = ucTemp[3] + (ucTemp[4] << 8);
|
||||
pTI->area[j] = ucTemp[5] + (ucTemp[6] << 8);
|
||||
pTI->pressure[j] = 0;
|
||||
}
|
||||
|
||||
if (i && (_iOrientation != 0)) { fixSamples(pTI); }
|
||||
return i > 0;
|
||||
}
|
||||
} // GT911
|
||||
else if (_iType == CT_TYPE_CHSC5816) { // CHSC5816
|
||||
__CHSC5816_PointReg touch;
|
||||
|
||||
// CHSC5816_REG_POINT
|
||||
uint8_t write_buffer[] = { 0x20, 0x00, 0x00, 0x2c };
|
||||
I2CWrite(_iAddr, write_buffer, 4);
|
||||
I2CRead(_iAddr, touch.data, 8);
|
||||
|
||||
if ((touch.rp.status == 0xFF) && (touch.rp.fingerNumber == 0)) {
|
||||
return 0;
|
||||
}
|
||||
pTI->x[0] = static_cast<uint16_t>(touch.rp.x_h4 << 8) | touch.rp.x_l8;
|
||||
pTI->y[0] = static_cast<uint16_t>(touch.rp.y_h4 << 8) | touch.rp.y_l8;
|
||||
|
||||
if (_iOrientation != 0) { fixSamples(pTI); }
|
||||
|
||||
return 1;
|
||||
} // CHSC5816
|
||||
return 0;
|
||||
} /* getSamples() */
|
||||
|
||||
int BBCapTouch::setOrientation(int iOrientation, int iWidth, int iHeight) {
|
||||
if ((iOrientation != 0) && (iOrientation != 90) && (iOrientation != 180) && (iOrientation != 270)) {
|
||||
return CT_ERROR;
|
||||
}
|
||||
_iOrientation = iOrientation;
|
||||
_iWidth = iWidth;
|
||||
_iHeight = iHeight;
|
||||
return CT_SUCCESS;
|
||||
} /* setOrientation() */
|
||||
|
||||
void BBCapTouch::sensorType(int iType) {
|
||||
_iType = iType;
|
||||
}
|
||||
|
||||
void BBCapTouch::setI2CAddress(int i2caddr) {
|
||||
_iAddr = i2caddr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Threashold is used _during_ init() so should be set before init() is called.
|
||||
*/
|
||||
void BBCapTouch::setThreshold(int thresh) {
|
||||
_thresh = thresh;
|
||||
}
|
||||
@@ -0,0 +1,187 @@
|
||||
//
|
||||
// BitBank Capacitive Touch Sensor Library
|
||||
// written by Larry Bank
|
||||
//
|
||||
// Copyright 2023 BitBank Software, Inc. All Rights Reserved.
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// ===========================================================================
|
||||
|
||||
//
|
||||
// Written for the many variants of ESP32 + Capacitive touch LCDs on the market
|
||||
//
|
||||
// 2024-06-10 tonhuisman: Add support for CHSC5816 touchscreen, code borrowed from Lewis He SensorLib at
|
||||
// https://github.com/lewisxhe/SensorLib
|
||||
// 2024-06-02 tonhuisman: Fix FT62x6 to not return true when no data is read
|
||||
// Formatted source using Uncrustify
|
||||
// Adjust I2C handling so ESPEasy stays happy, ignoring SDA/SCL pins and I2C enable/disable
|
||||
// ===========================================================================
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <Wire.h>
|
||||
|
||||
#ifndef __BB_CAPTOUCH__
|
||||
# define __BB_CAPTOUCH__
|
||||
|
||||
# define CT_SUCCESS 0
|
||||
# define CT_ERROR -1
|
||||
|
||||
enum {
|
||||
CT_TYPE_UNKNOWN = 0,
|
||||
CT_TYPE_FT6X36,
|
||||
CT_TYPE_GT911,
|
||||
CT_TYPE_CST820,
|
||||
CT_TYPE_CST226,
|
||||
CT_TYPE_AXS15231,
|
||||
CT_TYPE_CHSC5816,
|
||||
CT_TYPE_COUNT
|
||||
};
|
||||
|
||||
# define GT911_ADDR1 0x5D
|
||||
# define GT911_ADDR2 0x14
|
||||
# define FT6X36_ADDR 0x38
|
||||
# define CST820_ADDR 0x15
|
||||
# define CST226_ADDR 0x5A
|
||||
# define AXS15231_ADDR 0x3B
|
||||
# define CHSC5816_ADDR 0x2E
|
||||
|
||||
// CST8xx gestures
|
||||
enum {
|
||||
GESTURE_NONE = 0,
|
||||
GESTURE_SWIPE_UP,
|
||||
GESTURE_SWIPE_DOWN,
|
||||
GESTURE_SWIPE_LEFT,
|
||||
GESTURE_SWIPE_RIGHT,
|
||||
GESTURE_SINGLE_CLICK,
|
||||
GESTURE_DOUBLE_CLICK = 0x0B,
|
||||
GESTURE_LONG_PRESS = 0x0C
|
||||
};
|
||||
|
||||
// CST820 registers
|
||||
# define CST820_TOUCH_REGS 1
|
||||
|
||||
// GT911 registers
|
||||
# define GT911_POINT_INFO 0x814E
|
||||
# define GT911_POINT_1 0x814F
|
||||
# define GT911_CONFIG_FRESH 0x8100
|
||||
# define GT911_CONFIG_SIZE 0xb9
|
||||
# define GT911_CONFIG_START 0x8047
|
||||
|
||||
// FT6x36 registers
|
||||
# define TOUCH_REG_MODE 0x00
|
||||
# define TOUCH_REG_STATUS 0x02
|
||||
# define TOUCH_REG_XH 0x03
|
||||
# define TOUCH_REG_XL 0x04
|
||||
# define TOUCH_REG_YH 0x05
|
||||
# define TOUCH_REG_YL 0x06
|
||||
# define TOUCH_REG_WEIGHT 0x07
|
||||
# define TOUCH_REG_AREA 0x08
|
||||
# define TOUCH_REG_CHIPID 0xA3 // !< Chip selecting
|
||||
# define TOUCH_REG_VENDID 0xA8 // !< FocalTech's panel ID
|
||||
|
||||
// FT62x6 Vendor and Chip IDs
|
||||
# define FT62XX_VENDID 0x11 // !< FocalTech's vendor ID
|
||||
# define FT6206_CHIPID 0x06 // !< Chip selecting
|
||||
# define FT6236_CHIPID 0x36 // !< Chip selecting
|
||||
# define FT6236U_CHIPID 0x64 // !< Chip selecting
|
||||
# define FT5316_CHIPID 0x0A // !< Chip selecting
|
||||
|
||||
// register offset to info for the second touch point
|
||||
# define PT2_OFFSET 6
|
||||
|
||||
union __CHSC5816_PointReg {
|
||||
struct {
|
||||
uint8_t status;
|
||||
uint8_t fingerNumber;
|
||||
uint8_t x_l8;
|
||||
uint8_t y_l8;
|
||||
uint8_t z;
|
||||
uint8_t x_h4 : 4;
|
||||
uint8_t y_h4 : 4;
|
||||
uint8_t id : 4;
|
||||
uint8_t event : 4;
|
||||
uint8_t p2;
|
||||
} rp;
|
||||
unsigned char data[8];
|
||||
};
|
||||
|
||||
# ifndef __TOUCHINFO_STRUCT__
|
||||
# define __TOUCHINFO_STRUCT__
|
||||
typedef struct _fttouchinfo {
|
||||
int count;
|
||||
uint16_t x[5], y[5];
|
||||
uint8_t pressure[5], area[5];
|
||||
} TOUCHINFO;
|
||||
# endif // ifndef __TOUCHINFO_STRUCT__
|
||||
|
||||
class BBCapTouch {
|
||||
public:
|
||||
|
||||
BBCapTouch() {
|
||||
_iOrientation = 0;
|
||||
}
|
||||
|
||||
~BBCapTouch() { /*Wire.end();*/
|
||||
} // ESPEasy doesn't allow this
|
||||
|
||||
int init(int iSDA,
|
||||
int iSCL,
|
||||
int iRST = -1,
|
||||
int iINT = -1,
|
||||
uint32_t u32Speed = 400000);
|
||||
int getSamples(TOUCHINFO *pTI);
|
||||
void sensorType(int iType);
|
||||
int sensorType(void) const {
|
||||
return _iType;
|
||||
}
|
||||
|
||||
void setI2CAddress(int i2caddr);
|
||||
int getI2CAddress(void) const {
|
||||
return _iAddr;
|
||||
}
|
||||
|
||||
int setOrientation(int iOrientation,
|
||||
int iWidth,
|
||||
int iHeight);
|
||||
void setThreshold(int tresh);
|
||||
uint8_t getChipId(void) const {
|
||||
return _id; // Only set for FT62x6 family
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
void reset(int iResetPin);
|
||||
|
||||
private:
|
||||
|
||||
int _iAddr;
|
||||
int _iType = CT_TYPE_UNKNOWN;
|
||||
int _iOrientation, _iWidth{}, _iHeight{};
|
||||
int _thresh = -1;
|
||||
uint8_t _id = 0;
|
||||
|
||||
void fixSamples(TOUCHINFO *pTI);
|
||||
bool I2CTest(uint8_t u8Addr);
|
||||
int I2CRead(uint8_t u8Addr,
|
||||
uint8_t *pData,
|
||||
int iLen);
|
||||
int I2CReadRegister(uint8_t u8Addr,
|
||||
uint8_t u8Register,
|
||||
uint8_t *pData,
|
||||
int iLen);
|
||||
int I2CReadRegister16(uint8_t u8Addr,
|
||||
uint16_t u16Register,
|
||||
uint8_t *pData,
|
||||
int iLen);
|
||||
int I2CWrite(uint8_t u8Addr,
|
||||
uint8_t *pData,
|
||||
int iLen);
|
||||
}; // class BBCapTouch
|
||||
#endif // __BB_CAPTOUCH__
|
||||
+1
-1
@@ -492,7 +492,7 @@ static const char DATA_ESPEASY_DEFAULT_MIN_CSS[] PROGMEM = {
|
||||
// #define USES_P120 // ADXL345 I2C Acceleration / Gravity
|
||||
// #define USES_P121 // HMC5883L
|
||||
// #define USES_P122 // SHT2x
|
||||
// #define USES_P123 // FT6206
|
||||
// #define USES_P123 // I2C Touchscreens
|
||||
// #define USES_P124 // I2C Multi Relay
|
||||
// #define USES_P125 // ADXL345 SPI Acceleration / Gravity
|
||||
// #define USES_P126 // 74HC595 Shift register
|
||||
|
||||
@@ -2,11 +2,19 @@
|
||||
#ifdef USES_P123
|
||||
|
||||
// #######################################################################################################
|
||||
// #################################### Plugin 123: FT62x6 Touchscreen ###################################
|
||||
// ###################################### Plugin 123: I2C Touchscreens ###################################
|
||||
// #######################################################################################################
|
||||
|
||||
/**
|
||||
* Changelog:
|
||||
* 2024-06-10 tonhuisman: Add support for CHSC5816, as found in https://github.com/lewisxhe/SensorLib by Lewis He (added to bb_captouch)
|
||||
* 2024-06-02 tonhuisman: Renamed to I2C Touchscreens
|
||||
* Refactor to use modified bb_captouch library https://github.com/bitbank2/bb_captouch to add support for
|
||||
* FT62x6 and GT911 (tested), CST820, CST226 and AXS15231 (untested)
|
||||
* The library supports auto-configure, but that only checks if an I2C device is available at certain addresses
|
||||
* so that's not really reliable. Added methods to override the used touchscreen with the known device
|
||||
* Only single-point support for now.
|
||||
* For the auto-configure option the I2C device check is disabled for this plugin.
|
||||
* 2024-03-21 tonhuisman: Refactor increment/decrement to next/prevButtonGroup/Page functions, to align with ESPEasy_TouchHandler
|
||||
* 2023-12-31 tonhuisman: Code optimizations
|
||||
* 2023-10-01 tonhuisman: Re-implement (fix) switching of X/Y/Z vs X/Y output values using PLUGIN_GET_DEVICEVALUECOUNT, store (also) in task
|
||||
@@ -47,7 +55,7 @@
|
||||
|
||||
# define PLUGIN_123
|
||||
# define PLUGIN_ID_123 123
|
||||
# define PLUGIN_NAME_123 "Touch - FT62x6 touchscreen"
|
||||
# define PLUGIN_NAME_123 "Touch - I2C Touchscreens"
|
||||
# define PLUGIN_VALUENAME1_123 "X"
|
||||
# define PLUGIN_VALUENAME2_123 "Y"
|
||||
# define PLUGIN_VALUENAME3_123 "Z"
|
||||
@@ -74,6 +82,7 @@ boolean Plugin_123(uint8_t function, struct EventStruct *event, String& string)
|
||||
Device[deviceCount].SendDataOption = false;
|
||||
Device[deviceCount].TimerOption = false;
|
||||
Device[deviceCount].ExitTaskBeforeSave = false;
|
||||
Device[deviceCount].I2CNoDeviceCheck = true;
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
@@ -96,7 +105,7 @@ boolean Plugin_123(uint8_t function, struct EventStruct *event, String& string)
|
||||
|
||||
case PLUGIN_I2C_HAS_ADDRESS:
|
||||
{
|
||||
success = (event->Par1 == P123_I2C_ADDRESS); // Fixed I2C address
|
||||
success = P123_data_struct::plugin_i2c_has_address(event->Par1);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -107,6 +116,10 @@ boolean Plugin_123(uint8_t function, struct EventStruct *event, String& string)
|
||||
P123_CONFIG_ROTATION = P123_TS_ROTATION;
|
||||
P123_CONFIG_X_RES = P123_TS_X_RES;
|
||||
P123_CONFIG_Y_RES = P123_TS_Y_RES;
|
||||
P123_I2C_ADDRESS = 0x38; // Former default was FT62x6
|
||||
P123_SET_TOUCH_TYPE(static_cast<int>(P123_TouchType_e::FT62x6));
|
||||
P123_INTERRUPTPIN = -1; // No interrupt
|
||||
P123_RESETPIN = -1; // No reset
|
||||
|
||||
success = true;
|
||||
break;
|
||||
@@ -167,13 +180,49 @@ boolean Plugin_123(uint8_t function, struct EventStruct *event, String& string)
|
||||
AdaGFXFormColorDepth(F("colordepth"), P123_COLOR_DEPTH, (colorDepth_ == 0));
|
||||
|
||||
addFormNumericBox(F("Touch minimum pressure"), F("threshold"), P123_CONFIG_THRESHOLD, 0, 255);
|
||||
addUnit(F("Only used for FT62x6"));
|
||||
|
||||
{
|
||||
P123_data_struct *P123_data = static_cast<P123_data_struct *>(getPluginTaskData(event->TaskIndex));
|
||||
bool deleteP123_data = false;
|
||||
{
|
||||
const __FlashStringHelper *touchTypes[] = {
|
||||
toString(P123_TouchType_e::FT62x6),
|
||||
toString(P123_TouchType_e::GT911_1),
|
||||
toString(P123_TouchType_e::GT911_2),
|
||||
toString(P123_TouchType_e::CST820),
|
||||
toString(P123_TouchType_e::CST226),
|
||||
toString(P123_TouchType_e::AXS15231),
|
||||
toString(P123_TouchType_e::CHSC5816),
|
||||
toString(P123_TouchType_e::Automatic),
|
||||
};
|
||||
const int touchTypeOptions[] = {
|
||||
static_cast<int>(P123_TouchType_e::FT62x6),
|
||||
static_cast<int>(P123_TouchType_e::GT911_1),
|
||||
static_cast<int>(P123_TouchType_e::GT911_2),
|
||||
static_cast<int>(P123_TouchType_e::CST820),
|
||||
static_cast<int>(P123_TouchType_e::CST226),
|
||||
static_cast<int>(P123_TouchType_e::AXS15231),
|
||||
static_cast<int>(P123_TouchType_e::CHSC5816),
|
||||
static_cast<int>(P123_TouchType_e::Automatic),
|
||||
};
|
||||
addFormSelector(F("Touchscreen type (address)"),
|
||||
F("ttype"),
|
||||
NR_ELEMENTS(touchTypeOptions),
|
||||
touchTypes,
|
||||
touchTypeOptions,
|
||||
P123_GET_TOUCH_TYPE);
|
||||
|
||||
if (nullptr != P123_data) {
|
||||
addUnit(concat(F("Detected: "), toString(P123_data->getTouchType())));
|
||||
}
|
||||
}
|
||||
addFormPinSelect(PinSelectPurpose::Generic_bidir, F("Interrupt pin"), F("taskdevicepin1"), P123_INTERRUPTPIN);
|
||||
addFormPinSelect(PinSelectPurpose::Generic_bidir, F("Reset pin"), F("taskdevicepin2"), P123_RESETPIN);
|
||||
addFormNote(F("Interrupt and Reset pins are optional. Interrupt is only used by GT911."));
|
||||
|
||||
if (nullptr == P123_data) {
|
||||
P123_data = new (std::nothrow) P123_data_struct();
|
||||
P123_data = new (std::nothrow) P123_data_struct(static_cast<P123_TouchType_e>(P123_GET_TOUCH_TYPE));
|
||||
deleteP123_data = true;
|
||||
}
|
||||
|
||||
@@ -200,6 +249,10 @@ boolean Plugin_123(uint8_t function, struct EventStruct *event, String& string)
|
||||
P123_CONFIG_ROTATION = getFormItemInt(F("rotate"));
|
||||
P123_CONFIG_X_RES = getFormItemInt(F("xres"));
|
||||
P123_CONFIG_Y_RES = getFormItemInt(F("yres"));
|
||||
P123_SET_TOUCH_TYPE(getFormItemInt(F("ttype")));
|
||||
P123_I2C_ADDRESS = P123_data_struct::plugin_i2c_address(static_cast<P123_TouchType_e>(P123_GET_TOUCH_TYPE));
|
||||
|
||||
// taskdevicepin1/taskdevicepin2 are saved automatically
|
||||
|
||||
const int colorDepth = getFormItemInt(F("colordepth"), -1);
|
||||
|
||||
@@ -212,7 +265,7 @@ boolean Plugin_123(uint8_t function, struct EventStruct *event, String& string)
|
||||
bool deleteP123_data = false;
|
||||
|
||||
if (nullptr == P123_data) {
|
||||
P123_data = new (std::nothrow) P123_data_struct();
|
||||
P123_data = new (std::nothrow) P123_data_struct(static_cast<P123_TouchType_e>(P123_GET_TOUCH_TYPE));
|
||||
deleteP123_data = true;
|
||||
}
|
||||
|
||||
@@ -233,7 +286,12 @@ boolean Plugin_123(uint8_t function, struct EventStruct *event, String& string)
|
||||
# ifdef PLUGIN_123_DEBUG
|
||||
addLogMove(LOG_LEVEL_INFO, F("P123 PLUGIN_INIT"));
|
||||
# endif // ifdef PLUGIN_123_DEBUG
|
||||
initPluginTaskData(event->TaskIndex, new (std::nothrow) P123_data_struct());
|
||||
|
||||
if (0 == P123_I2C_ADDRESS) {
|
||||
P123_I2C_ADDRESS = 0x38; // Former default was FT62x6
|
||||
P123_SET_TOUCH_TYPE(static_cast<int>(P123_TouchType_e::FT62x6));
|
||||
}
|
||||
initPluginTaskData(event->TaskIndex, new (std::nothrow) P123_data_struct(static_cast<P123_TouchType_e>(P123_GET_TOUCH_TYPE)));
|
||||
P123_data_struct *P123_data = static_cast<P123_data_struct *>(getPluginTaskData(event->TaskIndex));
|
||||
|
||||
if (nullptr == P123_data) {
|
||||
+42
-11
@@ -6,25 +6,56 @@
|
||||
#include "../Globals/I2Cdev.h"
|
||||
#include "../Globals/Settings.h"
|
||||
|
||||
#include "../Helpers/Hardware_I2C.h"
|
||||
#include "../Helpers/StringConverter.h"
|
||||
|
||||
#include "../../ESPEasy_common.h"
|
||||
|
||||
void i2c_scanI2Cbus(bool dbg, int8_t channel) {
|
||||
uint8_t error, address;
|
||||
|
||||
#if FEATURE_I2CMULTIPLEXER
|
||||
|
||||
if (-1 == channel) {
|
||||
serialPrintln(F("Standard I2C bus"));
|
||||
} else {
|
||||
serialPrintln(concat(F("Multiplexer channel "), channel));
|
||||
}
|
||||
#endif // if FEATURE_I2CMULTIPLEXER
|
||||
|
||||
for (address = 1; address <= 127; address++) {
|
||||
Wire.beginTransmission(address);
|
||||
error = Wire.endTransmission();
|
||||
|
||||
if (error == 0) {
|
||||
serialPrintln(strformat(F("I2C : Found 0x%02x"), address));
|
||||
} else if ((error == 4) || dbg) {
|
||||
serialPrintln(strformat(F("I2C : Error %d at 0x%02x"), error, address));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const __FlashStringHelper* Command_i2c_Scanner(struct EventStruct *event, const char *Line)
|
||||
{
|
||||
uint8_t error, address;
|
||||
|
||||
if (Settings.isI2CEnabled()) {
|
||||
for (address = 1; address <= 127; address++) {
|
||||
Wire.beginTransmission(address);
|
||||
error = Wire.endTransmission();
|
||||
const bool dbg = equals(parseString(Line, 2), F("1"));
|
||||
I2CSelect_Max100kHz_ClockSpeed(); // Scan bus using low speed
|
||||
|
||||
if (error == 0) {
|
||||
serialPrint(F("I2C : Found 0x"));
|
||||
serialPrintln(String(address, HEX));
|
||||
} else if (error == 4) {
|
||||
serialPrint(F("I2C : Error at 0x"));
|
||||
serialPrintln(String(address, HEX));
|
||||
i2c_scanI2Cbus(dbg, -1); // Base I2C bus
|
||||
|
||||
#if FEATURE_I2CMULTIPLEXER
|
||||
|
||||
if (isI2CMultiplexerEnabled()) {
|
||||
uint8_t mux_max = I2CMultiplexerMaxChannels();
|
||||
|
||||
for (int8_t channel = 0; channel < mux_max; ++channel) {
|
||||
I2CMultiplexerSelect(channel);
|
||||
i2c_scanI2Cbus(dbg, channel); // Multiplexer I2C bus
|
||||
}
|
||||
I2CMultiplexerOff();
|
||||
}
|
||||
#endif // if FEATURE_I2CMULTIPLEXER
|
||||
I2CSelectHighClockSpeed(); // By default the bus is in standard speed
|
||||
} else {
|
||||
serialPrintln(F("I2C : Not enabled."));
|
||||
}
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
|
||||
#include "../../ESPEasy_common.h"
|
||||
|
||||
const __FlashStringHelper * Command_i2c_Scanner(struct EventStruct *event, const char* Line);
|
||||
void i2c_scanI2Cbus(bool dbg,
|
||||
int8_t channel);
|
||||
|
||||
const __FlashStringHelper* Command_i2c_Scanner(struct EventStruct *event,
|
||||
const char *Line);
|
||||
|
||||
#endif // COMMAND_I2C_H
|
||||
|
||||
@@ -1789,7 +1789,7 @@ To create/register a plugin, you have to :
|
||||
#define USES_P116 // ST77xx
|
||||
#endif
|
||||
#if !defined(USES_P123) && defined(ESP32)
|
||||
#define USES_P123 // FT6206
|
||||
#define USES_P123 // I2C Touchscreens
|
||||
#endif
|
||||
#if !defined(USES_P137) && defined(ESP32)
|
||||
#define USES_P137 // AXP192
|
||||
@@ -2258,7 +2258,7 @@ To create/register a plugin, you have to :
|
||||
#define USES_P122 // SHT2x
|
||||
#endif
|
||||
#ifndef USES_P123
|
||||
#define USES_P123 // FT6206
|
||||
#define USES_P123 // I2C Touchscreens
|
||||
#endif
|
||||
#ifndef USES_P124
|
||||
#define USES_P124 // I2C Multi relay
|
||||
|
||||
@@ -123,12 +123,12 @@
|
||||
# define TOUCH_FLAGS_SWAP_LEFT_RIGHT 19 // Swaps Left and Right, Up and Down swipe directions for menu actions
|
||||
# define TOUCH_FLAGS_IGNORE_TOUCH 20 // Disable touch, use for object/button features only
|
||||
|
||||
# define TOUCH_GET_VALUE_X UserVar.getInt32(event->TaskIndex, 0)
|
||||
# define TOUCH_GET_VALUE_Y UserVar.getInt32(event->TaskIndex, 1)
|
||||
# define TOUCH_GET_VALUE_Z UserVar.getInt32(event->TaskIndex, 2)
|
||||
# define TOUCH_SET_VALUE_X(N) UserVar.setInt32(event->TaskIndex, 0, N)
|
||||
# define TOUCH_SET_VALUE_Y(N) UserVar.setInt32(event->TaskIndex, 1, N)
|
||||
# define TOUCH_SET_VALUE_Z(N) UserVar.setInt32(event->TaskIndex, 2, N)
|
||||
# define TOUCH_GET_VALUE_X UserVar.getFloat(event->TaskIndex, 0)
|
||||
# define TOUCH_GET_VALUE_Y UserVar.getFloat(event->TaskIndex, 1)
|
||||
# define TOUCH_GET_VALUE_Z UserVar.getFloat(event->TaskIndex, 2)
|
||||
# define TOUCH_SET_VALUE_X(N) UserVar.setFloat(event->TaskIndex, 0, N)
|
||||
# define TOUCH_SET_VALUE_Y(N) UserVar.setFloat(event->TaskIndex, 1, N)
|
||||
# define TOUCH_SET_VALUE_Z(N) UserVar.setFloat(event->TaskIndex, 2, N)
|
||||
|
||||
# define TOUCH_TS_ROTATION 0 // Rotation 0-3 = 0/90/180/270 degrees
|
||||
# define TOUCH_TS_SEND_XY true // Enable/Disable X/Y events
|
||||
|
||||
@@ -4,12 +4,81 @@
|
||||
|
||||
# include "../Helpers/AdafruitGFX_helper.h"
|
||||
|
||||
const __FlashStringHelper* toString(P123_TouchType_e tType) {
|
||||
switch (tType) {
|
||||
case P123_TouchType_e::FT62x6: return F("FT62x6 (0x38)");
|
||||
case P123_TouchType_e::GT911_1: return F("GT911 (0x5D)");
|
||||
case P123_TouchType_e::GT911_2: return F("GT911 (0x14)");
|
||||
case P123_TouchType_e::CST820: return F("CST820 (0x15)");
|
||||
case P123_TouchType_e::CST226: return F("CST226 (0x5A)");
|
||||
case P123_TouchType_e::AXS15231: return F("AXS15231 (0x3B)");
|
||||
case P123_TouchType_e::CHSC5816: return F("CHSC5816 (0x2E)");
|
||||
case P123_TouchType_e::Automatic: return F("Auto-detect");
|
||||
}
|
||||
return F("");
|
||||
}
|
||||
|
||||
/**
|
||||
* Order must match enum P123_TouchType_e, with Automatic (-1) ignored
|
||||
*/
|
||||
const uint8_t P123_i2cAddressValues[] = { FT6X36_ADDR, GT911_ADDR1, GT911_ADDR2, CST820_ADDR, CST226_ADDR, AXS15231_ADDR, CHSC5816_ADDR };
|
||||
|
||||
bool P123_data_struct::plugin_i2c_has_address(const int Par1) {
|
||||
return intArrayContains(NR_ELEMENTS(P123_i2cAddressValues), P123_i2cAddressValues, Par1);
|
||||
}
|
||||
|
||||
uint8_t P123_data_struct::plugin_i2c_address(P123_TouchType_e touchType) {
|
||||
const int tType = static_cast<int>(touchType);
|
||||
|
||||
if ((tType >= 0) && (tType < NR_ELEMENTS(P123_i2cAddressValues))) {
|
||||
return P123_i2cAddressValues[tType];
|
||||
}
|
||||
return 0u;
|
||||
}
|
||||
|
||||
P123_TouchType_e P123_data_struct::getTouchType() {
|
||||
if (nullptr != touchscreen) {
|
||||
const int stype = touchscreen->sensorType();
|
||||
|
||||
switch (stype) {
|
||||
case CT_TYPE_FT6X36: return P123_TouchType_e::FT62x6;
|
||||
case CT_TYPE_GT911:
|
||||
|
||||
if (GT911_ADDR1 == touchscreen->getI2CAddress()) {
|
||||
return P123_TouchType_e::GT911_1;
|
||||
} else {
|
||||
return P123_TouchType_e::GT911_2;
|
||||
}
|
||||
case CT_TYPE_CST820: return P123_TouchType_e::CST820;
|
||||
case CT_TYPE_CST226: return P123_TouchType_e::CST226;
|
||||
case CT_TYPE_AXS15231: return P123_TouchType_e::AXS15231;
|
||||
case CT_TYPE_CHSC5816: return P123_TouchType_e::CHSC5816;
|
||||
}
|
||||
}
|
||||
return P123_TouchType_e::Automatic;
|
||||
}
|
||||
|
||||
int P123_data_struct::getBBCapTouchType(P123_TouchType_e touchType) {
|
||||
switch (touchType) {
|
||||
case P123_TouchType_e::Automatic: return CT_TYPE_UNKNOWN;
|
||||
case P123_TouchType_e::FT62x6: return CT_TYPE_FT6X36;
|
||||
case P123_TouchType_e::GT911_1: // Fall through
|
||||
case P123_TouchType_e::GT911_2: return CT_TYPE_GT911;
|
||||
case P123_TouchType_e::CST820: return CT_TYPE_CST820;
|
||||
case P123_TouchType_e::CST226: return CT_TYPE_CST226;
|
||||
case P123_TouchType_e::AXS15231: return CT_TYPE_AXS15231;
|
||||
case P123_TouchType_e::CHSC5816: return CT_TYPE_CHSC5816;
|
||||
}
|
||||
return CT_TYPE_UNKNOWN;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
P123_data_struct::P123_data_struct()
|
||||
: touchscreen(nullptr) {
|
||||
P123_data_struct::P123_data_struct(P123_TouchType_e touchType)
|
||||
: _touchType(touchType) {
|
||||
touchHandler = new (std::nothrow) ESPEasy_TouchHandler(); // Temporary object to be able to call loadTouchObjects
|
||||
_i2caddr = plugin_i2c_address(_touchType);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -50,12 +119,23 @@ bool P123_data_struct::init(struct EventStruct *event) {
|
||||
touchHandler->init(event);
|
||||
|
||||
if (touchHandler->touchEnabled()) {
|
||||
touchscreen = new (std::nothrow) Adafruit_FT6206();
|
||||
touchscreen = new (std::nothrow) BBCapTouch();
|
||||
|
||||
if (nullptr != touchscreen) {
|
||||
if (!touchscreen->begin(P123_CONFIG_THRESHOLD)) {
|
||||
touchscreen->setThreshold(P123_CONFIG_THRESHOLD);
|
||||
|
||||
P123_TouchType_e touchType = static_cast<P123_TouchType_e>(P123_GET_TOUCH_TYPE);
|
||||
|
||||
if (P123_TouchType_e::Automatic != touchType) { // Manual override
|
||||
touchscreen->sensorType(getBBCapTouchType(touchType));
|
||||
touchscreen->setI2CAddress(plugin_i2c_address(touchType));
|
||||
}
|
||||
|
||||
if (touchscreen->init(-1, -1, P123_RESETPIN, P123_INTERRUPTPIN) != CT_SUCCESS) {
|
||||
delete touchscreen;
|
||||
touchscreen = nullptr;
|
||||
} else {
|
||||
setRotation(_rotation);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -213,7 +293,7 @@ void P123_data_struct::loadTouchObjects(struct EventStruct *event) {
|
||||
*/
|
||||
bool P123_data_struct::touched() {
|
||||
if (isInitialized()) {
|
||||
return touchscreen->touched();
|
||||
return touchscreen->getSamples(&touchInfo) > 0; // 1 or more points touched
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -227,55 +307,11 @@ void P123_data_struct::readData(int16_t& x,
|
||||
int16_t& ox,
|
||||
int16_t& oy) {
|
||||
if (isInitialized()) {
|
||||
FT_Point p = touchscreen->getPoint();
|
||||
|
||||
int16_t _x = p.x;
|
||||
int16_t _y = p.y;
|
||||
|
||||
// Rotate, as the driver doesn't provide that, use native touch-panel resolution
|
||||
switch (_rotation) {
|
||||
case P123_ROTATION_90:
|
||||
|
||||
if (touchHandler->_flipped) {
|
||||
p.x = map(_y, 0, P123_TOUCH_Y_NATIVE, P123_TOUCH_Y_NATIVE, 0);
|
||||
p.y = _x;
|
||||
} else {
|
||||
p.x = _y;
|
||||
p.y = map(_x, 0, P123_TOUCH_X_NATIVE, P123_TOUCH_X_NATIVE, 0);
|
||||
}
|
||||
break;
|
||||
case P123_ROTATION_180:
|
||||
|
||||
if (!touchHandler->_flipped) { // Change only when not flipped
|
||||
p.x = map(_x, 0, P123_TOUCH_X_NATIVE, P123_TOUCH_X_NATIVE, 0);
|
||||
p.y = map(_y, 0, P123_TOUCH_Y_NATIVE, P123_TOUCH_Y_NATIVE, 0);
|
||||
}
|
||||
break;
|
||||
case P123_ROTATION_270:
|
||||
|
||||
if (touchHandler->_flipped) {
|
||||
p.x = _y;
|
||||
p.y = map(_x, 0, P123_TOUCH_X_NATIVE, P123_TOUCH_X_NATIVE, 0);
|
||||
} else {
|
||||
p.x = map(_y, 0, P123_TOUCH_Y_NATIVE, P123_TOUCH_Y_NATIVE, 0);
|
||||
p.y = _x;
|
||||
}
|
||||
break;
|
||||
case P123_ROTATION_0:
|
||||
default:
|
||||
|
||||
if (touchHandler->_flipped) {
|
||||
p.x = map(p.x, 0, P123_TOUCH_X_NATIVE, P123_TOUCH_X_NATIVE, 0);
|
||||
p.y = map(p.y, 0, P123_TOUCH_Y_NATIVE, P123_TOUCH_Y_NATIVE, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
x = p.x;
|
||||
y = p.y;
|
||||
z = p.z;
|
||||
ox = _x;
|
||||
oy = _y;
|
||||
x = touchInfo.x[0]; // Only 1 point used for now.
|
||||
y = touchInfo.y[0];
|
||||
z = touchInfo.pressure[0];
|
||||
ox = touchInfo.x[0]; // Change of touch driver has made these arguments obsolete, but in use for touchHandler...
|
||||
oy = touchInfo.y[0];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -284,6 +320,17 @@ void P123_data_struct::readData(int16_t& x,
|
||||
*/
|
||||
void P123_data_struct::setRotation(uint8_t n) {
|
||||
_rotation = n;
|
||||
|
||||
if (isInitialized()) {
|
||||
const bool fl = touchHandler->_flipped;
|
||||
|
||||
switch (_rotation) { // Rotation is handled by touch driver, flipped handled here
|
||||
case 0: touchscreen->setOrientation(fl ? 180 : 0, _ts_x_res, _ts_y_res); break;
|
||||
case 1: touchscreen->setOrientation(fl ? 270 : 90, _ts_x_res, _ts_y_res); break;
|
||||
case 2: touchscreen->setOrientation(fl ? 0 : 180, _ts_x_res, _ts_y_res); break;
|
||||
case 3: touchscreen->setOrientation(fl ? 90 : 270, _ts_x_res, _ts_y_res); break;
|
||||
}
|
||||
}
|
||||
# ifdef PLUGIN_123_DEBUG
|
||||
|
||||
if (loglevelActiveFor(LOG_LEVEL_INFO)) {
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
# include "../Helpers/ESPEasy_TouchHandler.h"
|
||||
|
||||
# include <Adafruit_FT6206.h>
|
||||
# include <bb_captouch.h>
|
||||
|
||||
# ifndef LIMIT_BUILD_SIZE
|
||||
# define PLUGIN_123_DEBUG // Additional debugging information
|
||||
@@ -21,9 +21,19 @@
|
||||
# undef PLUGIN_123_DEBUG
|
||||
# endif // if defined(BUILD_NO_DEBUG) && defined(PLUGIN_123_DEBUG)
|
||||
|
||||
# define P123_I2C_ADDRESS (0x38) // Fixed value
|
||||
# define P123_I2C_ADDRESS PCONFIG(6)
|
||||
# define P123_CONFIG_DISPLAY_TASK PCONFIG(0)
|
||||
|
||||
# define P123_CONFIG_FLAGS PCONFIG_ULONG(0) // All flags
|
||||
# define P123_CONFIG_FLAG_TOUCHTYPE 0 // Flag indexes
|
||||
|
||||
// We're storing an int8_t in range -128..127 in an uin8_t
|
||||
# define P123_GET_TOUCH_TYPE (get8BitFromUL(P123_CONFIG_FLAGS, P123_CONFIG_FLAG_TOUCHTYPE) - 128)
|
||||
# define P123_SET_TOUCH_TYPE(T) (set8BitToUL(P123_CONFIG_FLAGS, P123_CONFIG_FLAG_TOUCHTYPE, T + 128))
|
||||
|
||||
# define P123_INTERRUPTPIN (CONFIG_PIN1)
|
||||
# define P123_RESETPIN (CONFIG_PIN2)
|
||||
|
||||
# define P123_COLOR_DEPTH PCONFIG_LONG(1)
|
||||
# define P123_CONFIG_THRESHOLD PCONFIG(1)
|
||||
# define P123_CONFIG_ROTATION PCONFIG(2)
|
||||
@@ -47,31 +57,50 @@
|
||||
# define P123_ROTATION_180 2
|
||||
# define P123_ROTATION_270 3
|
||||
|
||||
enum class P123_TouchType_e : int8_t {
|
||||
Automatic = -1,
|
||||
FT62x6 = 0, // Also used as offset in I2C address array
|
||||
GT911_1 = 1,
|
||||
GT911_2 = 2,
|
||||
CST820 = 3,
|
||||
CST226 = 4,
|
||||
AXS15231 = 5,
|
||||
CHSC5816 = 6,
|
||||
};
|
||||
|
||||
const __FlashStringHelper* toString(P123_TouchType_e tType);
|
||||
|
||||
// Data structure
|
||||
struct P123_data_struct : public PluginTaskData_base
|
||||
{
|
||||
P123_data_struct();
|
||||
P123_data_struct(P123_TouchType_e touchType);
|
||||
~P123_data_struct();
|
||||
|
||||
void reset();
|
||||
bool init(struct EventStruct *event);
|
||||
bool isInitialized() const;
|
||||
static bool plugin_i2c_has_address(int Par1);
|
||||
static uint8_t plugin_i2c_address(P123_TouchType_e touchType);
|
||||
|
||||
bool plugin_webform_load(struct EventStruct *event);
|
||||
bool plugin_webform_save(struct EventStruct *event);
|
||||
bool plugin_write(struct EventStruct *event,
|
||||
const String & string);
|
||||
bool plugin_fifty_per_second(struct EventStruct *event);
|
||||
bool plugin_get_config_value(struct EventStruct *event,
|
||||
String & string);
|
||||
P123_TouchType_e getTouchType();
|
||||
int getBBCapTouchType(P123_TouchType_e touchType);
|
||||
|
||||
void loadTouchObjects(struct EventStruct *event);
|
||||
bool touched();
|
||||
void readData(int16_t& x,
|
||||
int16_t& y,
|
||||
int16_t& z,
|
||||
int16_t& ox,
|
||||
int16_t& oy);
|
||||
void reset();
|
||||
bool init(struct EventStruct *event);
|
||||
bool isInitialized() const;
|
||||
|
||||
bool plugin_webform_load(struct EventStruct *event);
|
||||
bool plugin_webform_save(struct EventStruct *event);
|
||||
bool plugin_write(struct EventStruct *event,
|
||||
const String & string);
|
||||
bool plugin_fifty_per_second(struct EventStruct *event);
|
||||
bool plugin_get_config_value(struct EventStruct *event,
|
||||
String & string);
|
||||
|
||||
void loadTouchObjects(struct EventStruct *event);
|
||||
bool touched();
|
||||
void readData(int16_t& x,
|
||||
int16_t& y,
|
||||
int16_t& z,
|
||||
int16_t& ox,
|
||||
int16_t& oy);
|
||||
|
||||
void setRotation(uint8_t n);
|
||||
void setRotationFlipped(bool _flipped);
|
||||
@@ -111,13 +140,20 @@ struct P123_data_struct : public PluginTaskData_base
|
||||
private:
|
||||
|
||||
// This is initialized by calling init()
|
||||
Adafruit_FT6206 *touchscreen = nullptr;
|
||||
uint8_t _rotation = 0u;
|
||||
uint16_t _ts_x_res = 0u;
|
||||
uint16_t _ts_y_res = 0u;
|
||||
BBCapTouch *touchscreen = nullptr;
|
||||
uint8_t _rotation = 0u;
|
||||
uint16_t _ts_x_res = 0u;
|
||||
uint16_t _ts_y_res = 0u;
|
||||
|
||||
int16_t _i2caddr{};
|
||||
int16_t _resetPin = -1;
|
||||
int16_t _interruptPin = -1;
|
||||
P123_TouchType_e _touchType;
|
||||
|
||||
TOUCHINFO touchInfo;
|
||||
|
||||
ESPEasy_TouchHandler *touchHandler = nullptr;
|
||||
};
|
||||
|
||||
#endif // ifdef USED_P123
|
||||
#endif // ifdef USES_P123
|
||||
#endif // ifndef PLUGINSTRUCTS_P123_DATA_STRUCT_H
|
||||
|
||||
@@ -187,13 +187,17 @@ String getKnownI2Cdevice(uint8_t address) {
|
||||
break;
|
||||
case 0x12:
|
||||
case 0x13:
|
||||
case 0x14:
|
||||
case 0x15:
|
||||
case 0x16:
|
||||
case 0x17:
|
||||
case 0x18:
|
||||
result += F("I2C_MultiRelay");
|
||||
break;
|
||||
case 0x14:
|
||||
result += F("I2C_MultiRelay,GT911");
|
||||
break;
|
||||
case 0x15:
|
||||
result += F("I2C_MultiRelay,CST820");
|
||||
break;
|
||||
case 0x1D:
|
||||
result += F("ADXL345");
|
||||
break;
|
||||
@@ -217,6 +221,9 @@ String getKnownI2Cdevice(uint8_t address) {
|
||||
case 0x29:
|
||||
result += F("TSL2561,TSL2591,TCS34725,VL53L0X,VL53L1X");
|
||||
break;
|
||||
case 0x2E:
|
||||
result += F("CHSC5816");
|
||||
break;
|
||||
case 0x30:
|
||||
result += F("VL53L0X,VL53L1X");
|
||||
break;
|
||||
@@ -236,9 +243,11 @@ String getKnownI2Cdevice(uint8_t address) {
|
||||
result += F("LCD,PCF8574A,TSL2561,APDS9960,AHT10,Adafruit Rotary enc,Adafruit Soil moisture");
|
||||
break;
|
||||
case 0x3A:
|
||||
case 0x3B:
|
||||
result += F("LCD,PCF8574A,Adafruit Rotary enc");
|
||||
break;
|
||||
case 0x3B:
|
||||
result += F("LCD,PCF8574A,Adafruit Rotary enc,AXS15231");
|
||||
break;
|
||||
case 0x3C:
|
||||
case 0x3D:
|
||||
result += F("LCD,PCF8574A,OLED,Adafruit Rotary enc");
|
||||
@@ -299,7 +308,7 @@ String getKnownI2Cdevice(uint8_t address) {
|
||||
result += F("SGP4x,GP8403");
|
||||
break;
|
||||
case 0x5A:
|
||||
result += F("MLX90614,MPR121,CCS811,GP8403");
|
||||
result += F("MLX90614,MPR121,CCS811,GP8403,CST226");
|
||||
break;
|
||||
case 0x5B:
|
||||
result += F("MPR121,CCS811,GP8403");
|
||||
@@ -308,7 +317,7 @@ String getKnownI2Cdevice(uint8_t address) {
|
||||
result += F("DHT12,AM2320,BH1750,MPR121,GP8403");
|
||||
break;
|
||||
case 0x5D:
|
||||
result += F("MPR121,GP8403");
|
||||
result += F("MPR121,GP8403,GT911");
|
||||
break;
|
||||
case 0x5E:
|
||||
case 0x5F:
|
||||
|
||||
Reference in New Issue
Block a user