我使用一个按钮作为开关,它打开但不关闭(Arduino)

时间:2017-01-02 05:07:31

标签: button arduino arduino-uno light

我正在尝试将按钮用作开关。该代码可以将灯打开,但代码不想关闭它们。

我的代码就像这样:

  1. 如果按下按钮并且指示灯熄灭,请打开灯。
  2. 如果按下按钮并且指示灯亮起,请关闭指示灯。
  3. 但是数字2不起作用。

    int buttonStatus = 0;
    int check = 1;
    int Status = 0;
    
    void setup() {
      pinMode(5,OUTPUT);
      pinMode(7,OUTPUT);
      pinMode(9,OUTPUT);
      pinMode(11,OUTPUT);
      pinMode(13,OUTPUT);
      pinMode(2,INPUT);
    }
    
    void loop() {
      if (check = 1) {
        buttonStatus = digitalRead(2);
        if (buttonStatus == HIGH && Status == 0) {
          Status = 1;
          buttonStatus = 0;
        } else if (buttonStatus == HIGH && Status == 1) {
          Status = 0;
          buttonStatus = 0;
        }
      }
    
      if (Status == 1) {
        digitalWrite(5,HIGH);
        delay(50);
        digitalWrite(5,LOW);
        digitalWrite(7,HIGH);
        delay(50);
        digitalWrite(7,LOW);
        digitalWrite(9,HIGH);
        delay(50);
        digitalWrite(9,LOW);
        digitalWrite(11,HIGH);
        delay(100);
        digitalWrite(11,LOW);
        digitalWrite(13,HIGH);
        delay(100);
        digitalWrite(13,LOW);
      } else {
        digitalWrite(5,LOW);
        digitalWrite(7,LOW);
        digitalWrite(9,LOW);
        digitalWrite(11,LOW);
        digitalWrite(13,LOW);
      }
    }
    

3 个答案:

答案 0 :(得分:0)

尝试添加去抖延迟。这是开关的常见问题。 https://www.arduino.cc/en/Tutorial/Debounce

答案 1 :(得分:0)

也许是因为浮针。你有内置上拉或下拉电阻吗?

这很常见......

答案 2 :(得分:0)

好的,你的描述和你的代码讲述了两件不同的事情。我试着解释它们,但如果我错了就告诉我,我会尽力纠正答案。

此代码允许您使用按钮打开和关闭引脚5上的指示灯。按下一个按钮将其打开,另一个按钮将其关闭。您必须将按钮的一端连接到引脚2,另一端连接到地(因为我们使用的是上拉电阻)。

我还添加了一个小的去抖延迟来应对机械开关的反弹(50ms)

byte buttonStatus;
unsigned long lastEqualButtonTime;
#define debounceTimeMs 50

void setup() {
    pinMode(5,OUTPUT);
    pinMode(2,INPUT_PULLUP);
    buttonStatus = digitalRead(2);
    lastEqualButtonTime = millis();
}

void loop() {
    byte currentButtonStatus = digitalRead(2);
    if (currentButtonStatus == buttonStatus)
        lastEqualButtonTime = millis();
    else if ((millis() - lastEqualButtonTime) > debounceTimeMs)
    {
        lastEqualButtonTime = millis();
        buttonStatus = currentButtonStatus;

        // Change only on change, not on value
        if (buttonStatus == LOW) {
            digitalWrite(5, !digitalRead(5));
        }
    }
}

当您按下按钮时,针脚5上的LED将打开,当您再次按下它时它将关闭。

这是您提出的行为。另一方面,当您按下按钮时,您的代码会点亮一系列LED。在这种情况下,如果你想按下开始循环,然后再按下它,你必须使用一种简单的状态机,就像代码中的状态机一样。我还在按钮上添加了一个小的去抖动,它需要再次连接在2和地之间。

byte buttonStatus;
unsigned long lastEqualButtonTime;
#define debounceTimeMs 50

// Statuses
#define STATE_LEDSOFF 0
#define STATE_LED5ON  1
#define STATE_LED7ON  2
#define STATE_LED9ON  3
#define STATE_LED11ON 4
#define STATE_LED13ON 5

// How much time should each led be on?
// Expressed in milliseconds
#define TIME_LED5ON   50
#define TIME_LED7ON   50
#define TIME_LED9ON   50
#define TIME_LED11ON 100
#define TIME_LED13ON 100

byte stateMachineStatus;
unsigned long stateMachineTime;

void setup() {
    pinMode(5,OUTPUT);
    pinMode(7,OUTPUT);
    pinMode(9,OUTPUT);
    pinMode(11,OUTPUT);
    pinMode(13,OUTPUT);
    pinMode(2,INPUT_PULLUP);
    buttonStatus = digitalRead(2);
    lastEqualButtonTime = millis();
    stateMachineStatus = STATE_LEDSOFF;
}

void loop() {
    byte currentButtonStatus = digitalRead(2);
    if (currentButtonStatus == buttonStatus)
        lastEqualButtonTime = millis();
    else if ((millis() - lastEqualButtonTime) > debounceTimeMs)
    {
        lastEqualButtonTime = millis();
        buttonStatus = currentButtonStatus;

        // Change only on change, not on value
        if (buttonStatus == LOW) {
            // Turn on the LEDs sequence if it was off
            if (stateMachineStatus == STATE_LEDSOFF)
            {
                stateMachineStatus = STATE_LED5ON;
                stateMachineTime = millis();
            }
            else // Turn it off if it was on
                stateMachineStatus = STATE_LEDSOFF;
        }
    }

    switch (stateMachineStatus)
    {
    case STATE_LEDSOFF:
        digitalWrite(5,LOW);
        break;
    case STATE_LED5ON:
        digitalWrite(5,HIGH);
        if ((millis() > stateMachineTime) > TIME_LED5ON)
        {
            stateMachineTime += TIME_LED5ON;
            digitalWrite(5,LOW);
            stateMachineStatus = STATE_LED7ON;
        }
        break;
    case STATE_LED7ON:
        digitalWrite(7,HIGH);
        if ((millis() > stateMachineTime) > TIME_LED7ON)
        {
            stateMachineTime += TIME_LED7ON;
            digitalWrite(7,LOW);
            stateMachineStatus = STATE_LED9ON;
        }
        break;
    case STATE_LED9ON:
        digitalWrite(9,HIGH);
        if ((millis() > stateMachineTime) > TIME_LED9ON)
        {
            stateMachineTime += TIME_LED9ON;
            digitalWrite(9,LOW);
            stateMachineStatus = STATE_LED11ON;
        }
        break;
    case STATE_LED11ON:
        digitalWrite(11,HIGH);
        if ((millis() > stateMachineTime) > TIME_LED11ON)
        {
            stateMachineTime += TIME_LED11ON;
            digitalWrite(11,LOW);
            stateMachineStatus = STATE_LED13ON;
        }
        break;
    case STATE_LED13ON:
        digitalWrite(13,HIGH);
        if ((millis() > stateMachineTime) > TIME_LED13ON)
        {
            stateMachineTime += TIME_LED13ON;
            digitalWrite(13,LOW);
            stateMachineStatus = STATE_LED5ON;
        }
        break;
    default:
        stateMachineStatus = STATE_LEDSOFF;
        break;

    }
}

这样可以这样工作:按下按钮,电路板将开始循环通过LED。 5,7,9,11,13,5,7,9,11,13 ......直到再次按下按钮。执行此操作时,它会停止,然后在下一次按下时从5开始重新启动。

如果您想在13之后停止,请将第105行从stateMachineStatus = STATE_LED5ON;更改为stateMachineStatus = STATE_LEDSOFF;

一个注意事项:在你的代码中,延迟太低(和我放在这里的相同):一个LED和另一个之间的50毫秒不能被注意到。如果您想要按顺序实际看到它们,请在TIME_LEDxON中定义至少250的值。

免责声明:我没有测试这些代码,因为我目前没有安装arduino ide。如果有一些错误,只需告诉我,我会解决它们。