Support 3-pin button module (VCC/GND/OUT) with auto polarity.

Sample idle level at boot; OUT on GPIO22, no internal pull fight.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-10-23 12:48:45 +08:00
parent 280c5ea97c
commit 7459f9bde1
9 changed files with 62 additions and 48 deletions

View File

@@ -1,31 +1,30 @@
# 轻触开关计数(CYD)
# 三脚按键模块计数(CYD)
触控 + LVGL 参考 `hw269test`。GPIO22 读 **轻触带帽开关**:每按一次,屏幕计数 +1。
GPIO22 读三脚轻触按键模块:每按一次,屏幕计数 +1。
## 硬件
| 项目 | 说明 |
|------|------|
| 板子 | CYD ESP32-2432S028R |
| 开关 | 轻触开关(带帽),瞬时闭合 |
| 引脚 | **GPIO22** |
| 模块 | 三脚轻触按键(VCC / GND / OUT) |
| 输出 | **GPIO22** |
### 接线(重要)
### 接线
```
GPIO22 ── 开关一脚
GND ── 开关另一脚
```
| 模块 | CYD |
|------|-----|
| VCC / 3.3V | **3.3V** |
| GND | **GND** |
| OUT / S / DO | **GPIO22** |
- 不要接 3.3V / VCC
- **四脚轻触**:矩形四脚中,同侧两脚内部常通;要接 **对角** 或 **能通断的一对**,不要接已经常通的那一对
- 固件内部上拉:松开=HIGH,按下=LOW
开机自动采空闲电平,反相视为按下(兼容「按下变高」或「按下变低」)。
屏上会显示 `GPIO22: HIGH/LOW`:按下应变为 **LOW**;若一直 HIGH,多半是接线或脚对选错。
屏上 `OUT HIGH/LOW` 与 `act=`:按下时 OUT 应变到 `act` 那一侧并 +1。
## 操作
- 按一下开关:计数 +1
- 按一下:计数 +1(上电时请勿按住)
- 触控 **Reset**:清零
## 构建
@@ -33,10 +32,3 @@ GND ── 开关另一脚
```bash
pio run -e cyd -t upload
```
预编译:
```powershell
cd firmware\cyd
.\flash.ps1
```

View File

@@ -1,8 +1,8 @@
name: CYD Button (cyd)
git: 2d1d49c
git: 280c5ea
date: 2026-10-23
board: ESP32-2432S028R (ILI9341)
features: SoftSPI touch, LVGL, button SIG on GPIO22 count+1
features: SoftSPI touch, LVGL, 3-pin button OUT on GPIO22 count+1
flash_size: 4MB
offsets:
0x1000 bootloader.bin
@@ -12,5 +12,5 @@ offsets:
sha256:
bootloader.bin 3D234A7471F67B013686DABD4DEE7C1FA915C9928463616A94BC9297ACF1ABF8
boot_app0.bin F94C5D786A7A8FAB06AC5D10E33BF37711A6697636DC037559EA19CC410A17F0
firmware.bin B57118B1598F34B9737625C04E1EEB6C88395C639017288D69A6AB1BEC0C633C
firmware.bin BFCAD59431009CF5930B228CA7D6E3DE24C5FD2587690D131F770070EC8C604D
partitions.bin 148B959CBFF1C38AA8E1D5C0BA9D612C54997B945E56A63F41223EEF650653A1

Binary file not shown.

View File

@@ -1,7 +1,7 @@
{
"boardId": "esp32-2432s028",
"name": "CYD Button",
"summary": "Button on GPIO22: each press increments on-screen count",
"description": "SoftSPI touch + LVGL. SIG->GPIO22 INPUT_PULLUP. Press +1, touch Reset clears.",
"summary": "3-pin button module on GPIO22: each press increments count",
"description": "SoftSPI touch + LVGL. VCC/GND/OUT->GPIO22. Auto polarity. Press +1, touch Reset clears.",
"tags": ["button", "gpio22", "touch", "lvgl", "counter"]
}

View File

@@ -41,7 +41,7 @@ $lines = @(
"git: $git",
"date: $date",
"board: ESP32-2432S028R (ILI9341)",
"features: SoftSPI touch, LVGL, button SIG on GPIO22 count+1",
"features: SoftSPI touch, LVGL, 3-pin button OUT on GPIO22 count+1",
"flash_size: 4MB",
"offsets:",
" 0x1000 bootloader.bin",

View File

@@ -8,5 +8,7 @@ bool button_poll_press();
uint32_t button_count();
void button_reset_count();
bool button_is_down();
/** 原始电平:1=HIGH,0=LOW(便于接线排查) */
/** 原始电平:1=HIGH,0=LOW */
int button_raw_level();
/** 按下时的有效电平:1=HIGH 有效,0=LOW 有效(开机按空闲电平自动判定) */
int button_active_level();

View File

@@ -10,7 +10,7 @@
#define CYD_TOUCH_CLK 25
#define CYD_TOUCH_CS 33
// 轻触开关:一脚 → GPIO22,另一脚 → GND(内部上拉,按下为 LOW)
// 三脚按键模块 OUT/S → GPIO22(VCC→3.3V,GND→GND)
#define BTN_PIN 22
#define SCREEN_WIDTH 240

View File

@@ -3,27 +3,44 @@
#include <Arduino.h>
// 轻触开关:一端 → GPIO22,另一端 → GND(内部上拉,按下=LOW)
// 三脚按键模块:VCC→3.3V,GND→GND,OUT/S→GPIO22
// 开机采样空闲电平,反相即为“按下”(兼容按下拉高 / 按下拉低两种模块)
static uint32_t g_count = 0;
static bool g_stable_down = false;
static int g_stable_raw = HIGH;
static int g_stable_raw = LOW;
static int g_active_level = HIGH; // 按下时期望电平
static uint32_t g_change_ms = 0;
static int g_pending_raw = HIGH;
static int g_pending_raw = LOW;
static bool g_pending = false;
static constexpr uint32_t DEBOUNCE_MS = 25;
static constexpr uint32_t DEBOUNCE_MS = 30;
static bool raw_is_down(int raw) { return raw == g_active_level; }
void button_init() {
pinMode(BTN_PIN, INPUT_PULLUP);
delay(5);
g_count = 0;
g_stable_raw = digitalRead(BTN_PIN);
g_stable_down = (g_stable_raw == LOW);
// 模块自带上下拉,不要用内部上拉去顶它
pinMode(BTN_PIN, INPUT);
delay(30);
int high_n = 0;
for (int i = 0; i < 20; 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_stable_down = false;
g_pending = false;
g_pending_raw = g_stable_raw;
g_pending_raw = idle;
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");
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");
}
bool button_poll_press() {
@@ -38,12 +55,12 @@ bool button_poll_press() {
} else if ((now - g_change_ms) >= DEBOUNCE_MS) {
g_stable_raw = g_pending_raw;
g_pending = false;
const bool down = (g_stable_raw == LOW);
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=%d\n", (unsigned long)g_count,
g_stable_raw);
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;
@@ -65,3 +82,5 @@ void button_reset_count() {
bool button_is_down() { return g_stable_down; }
int button_raw_level() { return digitalRead(BTN_PIN); }
int button_active_level() { return g_active_level; }

View File

@@ -42,9 +42,10 @@ void ui_refresh_count() {
}
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_label_set_text_fmt(lbl_raw, "OUT %s act=%s", lv ? "HIGH" : "LOW",
button_active_level() ? "HIGH" : "LOW");
lv_obj_set_style_text_color(lbl_raw,
lv_color_hex(lv ? COL_MUTED : 0x3DDC97), 0);
lv_color_hex(lv ? 0x3DDC97 : COL_MUTED), 0);
}
}
@@ -68,7 +69,7 @@ void ui_create() {
lv_obj_align(lbl_title, LV_ALIGN_TOP_MID, 0, 4);
lbl_pin = lv_label_create(scr);
lv_label_set_text_fmt(lbl_pin, "IO%d <-> switch <-> GND", BTN_PIN);
lv_label_set_text_fmt(lbl_pin, "OUT->GPIO%d VCC 3.3V", 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, 36);
@@ -92,7 +93,7 @@ void ui_create() {
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_label_set_text(lbl_raw, "OUT --");
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);