当前位置:   article > 正文

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

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
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;
  }
}



  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
bool MyTimingisOk(u32* lastTime,u16 setTime)
{
  if(millis()-*lastTime>setTime)
  {
    *lastTime=millis();
    return true;
  }
  return false;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

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

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

void loop()
{
  Get_TouchStatus();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/431318
推荐阅读
相关标签
  

闽ICP备14008679号