简体   繁体   English

我使用按钮作为开关,它可以打开但不能关闭(Arduino)

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

I am trying to make a button work as a switch. 我正在尝试使按钮像开关一样工作。 The code works to turn the lights "on" but the code doesn't want to turn them off. 该代码可以将灯“打开”,但是该代码不想将其关闭。

My code works like so: 我的代码如下所示:

  1. If button is pressed and the lights are off, turn on the lights. 如果按下按钮并且灯熄灭,请打开灯。
  2. If button is pressed and the lights are on, turn off the lights. 如果按下按钮并且灯点亮,请关闭灯。

But number 2 doesn't work. 但是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);
  }
}

Try adding debounce delay. 尝试添加去抖动延迟。 This is common issue with switches. 这是开关的常见问题。 https://www.arduino.cc/en/Tutorial/Debounce https://www.arduino.cc/zh/Tutorial/Debounce

Maybe it's because of a floating pin. 也许是因为有浮针。 Have you built in a pull up or pull down resistor? 您是否内置了上拉或下拉电阻?

It's a common thing... 这是很平常的事

Ok, your description and your code tell two different things. 好的,您的描述和代码告诉了两个不同的问题。 I'm try to interprete them, but if I'm wrong just tell me and I'll try to correct the answer. 我试图解释它们,但是如果我错了,请告诉我,我将尝试纠正答案。

This code lets you use a pushbutton to turn on and off a light on pin 5. One press will turn it on, the other will turn it off. 此代码使您可以使用按钮打开和关闭插针5上的灯。一按将其打开,另一按将其关闭。 You have to connect the button with one end to pin 2 and the other to ground (since we are using a pull-up resistor). 您必须将按钮的一端连接到引脚2,另一端接地(因为我们使用的是上拉电阻)。

I also added a small debounce delay to cope with the bounces of the mechanical switch (50ms) 我还添加了一个小的反跳延迟来应对机械开关的反跳(50毫秒)

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));
        }
    }
}

When you press the button the led on pin 5 will turn on, when you press it again it will turn off. 当您按下按钮时,引脚5上的指示灯将点亮,再次按下时,其指示灯将熄灭。

This is the behavior you asked. 这是您要求的行为。 Your code, on the other side, lights up a sequence of LEDs when you push the button. 另一方面,您的代码在按下按钮时会点亮一系列LED。 In this case, if you want to start the cycle with a press and then stop it with another press, you have to use a sort of simple state machine, like the one in the code. 在这种情况下,如果您想按一个循环开始循环,然后再按一次停止循环,则必须使用一种简单的状态机,如代码中的状态机。 I also added a small debounce to the button, which needs again to be connected between 2 and ground. 我还为按钮添加了一个小的反跳,需要再次将其连接到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;

    }
}

This works in this way: you press the button and the board will start cycling through the LEDS. 这是这样工作的:按下按钮,电路板将开始循环通过LED。 5, 7, 9, 11, 13, 5, 7, 9, 11, 13, ... Until you press again the button. 5,7,9,11,13,5,7,9,11,13,...直到再次按下按钮。 When you do this, it stops, then at the next press restarts from 5. 执行此操作时,它将停止,然后在下一次按下时从5重新开始。

If you want that after the 13 it stops, change the line 105 from stateMachineStatus = STATE_LED5ON; 如果您希望在13号停止后将其从105行更改为stateMachineStatus = STATE_LED5ON; to stateMachineStatus = STATE_LEDSOFF; stateMachineStatus = STATE_LEDSOFF; .

One note: in your code the delay is too low (and it is the same that I put here): 50 ms between one led and the other cannot be noticed. 一个注意事项:在您的代码中,延迟太低(与我在此处所说的相同):一个LED与另一个LED之间的50毫秒无法注意到。 If you want to actually see them in sequence, put values of at least 250 in the TIME_LEDxON defines. 如果要按顺序实际查看它们,请在TIME_LEDxON定义中至少输入250。

DISCLAIMER: I haven't tested these codes since I don't have arduino ide installed at present. 免责声明:由于我目前尚未安装arduino ide,因此我尚未测试这些代码。 If there are some bugs, simply tell me and I'll fix them. 如果有错误,只需告诉我,我会修复。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM