Arduino 触摸按键:实现单击,双击,长按功能,稳定无抖动。

实现思路:
由具体多次测试可得出不同的按键状态条件如下:

  1. 单击
    ① 产生一个下降沿(高电平 -> 低电平)
    ② 150ms 内没有再产生下降沿
  2. 双击
    ① 产生第一个下降沿(高电平 -> 低电平)
    ② 产生第二个下降沿:两个下降沿的间隔需要在150ms内,判断为双击,反之判断为单击。
  3. 长按
    ① 高电平持续时间 >700ms

要点:
双击判断时,第一次按下后,要及时设置标志位,排除单击情况并更新状态,反之立刻判断为单击更新按键状态。

Tips:
不同的实物按键可能具有不同的参数: 单击可产生(上升沿/下降沿)、两次跳变沿的间隔时间不同等等。

可自己根据你们的实际测试的按键参数进行参数修改

#ifndef TOUCH_H
#define TOUCH_H

#define TOUCH_PWR           32
#define TOUCH_PIN           15

enum
{
  None,
  ONE,
  DOUBLE,
  LONG,
};

u32 RisTime = 0;
u32 FalTime = 0;
u32 firstTouchTime = 0;
bool isDouble = 0;
bool isOne = 0;
int touchStatus = 0;

#endif
void Touch_init()
{
  /*Set touch Pin as input*/
  pinMode(TOUCH_PIN, INPUT);
  pinMode(TOUCH_PWR, PULLUP);
  digitalWrite(TOUCH_PWR, HIGH);
  attachInterrupt(digitalPinToInterrupt(TOUCH_PIN), TouchRising_ISR, RISING);
}

void TouchRising_ISR()
{
  if (isOne && millis() - firstTouchTime <= 150)
  {
    isOne = 0;
    isDouble = 1;
    touchStatus = 2;
    Serial.print("touchStatus:");
    Serial.println(touchStatus);
  }

  RisTime = millis();
  attachInterrupt(digitalPinToInterrupt(TOUCH_PIN), TouchFalling_ISR, FALLING);
}

void TouchFalling_ISR()
{
  u32 highLastTime = 0;
  FalTime = millis();
  highLastTime = FalTime - RisTime;
  
  if ( highLastTime > 700)
  {
    touchStatus = 3;
  }
  else if (isDouble)
  {
    isDouble = 0;
  }
  else
  {
    isOne = 1;
    firstTouchTime = millis();
  }
  attachInterrupt(digitalPinToInterrupt(TOUCH_PIN), TouchRising_ISR, RISING);
}

int Get_TouchStatus()
{
  static u32 timeStatus = 0;
  //10ms 执行一次按键扫描
  if (MyTimingisOk(&timeStatus, 10))
  {

    if (isOne && millis() - firstTouchTime > 150)
    {
      isDouble = 0;
      isOne = 0;
      touchStatus = 1;
    }

    switch (touchStatus)
    {
      case None:   /*按键无点击情况*/   break;
      case ONE:    /*按键单击情况*/     break;
      case DOUBLE: /*按键双击情况*/     break;
      case LONG:   /*按键长按情况*/     break;
    }
    touchStatus = 0;
  }
}



bool MyTimingisOk(u32* lastTime,u16 setTime)
{
  if(millis()-*lastTime>setTime)
  {
    *lastTime=millis();
    return true;
  }
  return false;
}

主循环中,10ms进行一次按键扫描(状态判定)

void setup() {
  Serial.begin(115200);
  Touch_init();
}

void loop()
{
  Get_TouchStatus();
}
  • 11
    点赞
  • 88
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论
实现按键按和短按功能可以通过软件延时和计时器实现。下面是一个示例代码,演示如何实现按键按和短按功能: ```C++ const int buttonPin = 2; // 按钮接口 int buttonState = HIGH; // 按钮状态 int lastButtonState = HIGH; // 上一次按钮状态 unsigned long lastDebounceTime = 0; // 上一次抖动时间 const int debounceDelay = 50; // 抖动延时 const int longPressDelay = 1000; // 按延时 bool longPress = false; // 是否按 unsigned long pressStartTime; // 按下按键开始计时 unsigned long pressEndTime; // 释放按键结束计时 void setup() { pinMode(buttonPin, INPUT_PULLUP); // 初始化按键接口 Serial.begin(9600); // 初始化串口通信 } void loop() { int reading = digitalRead(buttonPin); // 读取按钮状态 if (reading != lastButtonState) { // 抖动检测 lastDebounceTime = millis(); } if ((millis() - lastDebounceTime) > debounceDelay) { if (reading != buttonState) { // 按钮状态改变 buttonState = reading; if (buttonState == LOW) { // 按钮按下 pressStartTime = millis(); } else { // 按钮释放 pressEndTime = millis(); longPress = false; if ((pressEndTime - pressStartTime) > longPressDelay) { // 按 longPress = true; Serial.println("Long press!"); } else { // 短按 Serial.println("Short press!"); } } } } lastButtonState = reading; } ``` 这个代码使用 `digitalRead()` 函数读取按钮状态,并使用 `millis()` 函数计时。在按钮按下时,记录下按键开始计时的时间,当按钮释放时,记录下按键结束计时的时间,并计算出按键持续时间,如果持续时间超过设定的按延时,则判断为按。如果持续时间小于按延时,则判断为短按。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ou.cs

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值