关于如何实现按键长按短按不同功能代码

运行环境vscode+platformio+arduino框架+esp32s3

#include <Arduino.h>

#include <Ticker.h>	//滴答时钟,这个是esp32自有库
Ticker key_tick;

// put function declarations here:
#define KEY_8   18 	//按键引脚
#define LED     9		//led引脚

#define BUTTON_8      digitalRead(KEY_8)	//读取按键状态

#define NO_KEY_PRES 0		//没有按下状态
#define delay_time 300		//延时300ms
#define short_press_time 10     //短按时间
#define long_press_time 1000    //长按时间

#define KEY8_KEY_PRES 8
#define KEY8_LONG_PRES 80
bool KEY8_UP = 0;
uint8_t KEY8_KEY_READ = 0;
uint16_t KEY8_PRESS_COUNT = 0;


void LED_ON(){
  digitalWrite(LED, LOW);
}

void LED_OFF(){
  digitalWrite(LED, HIGH);
}

void detection(){
    if (BUTTON_8 == 0) {//按键是按下时引脚下拉为0
    KEY8_PRESS_COUNT++;//每ms加1
    KEY8_UP = 1;
    if (KEY8_PRESS_COUNT <= short_press_time)//按下小于10ms,就相当于没按
      KEY8_KEY_READ = NO_KEY_PRES;
    if (KEY8_PRESS_COUNT >= short_press_time && KEY8_PRESS_COUNT <= long_press_time)//按下在10ms到1000ms之间认为短按
      KEY8_KEY_READ = KEY8_KEY_PRES;
    if (KEY8_PRESS_COUNT >= long_press_time)//按下超过1000ms认为长按  
      KEY8_KEY_READ = KEY8_LONG_PRES;
  }
  if (BUTTON_8) {
    KEY8_PRESS_COUNT = 0;
    KEY8_UP = 0;//按键状态,0为弹起,1为按下
  }
  
  if (KEY8_KEY_READ == KEY8_KEY_PRES && KEY8_UP == 0) {	//当短按并且按键回弹时,灯打开
      LED_ON();
    KEY8_KEY_READ = NO_KEY_PRES;
  }//短按
    if (KEY8_KEY_READ == KEY8_LONG_PRES && KEY8_UP == 0) {	//当长按并且按键回弹时,灯关闭
      LED_OFF();
    KEY8_KEY_READ = NO_KEY_PRES;
  }//长按
}



void setup() {
  Serial0.begin(115200); 
  pinMode(LED, OUTPUT);
  key_tick.attach_ms(1, detection);//初始化时钟后会每隔1ms运行一次detection()
}

void loop() {
}


用简单的代码即可实现长按关灯,短按开灯

### ESP32 Arduino 实现按键短按 为了实现在ESP32上的按键按和短按功能,可以利用Arduino框架下的GPIO中断机制配合延时判断来区分不同的按下事件。下面是一个具体的实现方案。 #### GPIO设置与回调注册 首先需要设定好要监听的按键所对应的GPIO引脚模式,并为其绑定一个外部中断服务函数(ISR),该ISR会在每次检测到电平变化时被触发[^2]。 ```cpp const int buttonPin = 0; // 定义使用的按键引脚编号为GPIO0 volatile bool isPressed = false; unsigned long pressTime; void setup() { pinMode(buttonPin, INPUT_PULLUP); attachInterrupt(digitalPinToInterrupt(buttonPin), handleButtonPress, FALLING); } // 中断处理程序 void handleButtonPress(){ isPressed = true; pressTime = millis(); } ``` #### 主循环逻辑分析 在`loop()`函数内部持续监测全局变量的状态标志位`isPressed`,一旦发现其变为真则进一步考察自上次记录的时间戳至今已经过去了多久,以此决定当前操作应视为“短按”还是“按”。需要注意的是,在完成一次完整的点击判定之后应当重置状态以便下一轮交互正常工作[^1]。 ```cpp void loop() { if(isPressed){ unsigned long interval = millis()-pressTime; if(interval >= 1000){ // 如果超过一秒认为是按 Serial.println("Long Press"); isPressed=false; }else{ delay(50); // 延迟一小段时间防止误判 if(!digitalRead(buttonPin)){ // 再次确认确实处于释放状态 Serial.print("Short Press after "); Serial.print(interval); Serial.println(" ms."); while (!digitalRead(buttonPin)){} // 等待松开 isPressed=false; } } } } ``` 此段代码展示了基本思路,实际应用中可能还需要考虑更多细节比如去抖动等问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值