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

I am using a button as a switch, it turns on but doesn't turn off (Arduino)

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

我的代码是这样工作的:

  1. 如果按下按钮并且灯熄灭,请打开灯。
  2. 如果按下按钮并且灯亮着,请关闭灯。

但是数字 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);
  }
}

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

可能是因为浮动引脚。您是否内置了上拉或下拉电阻?

这是常事...

好的,您的描述和代码说明了两件不同的事情。我试着解释它们,但如果我错了请告诉我,我会尽力更正答案。

此代码可让您使用按钮打开和关闭引脚 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 会亮起,当您再次按下它时,它会熄灭。

这是你问的行为。在另一个 side 上,您的代码会在您按下按钮时点亮一系列 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 ms 是不会被注意到的。如果您想按顺序实际查看它们,请在 TIME_LEDxON 定义中输入至少 250 的值。

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