37#define IO_EXPANDER_TOUCH_RST (3 | 0x80)
38#define IO_EXPANDER_TOUCH_IRQ (4 | 0x80)
40#ifdef ARDUINO_ESP32P4_DEV
61 uint32_t startTime = 0;
62 uint32_t lastTime = 0;
68static const int SWIPE_THRESHOLD = 70;
69static const int TAP_MOVE_THRESHOLD = 18;
70static const uint32_t TAP_TIME_THRESHOLD = 250;
71static const uint32_t MAX_GESTURE_TIME = 1200;
72static const float DOMINANCE_RATIO = 1.2f;
73static const bool enableTap =
false;
76static const uint32_t SWIPE_COOLDOWN_MS = 600;
78uint32_t lastSwipeEventTime = 0;
79bool swipeEventLocked =
false;
87 digitalWrite(gpio,
level);
96 return digitalRead(gpio);
109const char *gestureToString(GestureType g)
112 case GESTURE_TAP:
return "TAP";
113 case GESTURE_LEFT:
return "LEFT";
114 case GESTURE_RIGHT:
return "RIGHT";
115 case GESTURE_UP:
return "UP";
116 case GESTURE_DOWN:
return "DOWN";
117 default:
return "NONE";
121bool isSwipeGesture(GestureType g)
123 return g == GESTURE_LEFT ||
124 g == GESTURE_RIGHT ||
131 gesture.active =
false;
137 gesture.startTime = 0;
138 gesture.lastTime = 0;
142GestureType classifyGesture(
int dx,
int dy, uint32_t dt)
147 if (dt <= TAP_TIME_THRESHOLD && adx <= TAP_MOVE_THRESHOLD && ady <= TAP_MOVE_THRESHOLD) {
151 if (dt > MAX_GESTURE_TIME) {
155 if (adx >= SWIPE_THRESHOLD && (
float)adx > (
float)ady * DOMINANCE_RATIO) {
156 return dx > 0 ? GESTURE_RIGHT : GESTURE_LEFT;
159 if (ady >= SWIPE_THRESHOLD && (
float)ady > (
float)adx * DOMINANCE_RATIO) {
160 return dy > 0 ? GESTURE_DOWN : GESTURE_UP;
166void unlockSwipeIfNeeded(uint32_t now)
168 if (swipeEventLocked && (now - lastSwipeEventTime) >= SWIPE_COOLDOWN_MS) {
169 swipeEventLocked =
false;
173bool canEmitSwipe(uint32_t now)
175 if (!swipeEventLocked) {
178 return (now - lastSwipeEventTime) >= SWIPE_COOLDOWN_MS;
181void lockSwipeEvent(uint32_t now)
183 lastSwipeEventTime = now;
184 swipeEventLocked =
true;
187void printGestureResult(GestureType type,
int dx,
int dy, uint32_t dt)
189 Serial.println(
"===== Gesture Result =====");
190 Serial.printf(
"id : %u\n", gesture.id);
191 Serial.printf(
"start : (%d, %d)\n", gesture.startX, gesture.startY);
192 Serial.printf(
"end : (%d, %d)\n", gesture.lastX, gesture.lastY);
193 Serial.printf(
"delta : dx=%d dy=%d\n", dx, dy);
194 Serial.printf(
"time : %lu ms\n", (
unsigned long)dt);
195 Serial.printf(
"samples : %u\n", gesture.samples);
196 Serial.printf(
"gesture : %s\n", gestureToString(type));
197 if (isSwipeGesture(type)) {
198 Serial.printf(
"swipe cooldown: %lu ms\n", (
unsigned long)SWIPE_COOLDOWN_MS);
205 Serial.begin(115200);
208 Serial.println(
"GT9895 Gesture Test - swipe cooldown only, tap excluded");
214 Serial.println(
"Failed to find io expander - check your wiring!");
222 if (!
touch.
begin(Wire, GT9895_SLAVE_ADDRESS_L)) {
224 Serial.println(
"Failed to find touch device - check your wiring!");
229 Serial.println(
"GT9895 Touch Initialized");
230 Serial.print(
"Chip ID : 0x");
242 Serial.printf(
"Ready. Swipe cooldown = %lu ms, TAP is not limited.\n",
243 (
unsigned long)SWIPE_COOLDOWN_MS);
249 uint32_t now = millis();
250 unlockSwipeIfNeeded(now);
257 if (!gesture.active) {
258 gesture.active =
true;
259 gesture.id = point.
id;
260 gesture.startX = point.
x;
261 gesture.startY = point.
y;
262 gesture.lastX = point.
x;
263 gesture.lastY = point.
y;
264 gesture.startTime = now;
265 gesture.lastTime = now;
268 gesture.lastX = point.
x;
269 gesture.lastY = point.
y;
270 gesture.lastTime = now;
274 if (gesture.active) {
275 int dx = gesture.lastX - gesture.startX;
276 int dy = gesture.lastY - gesture.startY;
277 uint32_t dt = gesture.lastTime - gesture.startTime;
279 GestureType type = classifyGesture(dx, dy, dt);
281 if (type == GESTURE_TAP) {
283 printGestureResult(type, dx, dy, dt);
285 }
else if (isSwipeGesture(type)) {
286 if (canEmitSwipe(now)) {
287 printGestureResult(type, dx, dy, dt);
301 Serial.begin(115200);
305 Serial.println(
"Sketch only works with LilyGo-T-Display-P4 AMOLED(GT9895) Version");
bool begin(SensorCommCustom::CustomCallback callback, uint8_t addr)
Initialize the sensor using custom callback interface.
bool digitalRead(uint8_t pin)
Read the digital value from an input pin.
void pinMode(uint8_t pin, uint8_t mode)
Set the direction of a GPIO pin.
void digitalWrite(uint8_t pin, bool value)
Write a digital value to an output pin.
Concrete driver for the XL9555 16‑bit I2C GPIO expander.
bool begin(SensorCommCustom::CustomCallback callback, SensorCommCustomHal::CustomHalCallback hal_callback, uint8_t addr) override
Initialize the touch driver for custom communication.
const TouchPoints & getTouchPoints() override
Get the touch points.
uint32_t getChipID() override
Get the chip ID.
virtual void setGpioCallback(SensorHalCustom::CustomMode mode_cb, SensorHalCustom::CustomWrite write_cb, SensorHalCustom::CustomRead read_cb)
Set custom GPIO callbacks for pin control (e.g., reset, interrupt).
virtual void setResolution(uint16_t width, uint16_t height)
Set the raw resolution of the touch panel (physical maximum coordinates).
virtual void setPins(int rst, int irq)
Set the hardware reset and interrupt pin numbers.
virtual void setTargetResolution(uint16_t width, uint16_t height)
Set the target display resolution to map touch coordinates to screen pixels.
Container for touch point data and optional gesture information.
TouchPoint & getPoint(uint8_t index)
Gets a reference to a touch point at the specified index.
bool hasPoints() const
Checks whether any touch points are stored.
#define IO_EXPANDER_TOUCH_IRQ
#define IO_EXPANDER_TOUCH_RST
IoExpanderPCA9570 expander
Represents a single touch point with its properties.
uint8_t id
Touch point ID for multi‑touch tracking.
uint16_t x
X coordinate of the touch point.
uint16_t y
Y coordinate of the touch point.
void TouchDrvPinMode(uint8_t gpio, uint8_t mode)
void TouchDrvDigitalWrite(uint8_t gpio, uint8_t level)
uint8_t TouchDrvDigitalRead(uint8_t gpio)