Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/arduino/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Function 一个用于多个按钮的处理程序函数_Function_Arduino - Fatal编程技术网

Function 一个用于多个按钮的处理程序函数

Function 一个用于多个按钮的处理程序函数,function,arduino,Function,Arduino,我正在用两个按钮写一个简单的草图。为了处理按钮状态,我编写了一个名为changeButtonStatus(作为参数,我传递一个按钮pin)的函数,该函数返回一个事件编号: 0-没有单击 1-单击一次 2-双击 三长新闻 4-长按后发布 在主循环中,我为两个按钮中的每一个调用此函数,并使用Serial.println() 问题是我的草图只适用于一个按钮,而不适用于两个或更多按钮 这是我的密码: #包括 int-but1=3; int-but2=4; int eventBut1、eventBut

我正在用两个按钮写一个简单的草图。为了处理按钮状态,我编写了一个名为
changeButtonStatus
(作为参数,我传递一个按钮pin)的函数,该函数返回一个事件编号:

  • 0-没有单击
  • 1-单击一次
  • 2-双击
  • 三长新闻
  • 4-长按后发布
在主循环中,我为两个按钮中的每一个调用此函数,并使用
Serial.println()

问题是我的草图只适用于一个按钮,而不适用于两个或更多按钮

这是我的密码:

#包括
int-but1=3;
int-but2=4;
int eventBut1、eventBut2;
int currentButtonStatus=0;//0-按钮未按下
//1-第一次按下按钮
//2-按钮按下后释放
//3-第二次按下按钮
无符号长currentButtonStatusStart1;//状态更改为1时的毫秒数
无符号长currentButtonStatusStart2;//状态更改为2时的毫秒数
无符号长currentButtonStatusStart3;//状态更改为3时的毫秒数
常数int delayFalse=30;//如果该值小于30毫秒,则不记录一次按下
常量int delayLongSingleClick=400;//如果该值大于400毫秒,将重新注册长按
常量int delayDeltaDoubleClick=300;//延迟注册双时钟
无效设置(){
引脚模式(but1,输入);
pinMode(但是2,输入);
Serial.begin(9600);
}
void循环(){
eventBut1=changeButtonStatus(but1);//保持but1状态的变量(未按下、单按、双按、长按)
eventBut2=changeButtonStatus(but2);//保持but2状态的变量(未按、单按、双按、长按)
如果(eventBut1>0){
如果(eventBut1==1){Serial.println(“But1单击”);}
如果(eventBut1==4){Serial.println(“长按后释放But1”);}
}
如果(eventBut2>0){
如果(eventBut2==1){Serial.println(“But2单击”);}
如果(eventBut2==2){Serial.println(“But2双击”);}
}
}
/**
*更改当前按钮状态
*@return=0-未按下
*1-单击一次
*2-双击
*三长压力机
*4-长按后发布
*/
int changeButtonStatus(int butPin){
//事件
int事件=0;
//当前按钮状态
int currentButtonClick=数字读取(butPin);
//当前时间
无符号长时间按钮=毫秒();
开关(currentButtonStatus){
案例0:
//按钮还没有按下
如果(当前按钮单击){
//修复按钮单击
currentButtonStatus=1;
currentButtonStatusStart1=millis();
}否则{
//按钮未按下
}
打破
案例1:
//第一次按下按钮
如果(当前按钮单击){
//按钮仍然按下
如果(timeButton-currentButtonStatusStart1>=delayLongSingleClick){
//按钮长按状态
事件=3;
}
}否则{
//按钮已被释放
如果(时间按钮-currentButtonStatusStart1delayDeltaDoubleClick){
//按钮已释放太长时间,请单击修复
currentButtonStatus=0;
事件=1;
} 
}
打破
案例3:
//确认双击
如果(当前按钮单击){
//按钮仍然按下
//等待按钮释放
}否则{
//按钮已被释放
//检查有无脱盎司
如果(时间按钮-currentButtonStatusStart3

如果您能帮我找出问题所在,我将不胜感激。

我们可以看到一个问题,您与两个按钮共享一些全局变量:
currentButtonStatus,currentButtonStatus…

您不应该在更正中定义这些变量的另一组,您应该为按钮创建一个类,并在类中包含这些以前的全局变量

我已经写了这样的代码,很少有改动。 从这一点上,您可以改进并创建一个枚举,该枚举将替换事件按钮的常量0,1,2,3

请注意,我已经检查了我的修改是否编译,但我还没有使用真正的按钮进行测试

//#include <elapsedMillis.h>

int butPin1 = 3; 
int butPin2 = 4;

int eventBut1, eventBut2;

class ButtonStat {

  static const int delayFalse = 30;               // if the value is less than 30 milliseconds, one press is not registered 
  static const int delayLongSingleClick = 400;    // if the value is greater than 400 milliseconds, long press is reegistered 
  static const int delayDeltaDoubleClick = 300;   // delay to registere double clck        

  public:
  explicit ButtonStat(int pinBut): pin(pinBut),currentButtonStatus(0), currentButtonStatusStart1(0), 
           currentButtonStatusStart2(0), currentButtonStatusStart3(0)   {}
  int changeButtonStatus();
  int getPin() {return pin;}

  private:
  int pin;
  int currentButtonStatus;     // 0 - button is not pressed
                               // 1 - button is pressed for the first time
                               // 2 - button is released after being pressed
                               // 3 - button is pressed for the second time

  unsigned long currentButtonStatusStart1;  // number of milliseconds when the status has changed to 1 
  unsigned long currentButtonStatusStart2;  // number of milliseconds when the status has changed to 2    
  unsigned long currentButtonStatusStart3;  // number of milliseconds when the status has changed to 3 
}  ;

ButtonStat butt1 = ButtonStat(butPin1);
ButtonStat butt2 = ButtonStat(butPin2);

void setup() {
  pinMode (butt1.getPin(), INPUT);
  pinMode (butt2.getPin(), INPUT);
  Serial.begin(9600);
}

void loop() {
  eventBut1 = butt1.changeButtonStatus(); // variable to keep the state of but1 (not pressed, single press, double press, long press)
  eventBut2 = butt2.changeButtonStatus(); // variable to keep the state of but2 (not pressed, single press, double press, long press)

  if (eventBut1 > 0) {
      if (eventBut1 == 1) {Serial.println("But1 Single click");}
      if (eventBut1 == 4) {Serial.println("But1 is released after long press");}
    }

  if (eventBut2 > 0) {
      if (eventBut2 == 1) {Serial.println("But2 Single click");}
      if (eventBut2 == 2) {Serial.println("But2 Double press");}
    }
}

/**
 * Change current button status 
 * @return = 0 - not pressed
 *           1 - single click
 *           2 - double click
 *           3 - long press
 *           4 - released after long press
 */
int ButtonStat::changeButtonStatus() {
  // Event
  int event = 0;

  // Current button status
  int currentButtonClick = digitalRead(pin);

  // Current time 
  unsigned long timeButton = millis();

  switch(currentButtonStatus) {

    case 0:
      // button has not been pressed
      if(currentButtonClick) {
        // fix button click
        currentButtonStatus = 1;
        currentButtonStatusStart1 = millis(); 
      } else {
        // button is not pressed
      }
      break;

    case 1:
      // button is pressed for the first time
      if(currentButtonClick) {
        // button is still pressed
        if(timeButton - currentButtonStatusStart1 >= delayLongSingleClick) {
          // button long press state
          event = 3; 
        }

      } else {
        // button has been released
        if(timeButton - currentButtonStatusStart1 < delayFalse) {
          currentButtonStatus = 0;
          event = 0;
        } else if(timeButton - currentButtonStatusStart1 < delayLongSingleClick) {
          currentButtonStatus = 2;
          currentButtonStatusStart2 = millis();
        } else {
          // button has been released after long press
          currentButtonStatus = 0;
          event = 4;    
        }
      }
      break;

    case 2:
      if(currentButtonClick) {
        // if the button has been pressed for the second time

        // check how long the button has been released
        if(timeButton - currentButtonStatusStart2 < delayFalse) {
          currentButtonStatus = 1;
        } else {
          // fix second press
          currentButtonStatus = 3;
          currentButtonStatusStart3 = millis();
        }
      } else {
        // if the button is still released

        // check for the single click
        if(timeButton - currentButtonStatusStart2 > delayDeltaDoubleClick) {
          // button has been released for too long, fix single click
          currentButtonStatus = 0;
          event = 1;
        } 
      }
      break;

    case 3: 
      // confirm double click

      if(currentButtonClick) {
        // button is still pressed
        // wait for the button to be released 

      } else {
        // button has been released

        // check for the debounce
        if(timeButton - currentButtonStatusStart3 < delayFalse) {
          // button has been released too early, probably it's a debounce

        } else {
          // fix double click
          event = 2;
          currentButtonStatus = 0;
        }
      }
      break;
  }
  return event;
}
/#包括
int-butPin1=3;
int-butPin2=4;
int eventBut1、eventBut2;
类按钮状态{
static const int delayFalse=30;//如果该值小于30毫秒,则不允许按一次