这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 电子DIY » DIY-电子测光表-基础任务-按键检测

共1条 1/1 1 跳转至

DIY-电子测光表-基础任务-按键检测

菜鸟
2024-11-08 19:01:19     打赏


背景

Adafruit Feather ESP32-S3 TFT 开发板板载两个按键:

- Reset 按键:按下就会导致开发板复位,无需检测;

- Boot 按键:连接到 GPIO0,程序可以检测到。





从下面的原理图得知,BOOT 按键没有按下时是高电平,按下时为低电平。


Pasted image 20241108180457-boot-pin-原理图.png


基础按键检测

按键对应的管脚配置为 INPUT_PULLUP;

按键检测通过读取管脚电平,如果是 LOW 表示按键按下,如果是 HIGH 表示按键释放;

高级按键检测

引用 Bounce2 按键检测库,可以实现消抖检测按键,并设置消抖时间。

一般的使用流程如下:

1. 初始化全局变量 Bounce boot_btn = Bounce() 创建一个按键对象;

2. 调用 boot_btn.attach(pin, mode) 绑定按键对应的管脚并设置管脚上下拉模式;

3. 调用 boot_btn.interval(ms) 设置消抖时间;

4. 在 loop() 中周期性调用 boot_btn.update() 更新按键状态;

5. 在需要读取按键状态的代码位置调用 boot_btn.chagned() 判断状态是否发生改变,调用 boot_btn.read() 读取按键状态,按下还是释放;

我的按键检测示例

检测 BOOT 按键状态,只有当按键释放时切换 LED 状态,即每释放一次按键点亮/熄灭一次 LED。


演示视频:

【电子测光笔DIY--板载BOOT按键检测】 https://www.bilibili.com/video/BV1g7DZYLEpK/?share_source=copy_web&vd_source=a96f26eed24136ca40c5afd28478f4f8


源码如下:

// SPDX-FileCopyrightText: 2022 Limor Fried for Adafruit Industries
//
// SPDX-License-Identifier: MIT

/* Includes
 * --------------------------------------------------------------------------------------*/

#include <Arduino.h>

#include "Adafruit_LC709203F.h" /* 电池管理 -- 未检测到  */
#include "Adafruit_MAX1704X.h"  /* 电池管理 -- 当前板载的 */

#include <Adafruit_NeoPixel.h>
#include <Adafruit_ST7789.h>
#include <Fonts/FreeSans12pt7b.h>
#include <Bounce2.h> /* 按键检测 */

/* Constants -------------------------------------------------------------------------------------*/

#define LCD_WIDTH      240 /* 显示屏宽度 240 像素 */
#define LCD_HEIGHT     135 /* 显示屏高度 135 像素 */

/**
 * @brief boot 按键的管脚
 */
#define BOOT_BTN_PIN   0

/**
 * @brief 内置的 LED 管脚
 */
#define LED_PIN        LED_BUILTIN

/* Variables
 * -------------------------------------------------------------------------------------*/

/* 电池管理器,硬件对象 */
Adafruit_LC709203F lc_bat;
bool lc_bat_found = false;

/* 电池管理器,硬件对象 */
Adafruit_MAX17048 max_bat;
bool max_bat_found = false;

/* 显示屏,硬件对象 */
Adafruit_ST7789 display = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST);

/* 软件对象,画布:现在画布绘画,最后必须刷新到显示屏对象上 */
GFXcanvas16 canvas(LCD_WIDTH, LCD_HEIGHT); /* 这里仅分配一块连续的内存地址 */

/**
 * @brief 定义 Boot 按键对象
 */
Bounce boot_btn = Bounce();

uint8_t led_status = 0; /* LED 状态:点亮还是熄灭 */

uint8_t loop_cnt = 0;

/* Function Declarations
 * -----------------------------------------------------------------------------------------------*/

/**
 * @brief 按键硬件初始化、对象初始化
 */
void btn_init(void)
{
    pinMode(BOOT_BTN_PIN, INPUT_PULLUP); /* 按键硬件初始化,输入上拉模式 */
    boot_btn.attach(BOOT_BTN_PIN); /* 按键对象绑定到硬件 */
    boot_btn.interval(10); /* 设置按键消抖时间 */
}

void led_init(void)
{
    pinMode(LED_PIN, OUTPUT);
    digitalWrite(LED_PIN, led_status);

    pinMode(NEOPIXEL_POWER, OUTPUT);
    digitalWrite(NEOPIXEL_POWER, HIGH);
}

/**
 * @brief 显示屏初始化,整屏刷新为黑色
 *
 * @param
 */
void screen_init(void)
{
    /* turn on the TFT / I2C power supply */
    pinMode(TFT_I2C_POWER, OUTPUT); /* 这个管脚是必须拉高的 */
    digitalWrite(TFT_I2C_POWER, HIGH);

    /* 因为这里旋转了屏幕的方向,所以初始化的屏幕尺寸和实际使用的尺寸颠倒了 */
    display.init(LCD_HEIGHT, LCD_WIDTH); // Init ST7789 240x135
    display.setRotation(3);

    canvas.setFont(&FreeSans12pt7b);
    canvas.setTextColor(ST77XX_WHITE);

    canvas.fillScreen(ST77XX_BLACK);
    canvas.setCursor(0, 25);
    canvas.setTextColor(ST77XX_RED);
    canvas.println("Adafruit Feather");

    canvas.setTextColor(ST77XX_YELLOW);
    canvas.println("ESP32-S3 TFT Demo");

    /* 最后必须调用 display.drawRGBBitmap() 方法来刷新屏幕 */
    display.drawRGBBitmap(0, 0, canvas.getBuffer(), LCD_WIDTH, LCD_HEIGHT);
    pinMode(TFT_BACKLITE, OUTPUT);
    digitalWrite(TFT_BACKLITE, HIGH);
}


void battery_monitor_init(void)
{
    /* 初始化电池检测 */

    if (lc_bat.begin()) { /* LC709X not found */
        Serial.println("Found LC709203F");
        Serial.print("Version: 0x");
        Serial.println(lc_bat.getICversion(), HEX);
        lc_bat.setPackSize(LC709203F_APA_500MAH);
        lc_bat_found = true;
    } else {
        Serial.println(F(
            "Couldnt find Adafruit LC709203F?\nChecking for Adafruit MAX1704X.."));
        delay(200);

        if (!max_bat.begin()) {
            Serial.println(F("Couldnt find Adafruit MAX1704X?\nMake sure a battery "
                             "is plugged in!"));
            while (1)
                delay(10);
        }
        Serial.print(F("Found MAX17048"));
        Serial.print(F(" with Chip ID: 0x"));
        Serial.println(max_bat.getChipID(), HEX);
        max_bat_found = true;
    }

    canvas.setTextColor(ST77XX_GREEN);
    canvas.print("Battery: ");

    canvas.setTextColor(ST77XX_WHITE);
    if (lc_bat_found == true) {
        canvas.print(lc_bat.cellVoltage(), 1);
        canvas.print(" V  /  ");
        canvas.print(lc_bat.cellPercent(), 0);
        canvas.println("%");
    } else {
        canvas.print(max_bat.cellVoltage(), 1);
        canvas.print(" V  /  ");
        canvas.print(max_bat.cellPercent(), 0);
        canvas.println("%");
    }

    canvas.setTextColor(ST77XX_BLUE);
    canvas.print("Battery: ");
    canvas.setTextColor(ST77XX_WHITE);
    if (lc_bat_found) {
        canvas.println("LC709X");
    } else if (max_bat_found) {
        canvas.println("MAX170X");
    } else {
        canvas.println("unknown");
    }

    /* 最后必须调用 display.drawRGBBitmap() 方法来刷新屏幕 */
    display.drawRGBBitmap(0, 0, canvas.getBuffer(), LCD_WIDTH, LCD_HEIGHT);
}

/**
 * @brief 在新的界面上显示按键是否按下
 *
 * @param isPressed
 */
void screen_button_status(bool isPressed)
{
    canvas.fillScreen(ST77XX_BLACK);
    canvas.setCursor(0, 25);

    canvas.setTextColor(ST77XX_BLUE);
    canvas.print("Button: ");

    canvas.setTextColor(ST77XX_YELLOW);
    if(isPressed) {
        canvas.println("Pressed");
    } else {
        canvas.println("Released");
    }
    display.drawRGBBitmap(0, 0, canvas.getBuffer(), LCD_WIDTH, LCD_HEIGHT);
}

/**
 * @brief 在主循环中调用此函数
 *
 * @param
 */
void btn_process(void)
{
    /* 在此更新所有的按键状态 */
    boot_btn.update();

    if (boot_btn.changed())  { /* 按键状态变化了 */
        if (boot_btn.read()) { /* 高电平表示按键释放 */
            led_status = !led_status;
            screen_button_status(false);
        } else { /* 低电平表示按键按下 */
            screen_button_status(true);
        }
    }

    digitalWrite(LED_PIN, led_status);
}

/* Function Implementations
 * ----------------------------------------------------------------------*/


void setup()
{
    Serial.begin(115200);
    uint32_t wait_cnt = 5;
    while (!Serial && (wait_cnt-- > 0)) { /* 等待串口软件连接 */
        delay(1000);
    }

    // delay(3000);
    Serial.println("Adafruit Feather ESP32-S3 TFT");
    Serial.println("Build: " + String(__DATE__) + " " + String(__TIME__));

    screen_init();
    btn_init();
    led_init();
    battery_monitor_init();

    delay(10);
}

void loop()
{
    btn_process();

    loop_cnt++;
    delay(10);
}




共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]