need help with a project (C++) esp32 Trackpad
i did make a git for anyone to use:
https://github.com/Volanaro/cirque-pinnacle-trackpad-Olimex-ESP32-S3-DevKit-Lipo-pihut-
the problem im having is the "glide" is not working, and i randomly get the mouse freezing than it will contiune, im not sure where to go from here iv been stuck for a While..
anyhelp would be amzing, just incase here is my "loop"
Now im using a cirque Trackpad...
void loop() {
// ==================== HOUSEKEEPING ====================
hapticsUpdate();
unsigned long now = millis();
bool doPoll = false;
if (now - lastPollTime >= POLL_INTERVAL_MS) {
lastPollTime = now;
doPoll = true;
}
// ==================== BUTTONS FIRST ====================
handleButtons();
updateLED();
bool bleConnected = bleKeyboard.isConnected();
// ==================== READ TOUCHPAD ====================
if (doPoll) {
Pinnacle_GetAbsolute(&touchData);
}
bool touchDown = (touchData.zValue > 0);
bool newTouchDown = (touchDown && !prevRawTouch);
bool newTouchUp = (!touchDown && prevRawTouch);
prevRawTouch = touchDown;
// ==================== STATIC STATE ====================
static float vx = 0, vy = 0;
static float rawVX = 0, rawVY = 0;
static float smoothFactor = 0.35f;
static float friction = 0.92f;
static float minGlideSpeed = 0.15f;
// ==================== MAP TOUCH ====================
int x = map(touchData.xValue, PINNACLE_X_LOWER, PINNACLE_X_UPPER, 0, 8000);
int y = map(touchData.yValue, PINNACLE_Y_LOWER, PINNACLE_Y_UPPER, 0, 8000);
// ==================== NEW TOUCH START ====================
if (newTouchDown) {
vx = vy = 0;
rawVX = rawVY = 0;
glideActive = false;
lastX = x;
lastY = y;
return;
}
// ==================== DELTA & JUMP FILTER ====================
float dx = (float)(x - lastX);
float dy = (float)(y - lastY);
// If the movement is over 1000 units (1/8th of the pad), we assume it's a glitch.
if (abs(dx) > 1000 || abs(dy) > 1000) {
lastX = x;
lastY = y;
dx = 0;
dy = 0;
}
// ==================== DEADZONE ====================
float mag = sqrtf(dx*dx + dy*dy);
if (mag < 1.0f) {
dx = 0;
dy = 0;
}
// ==================== DPI / SPEED ====================
mouseSpeed = dpiPending;
// ==================== TOUCH MOVEMENT ====================
if (touchDown) {
rawVX = dx * 0.22f;
rawVY = dy * 0.22f;
vx = (vx * (1.0f - smoothFactor)) + (rawVX * smoothFactor);
vy = (vy * (1.0f - smoothFactor)) + (rawVY * smoothFactor);
float moveX = vx * mouseSpeed;
float moveY = vy * mouseSpeed;
fracX += moveX;
fracY += moveY;
int mvx = (int)fracX;
int mvy = (int)fracY;
// precision clamp
float speed = sqrtf(vx*vx + vy*vy);
bool precisionMode = (speed < 1.2f);
if (precisionMode) {
if (abs(mvx) > 1) mvx = (mvx > 0) ? 1 : -1;
if (abs(mvy) > 1) mvy = (mvy > 0) ? 1 : -1;
}
fracX -= mvx;
fracY -= mvy;
if (mvx != 0 || mvy != 0) {
// bleMouse.move(mvx, mvy);
if (bleConnected) bleMouse.move(mvx, mvy);
float tickInterval = constrain(40.0f - (speed * 3.0f), 8.0f, 40.0f);
if (millis() >= nextMoveTickTime) {
hapticsPulseMove();
nextMoveTickTime = millis() + tickInterval;
}
}
}
// ==================== GLIDE SEED ====================
if (newTouchUp) {
float speed = sqrtf(vx*vx + vy*vy);
if (speed < 0.25f) {
glideActive = false;
} else {
float scale = constrain(speed * 0.55f, 0.0f, 4.0f);
glideVX = vx * scale;
glideVY = vy * scale;
glideActive = true;
}
}
// ==================== GLIDE ====================
if (!touchDown && glideActive) {
glideVX *= friction;
glideVY *= friction;
float gSpeed = sqrtf(glideVX*glideVX + glideVY*glideVY);
if (gSpeed < minGlideSpeed) {
glideActive = false;
} else {
float moveGX = glideVX * mouseSpeed;
float moveGY = glideVY * mouseSpeed;
fracX += moveGX;
fracY += moveGY;
int gdx = (int)fracX;
int gdy = (int)fracY;
// same precision clamp for glide
bool precisionMode = (gSpeed < 1.2f);
if (precisionMode) {
if (abs(gdx) > 1) gdx = (gdx > 0) ? 1 : -1;
if (abs(gdy) > 1) gdy = (gdy > 0) ? 1 : -1;
}
fracX -= gdx;
fracY -= gdy;
if (gdx != 0 || gdy != 0) {
bleMouse.move(gdx, gdy);
float tickInterval = constrain(40.0f - (gSpeed * 3.0f), 8.0f, 40.0f);
if (millis() >= nextMoveTickTime) {
hapticsPulseMove();
nextMoveTickTime = millis() + tickInterval;
}
hapticsUpdate();
// ==================== NON-BLOCKING WEB SERVER ====================
static unsigned long lastServerTime = 0;
if (millis() - lastServerTime > 15) { // run at ~66Hz max
server.handleClient();
lastServerTime = millis();
}
}
}
}
lastX = x;
lastY = y;
}
Posted Apr 3, 2026, 4:44 PM UTC
16