Tune button feel: faster majority vote, idle pull, short lockout.

Snappier press detection without long-hold; reduces bounce chatter.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-10-23 12:51:15 +08:00
parent 7459f9bde1
commit 193ede4360
4 changed files with 71 additions and 45 deletions

View File

@@ -1,5 +1,5 @@
name: CYD Button (cyd)
git: 280c5ea
git: 7459f9b
date: 2026-10-23
board: ESP32-2432S028R (ILI9341)
features: SoftSPI touch, LVGL, 3-pin button OUT on GPIO22 count+1
@@ -12,5 +12,5 @@ offsets:
sha256:
bootloader.bin 3D234A7471F67B013686DABD4DEE7C1FA915C9928463616A94BC9297ACF1ABF8
boot_app0.bin F94C5D786A7A8FAB06AC5D10E33BF37711A6697636DC037559EA19CC410A17F0
firmware.bin BFCAD59431009CF5930B228CA7D6E3DE24C5FD2587690D131F770070EC8C604D
firmware.bin CE4D141B462731BC137E5793F055A5116A81F680DCA51D0F6A4E26F73E701F86
partitions.bin 148B959CBFF1C38AA8E1D5C0BA9D612C54997B945E56A63F41223EEF650653A1

Binary file not shown.

View File

@@ -3,70 +3,89 @@
#include <Arduino.h>
// 三脚按键模块:VCC→3.3V,GND→GND,OUT/S→GPIO22
// 开机采样空闲电平,反相即为“按下”(兼容按下拉高 / 按下拉低两种模块)
// 三脚按键模块:VCC→3.3V,GND→GND,OUT→GPIO22
// 短积分 + 多数表决:轻触更快;松开锁存防连跳
static uint32_t g_count = 0;
static bool g_stable_down = false;
static int g_stable_raw = LOW;
static int g_active_level = HIGH; // 按下时期望电平
static uint32_t g_change_ms = 0;
static int g_pending_raw = LOW;
static bool g_pending = false;
static constexpr uint32_t DEBOUNCE_MS = 30;
static int g_active_level = HIGH;
static int g_idle_level = LOW;
static int8_t g_score = 0;
static uint32_t g_lock_until_ms = 0;
static constexpr int8_t SCORE_MAX = 4;
static constexpr int8_t DOWN_TH = 2; // 约 2~3 次有效采样即算按下
static constexpr int8_t UP_TH = -2;
static constexpr uint32_t LOCKOUT_MS = 70; // 一次有效按下后忽略连跳
static bool raw_is_down(int raw) { return raw == g_active_level; }
static int read_majority() {
int high_n = 0;
for (int i = 0; i < 3; i++) {
if (digitalRead(BTN_PIN) == HIGH) {
high_n++;
}
delayMicroseconds(40);
}
return (high_n >= 2) ? HIGH : LOW;
}
void button_init() {
// 模块自带上下拉,不要用内部上拉去顶它
pinMode(BTN_PIN, INPUT);
delay(30);
delay(20);
int high_n = 0;
for (int i = 0; i < 20; i++) {
for (int i = 0; i < 30; i++) {
if (digitalRead(BTN_PIN) == HIGH) {
high_n++;
}
delay(2);
}
const int idle = (high_n >= 10) ? HIGH : LOW;
g_active_level = (idle == HIGH) ? LOW : HIGH;
g_stable_raw = idle;
g_idle_level = (high_n >= 15) ? HIGH : LOW;
g_active_level = (g_idle_level == HIGH) ? LOW : HIGH;
// 内部弱拉向空闲侧,压噪声、减轻“半按不稳”
if (g_idle_level == HIGH) {
pinMode(BTN_PIN, INPUT_PULLUP);
} else {
pinMode(BTN_PIN, INPUT_PULLDOWN);
}
g_stable_down = false;
g_pending = false;
g_pending_raw = idle;
g_change_ms = millis();
g_score = -SCORE_MAX;
g_lock_until_ms = 0;
g_count = 0;
Serial.printf(
"Button module GPIO%d INPUT idle=%s active=%s (VCC/GND/OUT)\n", BTN_PIN,
idle == HIGH ? "HIGH" : "LOW", g_active_level == HIGH ? "HIGH" : "LOW");
Serial.printf("Button GPIO%d idle=%s active=%s pull=%s\n", BTN_PIN,
g_idle_level == HIGH ? "HIGH" : "LOW",
g_active_level == HIGH ? "HIGH" : "LOW",
g_idle_level == HIGH ? "UP" : "DOWN");
}
bool button_poll_press() {
const int raw = digitalRead(BTN_PIN);
const int raw = read_majority();
if (raw_is_down(raw)) {
if (g_score < SCORE_MAX) {
g_score++;
}
} else if (g_score > -SCORE_MAX) {
g_score--;
}
const uint32_t now = millis();
if (raw != g_stable_raw) {
if (!g_pending || raw != g_pending_raw) {
g_pending = true;
g_pending_raw = raw;
g_change_ms = now;
} else if ((now - g_change_ms) >= DEBOUNCE_MS) {
g_stable_raw = g_pending_raw;
g_pending = false;
const bool down = raw_is_down(g_stable_raw);
if (down && !g_stable_down) {
g_stable_down = true;
g_count++;
Serial.printf("Button press count=%lu raw=%s\n", (unsigned long)g_count,
g_stable_raw == HIGH ? "HIGH" : "LOW");
return true;
}
g_stable_down = down;
if (!g_stable_down && g_score >= DOWN_TH) {
g_stable_down = true;
if (now >= g_lock_until_ms) {
g_count++;
g_lock_until_ms = now + LOCKOUT_MS;
Serial.printf("Button press count=%lu score=%d\n", (unsigned long)g_count,
(int)g_score);
return true;
}
} else {
g_pending = false;
} else if (g_stable_down && g_score <= UP_TH) {
g_stable_down = false;
}
return false;

View File

@@ -39,7 +39,14 @@ void setup() {
}
void loop() {
const bool pressed = button_poll_press();
// 每圈多采几次,轻触更快跟上
bool pressed = false;
for (int i = 0; i < 3; i++) {
if (button_poll_press()) {
pressed = true;
}
delayMicroseconds(200);
}
static bool last_down = false;
static int last_raw = -1;
@@ -52,6 +59,6 @@ void loop() {
}
lv_timer_handler();
lv_tick_inc(5);
delay(5);
lv_tick_inc(4);
delay(4);
}