feat(touch): implementar doble clic para cambiar pantalla, clic simple para pantalla completa y clic largo para configuracion con inmunidad a toques fantasma
This commit is contained in:
parent
26b0cd2ab3
commit
9e7b749404
3 changed files with 77 additions and 89 deletions
|
|
@ -22,8 +22,8 @@
|
||||||
|
|
||||||
#include "XPT2046_TouchscreenSOFTSPI.h"
|
#include "XPT2046_TouchscreenSOFTSPI.h"
|
||||||
|
|
||||||
#define Z_THRESHOLD 65
|
#define Z_THRESHOLD 180
|
||||||
#define Z_THRESHOLD_INT 50
|
#define Z_THRESHOLD_INT 100
|
||||||
#define MSEC_THRESHOLD 3
|
#define MSEC_THRESHOLD 3
|
||||||
#define SPI_SETTING SPISettings(2000000, MSBFIRST, SPI_MODE0)
|
#define SPI_SETTING SPISettings(2000000, MSBFIRST, SPI_MODE0)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -573,9 +573,10 @@ void loop() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// SCAN TOUCHSCREEN & BUTTON
|
// SCAN TOUCHSCREEN & BUTTON
|
||||||
// - Single tap on a quadrant in 4-quadrant view: switches to full screen for that quadrant
|
// - Double click: switch screen page (Page 0 <-> Page 1) with slide animation
|
||||||
// - Single tap anywhere in full screen view: returns to 4-quadrant view
|
// - Single click: toggle fullscreen for tapped quadrant (or refresh sensors on Tri-Temp)
|
||||||
// - Long press (> 1s) on screen OR holding selector button: opens configuration menu
|
// - Long press (> 1s): open configuration menu
|
||||||
|
// - Physical selector button: open configuration menu
|
||||||
uint16_t touchX = 0, touchY = 0;
|
uint16_t touchX = 0, touchY = 0;
|
||||||
bool isTouched = getTouch(&touchX, &touchY);
|
bool isTouched = getTouch(&touchX, &touchY);
|
||||||
bool btnPressed = (digitalRead(SELECTOR_PIN) == LOW);
|
bool btnPressed = (digitalRead(SELECTOR_PIN) == LOW);
|
||||||
|
|
@ -590,9 +591,15 @@ void loop() {
|
||||||
static uint16_t lastTouchX = 0, lastTouchY = 0;
|
static uint16_t lastTouchX = 0, lastTouchY = 0;
|
||||||
static bool longPressHandled = false;
|
static bool longPressHandled = false;
|
||||||
|
|
||||||
|
// Double-tap state machine
|
||||||
|
static bool waitingForDoubleTap = false;
|
||||||
|
static uint32_t firstTapReleaseTime = 0;
|
||||||
|
static uint16_t firstTapX = 0, firstTapY = 0;
|
||||||
|
|
||||||
if (btnPressed) {
|
if (btnPressed) {
|
||||||
delay(50);
|
delay(50);
|
||||||
if (digitalRead(SELECTOR_PIN) == LOW) {
|
if (digitalRead(SELECTOR_PIN) == LOW) {
|
||||||
|
waitingForDoubleTap = false;
|
||||||
touchBeep();
|
touchBeep();
|
||||||
configMenu();
|
configMenu();
|
||||||
waitForTouchRelease();
|
waitForTouchRelease();
|
||||||
|
|
@ -608,113 +615,94 @@ void loop() {
|
||||||
lastTouchX = touchX;
|
lastTouchX = touchX;
|
||||||
lastTouchY = touchY;
|
lastTouchY = touchY;
|
||||||
longPressHandled = false;
|
longPressHandled = false;
|
||||||
touchBeep(); // Crisp acoustic feedback on touch screen press!
|
|
||||||
} else {
|
} else {
|
||||||
// Keep tracking coordinates while held to ensure stable swipe/quadrant detection
|
|
||||||
lastTouchX = touchX;
|
lastTouchX = touchX;
|
||||||
lastTouchY = touchY;
|
lastTouchY = touchY;
|
||||||
|
|
||||||
int16_t liveDeltaX = (int16_t)lastTouchX - (int16_t)touchStartX;
|
// Long press check: finger held stationary for > 1000ms
|
||||||
int16_t liveDeltaY = (int16_t)lastTouchY - (int16_t)touchStartY;
|
int16_t currentDistX = abs((int16_t)lastTouchX - (int16_t)touchStartX);
|
||||||
|
int16_t currentDistY = abs((int16_t)lastTouchY - (int16_t)touchStartY);
|
||||||
|
|
||||||
// FAST LIVE SWIPE DETECTION:
|
if (!longPressHandled && (millis() - touchStartTime > 1000) && currentDistX < 35 && currentDistY < 35) {
|
||||||
// Trigger immediately as soon as finger moves >= 28px horizontally (no need to lift or press hard)
|
longPressHandled = true;
|
||||||
if (!longPressHandled) {
|
waitingForDoubleTap = false;
|
||||||
if (liveDeltaX < -28 && abs(liveDeltaY) < 85) {
|
touchBeep(); // Confirmation chirp
|
||||||
// SWIPE LEFT: Page 0 -> Page 1 (Tri-Temperature Screen)
|
configMenu();
|
||||||
longPressHandled = true;
|
waitForTouchRelease();
|
||||||
if (fullScreenCell != -1) {
|
lastActivityTime = millis();
|
||||||
fullScreenCell = -1;
|
initScreen();
|
||||||
}
|
isTouching = false;
|
||||||
if (currentScreenPage == 0) {
|
|
||||||
animateSlideTransition(true);
|
|
||||||
currentScreenPage = 1;
|
|
||||||
initScreen();
|
|
||||||
}
|
|
||||||
waitForTouchRelease();
|
|
||||||
isTouching = false;
|
|
||||||
lastActivityTime = millis();
|
|
||||||
} else if (liveDeltaX > 28 && abs(liveDeltaY) < 85) {
|
|
||||||
// SWIPE RIGHT: Page 1 -> Page 0 (4 Quadrants)
|
|
||||||
longPressHandled = true;
|
|
||||||
if (fullScreenCell != -1) {
|
|
||||||
fullScreenCell = -1;
|
|
||||||
}
|
|
||||||
if (currentScreenPage == 1) {
|
|
||||||
animateSlideTransition(false);
|
|
||||||
currentScreenPage = 0;
|
|
||||||
initScreen();
|
|
||||||
}
|
|
||||||
waitForTouchRelease();
|
|
||||||
isTouching = false;
|
|
||||||
lastActivityTime = millis();
|
|
||||||
} else if ((millis() - touchStartTime > 1000) && abs(liveDeltaX) < 20 && abs(liveDeltaY) < 20) {
|
|
||||||
// Long press (> 1s) held stationary: Open Config Menu immediately!
|
|
||||||
longPressHandled = true;
|
|
||||||
touchBeep(); // Confirmation chirp
|
|
||||||
configMenu();
|
|
||||||
waitForTouchRelease();
|
|
||||||
lastActivityTime = millis();
|
|
||||||
initScreen();
|
|
||||||
isTouching = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Touch / button released
|
// Touch released
|
||||||
if (isTouching) {
|
if (isTouching) {
|
||||||
isTouching = false;
|
isTouching = false;
|
||||||
|
uint32_t pressDuration = millis() - touchStartTime;
|
||||||
|
|
||||||
if (!longPressHandled) {
|
if (!longPressHandled) {
|
||||||
int16_t deltaX = (int16_t)lastTouchX - (int16_t)touchStartX;
|
int16_t deltaX = abs((int16_t)lastTouchX - (int16_t)touchStartX);
|
||||||
int16_t deltaY = (int16_t)lastTouchY - (int16_t)touchStartY;
|
int16_t deltaY = abs((int16_t)lastTouchY - (int16_t)touchStartY);
|
||||||
|
|
||||||
// Quick flick swipe fallback in case finger was lifted very rapidly
|
// Anti-noise: require at least 30ms of contact and displacement < 40px (clean tap)
|
||||||
if (deltaX < -25 && abs(deltaY) < 85) {
|
if (pressDuration >= 30 && deltaX < 40 && deltaY < 40) {
|
||||||
// SWIPE LEFT: Page 0 -> Page 1 (Tri-Temperature Screen)
|
touchBeep(); // Crisp acoustic feedback on confirmed tap!
|
||||||
if (fullScreenCell != -1) {
|
|
||||||
fullScreenCell = -1;
|
if (waitingForDoubleTap && (millis() - firstTapReleaseTime <= 400)) {
|
||||||
}
|
// DOUBLE CLICK DETECTED: Switch Screen Page!
|
||||||
if (currentScreenPage == 0) {
|
waitingForDoubleTap = false;
|
||||||
animateSlideTransition(true);
|
|
||||||
currentScreenPage = 1;
|
if (fullScreenCell != -1) {
|
||||||
initScreen();
|
|
||||||
}
|
|
||||||
} else if (deltaX > 25 && abs(deltaY) < 85) {
|
|
||||||
// SWIPE RIGHT: Page 1 -> Page 0 (4 Quadrants)
|
|
||||||
if (fullScreenCell != -1) {
|
|
||||||
fullScreenCell = -1;
|
|
||||||
}
|
|
||||||
if (currentScreenPage == 1) {
|
|
||||||
animateSlideTransition(false);
|
|
||||||
currentScreenPage = 0;
|
|
||||||
initScreen();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Valid TAP detected!
|
|
||||||
if (currentScreenPage == 0) {
|
|
||||||
if (fullScreenCell == -1) {
|
|
||||||
// Switch to full screen for tapped quadrant
|
|
||||||
int quad = (lastTouchX < 160) ? ((lastTouchY < 120) ? 0 : 2) : ((lastTouchY < 120) ? 1 : 3);
|
|
||||||
fullScreenCell = quad;
|
|
||||||
} else {
|
|
||||||
// Return to 4 quadrants view
|
|
||||||
fullScreenCell = -1;
|
fullScreenCell = -1;
|
||||||
}
|
}
|
||||||
initScreen();
|
|
||||||
|
if (currentScreenPage == 0) {
|
||||||
|
animateSlideTransition(true);
|
||||||
|
currentScreenPage = 1;
|
||||||
|
initScreen();
|
||||||
|
} else {
|
||||||
|
animateSlideTransition(false);
|
||||||
|
currentScreenPage = 0;
|
||||||
|
initScreen();
|
||||||
|
}
|
||||||
|
waitForTouchRelease();
|
||||||
|
lastActivityTime = millis();
|
||||||
} else {
|
} else {
|
||||||
// Tap on Tri-Temp screen: immediate sensor refresh
|
// First tap of a potential double click: start waiting window
|
||||||
updateTriTempSensors(true);
|
waitingForDoubleTap = true;
|
||||||
|
firstTapReleaseTime = millis();
|
||||||
|
firstTapX = lastTouchX;
|
||||||
|
firstTapY = lastTouchY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
waitForTouchRelease(); // Clear mechanical bounce on release
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if double-tap timeout has expired -> execute SINGLE CLICK action!
|
||||||
|
if (waitingForDoubleTap && (millis() - firstTapReleaseTime > 400)) {
|
||||||
|
waitingForDoubleTap = false;
|
||||||
|
|
||||||
|
if (currentScreenPage == 0) {
|
||||||
|
if (fullScreenCell == -1) {
|
||||||
|
// Switch to full screen for tapped quadrant
|
||||||
|
int quad = (firstTapX < 160) ? ((firstTapY < 120) ? 0 : 2) : ((firstTapY < 120) ? 1 : 3);
|
||||||
|
fullScreenCell = quad;
|
||||||
|
} else {
|
||||||
|
// Return to 4 quadrants view
|
||||||
|
fullScreenCell = -1;
|
||||||
|
}
|
||||||
|
initScreen();
|
||||||
|
} else {
|
||||||
|
// Tap on Tri-Temp screen: immediate sensor refresh
|
||||||
|
updateTriTempSensors(true);
|
||||||
|
}
|
||||||
|
lastActivityTime = millis();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// AUTO-SLEEP BY INACTIVITY
|
// AUTO-SLEEP BY INACTIVITY
|
||||||
// If auto-sleep is enabled, and screen is not being held, and engine is stopped (RPM <= 300)
|
// If auto-sleep is enabled, and screen is not being held, and engine is stopped (RPM <= 300)
|
||||||
if (autoSleepIndex > 0 && !isTouching && !btnPressed && !longPressHandled && currentRpm <= 300.0f) {
|
if (autoSleepIndex > 0 && !isTouching && !btnPressed && !longPressHandled && !waitingForDoubleTap && currentRpm <= 300.0f) {
|
||||||
uint32_t timeoutMs = (uint32_t)AUTO_SLEEP_SEC_TABLE[autoSleepIndex] * 1000UL;
|
uint32_t timeoutMs = (uint32_t)AUTO_SLEEP_SEC_TABLE[autoSleepIndex] * 1000UL;
|
||||||
if (millis() - lastActivityTime >= timeoutMs) {
|
if (millis() - lastActivityTime >= timeoutMs) {
|
||||||
enterLightSleep();
|
enterLightSleep();
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ bool getTouch(uint16_t *x, uint16_t *y) {
|
||||||
TS_Point p = ts.getPoint(tsSoftSpi);
|
TS_Point p = ts.getPoint(tsSoftSpi);
|
||||||
|
|
||||||
// Filter noise: require valid touch pressure and coordinates within active screen
|
// Filter noise: require valid touch pressure and coordinates within active screen
|
||||||
if (p.z < 60) return false;
|
if (p.z < 160) return false;
|
||||||
if (p.x < 150 || p.x > 3850 || p.y < 150 || p.y > 3850) return false;
|
if (p.x < 150 || p.x > 3850 || p.y < 150 || p.y > 3850) return false;
|
||||||
|
|
||||||
int16_t tx = map(p.x, 200, 3700, 0, 320);
|
int16_t tx = map(p.x, 200, 3700, 0, 320);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue