diff --git a/README.md b/README.md index c22e7de..b7a70cd 100644 --- a/README.md +++ b/README.md @@ -1,22 +1,32 @@ -# 按钮计数(CYD) +# 轻触开关计数(CYD) -触控 + LVGL 参考 `hw269test` / `tftest`。GPIO22 读按钮:每按一次,屏幕计数 +1。 +触控 + LVGL 参考 `hw269test`。GPIO22 读 **轻触带帽开关**:每按一次,屏幕计数 +1。 ## 硬件 | 项目 | 说明 | |------|------| | 板子 | CYD ESP32-2432S028R | -| 模块 | 轻触按钮 / 按键传感器(SIG 输出) | -| 信号 | **GPIO22**(内部上拉,按下为 LOW) | +| 开关 | 轻触开关(带帽),瞬时闭合 | +| 引脚 | **GPIO22** | -接线:`VCC→3.3V`,`GND→GND`,`SIG→GPIO22`。 +### 接线(重要) + +``` +GPIO22 ── 开关一脚 +GND ── 开关另一脚 +``` + +- 不要接 3.3V / VCC +- **四脚轻触**:矩形四脚中,同侧两脚内部常通;要接 **对角** 或 **能通断的一对**,不要接已经常通的那一对 +- 固件内部上拉:松开=HIGH,按下=LOW + +屏上会显示 `GPIO22: HIGH/LOW`:按下应变为 **LOW**;若一直 HIGH,多半是接线或脚对选错。 ## 操作 -- 按一下物理按钮:计数 +1 -- 屏幕显示当前计数与 PRESSED / IDLE -- 触控 **Reset**:计数清零 +- 按一下开关:计数 +1 +- 触控 **Reset**:清零 ## 构建 @@ -24,12 +34,9 @@ pio run -e cyd -t upload ``` -预编译包: +预编译: ```powershell cd firmware\cyd .\flash.ps1 -# 或 .\flash.ps1 -Port COMx ``` - -更新预编译包:`.\firmware\export_from_build.ps1` diff --git a/firmware/cyd/VERSION.txt b/firmware/cyd/VERSION.txt index e94291f..de9a100 100644 --- a/firmware/cyd/VERSION.txt +++ b/firmware/cyd/VERSION.txt @@ -1,5 +1,5 @@ name: CYD Button (cyd) -git: 22a3c46 +git: 2d1d49c date: 2026-10-23 board: ESP32-2432S028R (ILI9341) features: SoftSPI touch, LVGL, button SIG on GPIO22 count+1 @@ -12,5 +12,5 @@ offsets: sha256: bootloader.bin 3D234A7471F67B013686DABD4DEE7C1FA915C9928463616A94BC9297ACF1ABF8 boot_app0.bin F94C5D786A7A8FAB06AC5D10E33BF37711A6697636DC037559EA19CC410A17F0 - firmware.bin 66E2CE73AA8F010E314CE1B9664106250DD07D92B726DEF592FE123C5FC2F88A + firmware.bin B57118B1598F34B9737625C04E1EEB6C88395C639017288D69A6AB1BEC0C633C partitions.bin 148B959CBFF1C38AA8E1D5C0BA9D612C54997B945E56A63F41223EEF650653A1 diff --git a/firmware/cyd/firmware.bin b/firmware/cyd/firmware.bin index e1bc025..1a07218 100644 Binary files a/firmware/cyd/firmware.bin and b/firmware/cyd/firmware.bin differ diff --git a/include/button.h b/include/button.h index beefb80..7b596da 100644 --- a/include/button.h +++ b/include/button.h @@ -8,3 +8,5 @@ bool button_poll_press(); uint32_t button_count(); void button_reset_count(); bool button_is_down(); +/** 原始电平:1=HIGH,0=LOW(便于接线排查) */ +int button_raw_level(); diff --git a/include/pins.h b/include/pins.h index ae75a25..35b9c4c 100644 --- a/include/pins.h +++ b/include/pins.h @@ -10,7 +10,7 @@ #define CYD_TOUCH_CLK 25 #define CYD_TOUCH_CS 33 -// 按钮传感器 SIG → GPIO22(内部上拉,按下为 LOW) +// 轻触开关:一脚 → GPIO22,另一脚 → GND(内部上拉,按下为 LOW) #define BTN_PIN 22 #define SCREEN_WIDTH 240 diff --git a/src/button.cpp b/src/button.cpp index e7891fe..0678d5a 100644 --- a/src/button.cpp +++ b/src/button.cpp @@ -3,46 +3,56 @@ #include +// 轻触开关:一端 → GPIO22,另一端 → GND(内部上拉,按下=LOW) + static uint32_t g_count = 0; static bool g_stable_down = false; -static bool g_last_raw = false; -static uint32_t g_last_change_ms = 0; -static constexpr uint32_t DEBOUNCE_MS = 40; +static int g_stable_raw = HIGH; +static uint32_t g_change_ms = 0; +static int g_pending_raw = HIGH; +static bool g_pending = false; +static constexpr uint32_t DEBOUNCE_MS = 25; void button_init() { pinMode(BTN_PIN, INPUT_PULLUP); + delay(5); g_count = 0; - g_stable_down = false; - g_last_raw = (digitalRead(BTN_PIN) == LOW); - g_last_change_ms = millis(); - Serial.printf("Button GPIO%d INPUT_PULLUP (press=LOW)\n", BTN_PIN); + g_stable_raw = digitalRead(BTN_PIN); + g_stable_down = (g_stable_raw == LOW); + g_pending = false; + g_pending_raw = g_stable_raw; + g_change_ms = millis(); + Serial.printf("Button tactile GPIO%d pullup, idle=%s (wire other side to GND)\n", + BTN_PIN, g_stable_raw == HIGH ? "HIGH" : "LOW"); } bool button_poll_press() { - const bool raw_down = (digitalRead(BTN_PIN) == LOW); + const int raw = digitalRead(BTN_PIN); const uint32_t now = millis(); - if (raw_down != g_last_raw) { - g_last_raw = raw_down; - g_last_change_ms = now; + 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 = (g_stable_raw == LOW); + if (down && !g_stable_down) { + g_stable_down = true; + g_count++; + Serial.printf("Button press count=%lu raw=%d\n", (unsigned long)g_count, + g_stable_raw); + return true; + } + g_stable_down = down; + } + } else { + g_pending = false; } - if ((now - g_last_change_ms) < DEBOUNCE_MS) { - return false; - } - - if (raw_down == g_stable_down) { - return false; - } - - g_stable_down = raw_down; - if (!g_stable_down) { - return false; // 只计按下边沿 - } - - g_count++; - Serial.printf("Button press count=%lu\n", (unsigned long)g_count); - return true; + return false; } uint32_t button_count() { return g_count; } @@ -53,3 +63,5 @@ void button_reset_count() { } bool button_is_down() { return g_stable_down; } + +int button_raw_level() { return digitalRead(BTN_PIN); } diff --git a/src/main.cpp b/src/main.cpp index 86b5a26..6502bc1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -14,7 +14,7 @@ void setup() { Serial.begin(460800); delay(200); Serial.println(); - Serial.printf("LVGL %d.%d.%d | Button sensor GPIO%d\n", lv_version_major(), + Serial.printf("LVGL %d.%d.%d | Tactile button GPIO%d\n", lv_version_major(), lv_version_minor(), lv_version_patch(), BTN_PIN); Serial.println("BOOT_OK"); @@ -39,16 +39,16 @@ void setup() { } void loop() { - if (button_poll_press()) { + const bool pressed = button_poll_press(); + + static bool last_down = false; + static int last_raw = -1; + const bool down = button_is_down(); + const int raw = button_raw_level(); + if (pressed || down != last_down || raw != last_raw) { + last_down = down; + last_raw = raw; ui_refresh_count(); - } else { - // 按下/松开时刷新状态字,但不重复计数 - static bool last_down = false; - const bool down = button_is_down(); - if (down != last_down) { - last_down = down; - ui_refresh_count(); - } } lv_timer_handler(); diff --git a/src/ui.cpp b/src/ui.cpp index a5d5e8c..ddebe01 100644 --- a/src/ui.cpp +++ b/src/ui.cpp @@ -17,6 +17,7 @@ static lv_obj_t *lbl_pin; static lv_obj_t *lbl_count; static lv_obj_t *lbl_hint; static lv_obj_t *lbl_state; +static lv_obj_t *lbl_raw; static lv_obj_t *btn_reset; static lv_obj_t *lbl_reset; @@ -39,6 +40,12 @@ void ui_refresh_count() { lv_obj_set_style_text_color(lbl_state, lv_color_hex(down ? 0x3DDC97 : COL_MUTED), 0); } + if (lbl_raw) { + const int lv = button_raw_level(); + lv_label_set_text_fmt(lbl_raw, "GPIO%d: %s", BTN_PIN, lv ? "HIGH" : "LOW"); + lv_obj_set_style_text_color(lbl_raw, + lv_color_hex(lv ? COL_MUTED : 0x3DDC97), 0); + } } static void on_reset(lv_event_t *e) { @@ -58,35 +65,41 @@ void ui_create() { lv_label_set_text(lbl_title, "Button"); lv_obj_set_style_text_color(lbl_title, lv_color_hex(COL_INK), 0); lv_obj_set_style_text_font(lbl_title, &lv_font_montserrat_28, 0); - lv_obj_align(lbl_title, LV_ALIGN_TOP_MID, 0, 6); + lv_obj_align(lbl_title, LV_ALIGN_TOP_MID, 0, 4); lbl_pin = lv_label_create(scr); - lv_label_set_text_fmt(lbl_pin, "SIG -> GPIO%d (press +1)", BTN_PIN); + lv_label_set_text_fmt(lbl_pin, "IO%d <-> switch <-> GND", BTN_PIN); lv_obj_set_style_text_color(lbl_pin, lv_color_hex(COL_MUTED), 0); lv_obj_set_style_text_font(lbl_pin, &lv_font_montserrat_14, 0); - lv_obj_align(lbl_pin, LV_ALIGN_TOP_MID, 0, 40); + lv_obj_align(lbl_pin, LV_ALIGN_TOP_MID, 0, 36); lbl_count = lv_label_create(scr); lv_label_set_text(lbl_count, "0"); lv_obj_set_style_text_color(lbl_count, lv_color_hex(COL_ACCENT), 0); lv_obj_set_style_text_font(lbl_count, &lv_font_montserrat_28, 0); - lv_obj_align(lbl_count, LV_ALIGN_TOP_MID, 0, 78); + lv_obj_align(lbl_count, LV_ALIGN_TOP_MID, 0, 68); lbl_hint = lv_label_create(scr); lv_label_set_text(lbl_hint, "count"); lv_obj_set_style_text_color(lbl_hint, lv_color_hex(COL_MUTED), 0); lv_obj_set_style_text_font(lbl_hint, &lv_font_montserrat_14, 0); - lv_obj_align(lbl_hint, LV_ALIGN_TOP_MID, 0, 116); + lv_obj_align(lbl_hint, LV_ALIGN_TOP_MID, 0, 104); lbl_state = lv_label_create(scr); lv_label_set_text(lbl_state, "IDLE"); lv_obj_set_style_text_color(lbl_state, lv_color_hex(COL_MUTED), 0); lv_obj_set_style_text_font(lbl_state, &lv_font_montserrat_20, 0); - lv_obj_align(lbl_state, LV_ALIGN_TOP_MID, 0, 142); + lv_obj_align(lbl_state, LV_ALIGN_TOP_MID, 0, 126); + + lbl_raw = lv_label_create(scr); + lv_label_set_text(lbl_raw, "GPIO22: HIGH"); + lv_obj_set_style_text_color(lbl_raw, lv_color_hex(COL_MUTED), 0); + lv_obj_set_style_text_font(lbl_raw, &lv_font_montserrat_14, 0); + lv_obj_align(lbl_raw, LV_ALIGN_TOP_MID, 0, 152); btn_reset = lv_button_create(scr); - lv_obj_set_size(btn_reset, UI_HOR_RES - 48, 48); - lv_obj_align(btn_reset, LV_ALIGN_TOP_MID, 0, 180); + lv_obj_set_size(btn_reset, UI_HOR_RES - 48, 44); + lv_obj_align(btn_reset, LV_ALIGN_TOP_MID, 0, 184); style_btn(btn_reset, COL_BTN); lv_obj_add_event_cb(btn_reset, on_reset, LV_EVENT_CLICKED, nullptr); lbl_reset = lv_label_create(btn_reset);