首页 文章

当开关处于高电平时,如何触发一系列LED事件,如何在开关处于低电平时停止它们?

提问于
浏览
3

我试图在每次微限位开关为高电平(按下)的情况下制作这个东西,它开始这个过程,打开红色LED五十秒,然后闪烁LED大约十秒钟,然后最后关闭红色,打开绿色LED约50秒 . 另外,我在Arduino上做了所有这些 .

我遇到的一个大问题是每次没有按下限位开关时都会断开循环 . 我只想在按下开关时发生这一系列的LED事件 . 下面的代码使用延迟方法,我知道这个方法对于这个项目不起作用,因为在LED事件期间不会识别按钮状态变化 . 我把它放在下面,这样你们都可以理解我想要实现的目标 .

此外,我对Arduino相对较新,所以非常感谢每一点帮助 . 谢谢 .

这是我上面提到的代码:

const int buttonPin = 2;
const int ledPin = 12;
const int ledPin1 = 9;

int buttonState = 0;

void setup() {
  
  pinMode(buttonPin, INPUT);
  pinMode(ledPin, OUTPUT);
  pinMode(ledPin1, OUTPUT);
  Serial.begin(115200);
}

void loop() {
  buttonState = digitalRead(buttonPin);

  if (buttonState == HIGH) {

    
    digitalWrite(ledPin, HIGH);
    delay(50000);
    digitalWrite(ledPin, LOW);
    delay(1000);
    digitalWrite(ledPin, HIGH);
    delay(1000);
    digitalWrite(ledPin, LOW);
    delay(1000);
    digitalWrite(ledPin, HIGH);
    delay(1000);
    digitalWrite(ledPin, LOW);
    delay(1000);
    digitalWrite(ledPin1, HIGH);
    delay(50000);
  }

  else if (buttonState == LOW) {

    digitalWrite(ledPin, LOW);
    digitalWrite(ledPin1, LOW);
  }

}

2 回答

  • 0

    实现您想要的最简单方法是将 loop() 函数分成几个小函数,并将延迟分成许多小延迟 . 例如,为了处理你的第一次等待你需要这样的事情:

    bool wait50secondsOnHigh()
    {
        for (int counter = 0; counter < 5000; counter++)
        {
            if (digitalRead(buttonPin) == LOW)
            {
                return false;
            }
    
            digitalWrite(ledPin, HIGH);
            delay(10);
        }
    
        return wait1secondOnLow();
    }
    
    loop()
    {
        if (!wait50secondsOnHigh())
        {
            digitalWrite(ledPin, LOW);
            digitalWrite(ledPin1, LOW);
        }
    }
    

    其他等待函数可以用类似的方式编写:你每隔10毫秒检查你的按钮N次,如果是 HIGH 你继续,如果它是 LOW 你返回false . 完成后,调用下一个函数 . 顺序的最后一个函数将只返回 true

    bool wait50secondsOnHighLed1()
    {
        for (int counter = 0; counter < 5000; counter++)
        {
            if (digitalRead(buttonPin) == LOW)
            {
                return false;
            }
    
            digitalWrite(ledPin1, HIGH);
            delay(10);
        }
    
        return true;
    }
    

    一旦你有每个等待的功能你可以重构代码以避免重复,但我把它作为练习给你:)

    您还可以使用特殊库进行事件处理,例如http://playground.arduino.cc/Code/QP但是对于初学者,我建议使用更简单的方法 . 事件很难调试,特别是在Arduino上 . 但是你对Arduino感到更舒服,你应该试着尝试一下 .

    顺便说一句:我认为你最后应该关闭 led1 .

  • 1

    对于这些类型的问题,我真的很想使用 switch() 语句来创建状态机 . 我还建议您根本不使用 delay() 函数,而是计算自上次循环以来经过的时间 . 这是我想出的一个快速示例...如果它有任何错误,我道歉,我有点急 . 如果您在遵循逻辑时遇到问题,请告诉我,我会添加更多评论 .

    #define WAIT_TIME_50S   50000   /* 50,000ms = 50s */
    #define WAIT_TIME_10S   10000   /* 10,000ms = 10s */
    #define WAIT_TIME_1S    1000    /* 1,000ms  = 1s  */
    
    /* Create an enumeration 'type' with the different states that you will
       be going through.  This keeps your switch statement very
       descriptive and you know exactly what happens as you go from
       state to state. */
    typedef enum
    {
        SWITCH_RELEASED,
        RED_LED_ON_50S,
        RED_LED_BLINK_10S,
        GREEN_LED_ON_50S,
        RESET_LEDS
    } LedState_t;
    
    const int buttonPin     = 2;
    const int ledPinRed     = 12;
    const int ledPinGreen   = 9;
    int buttonState         = LOW;
    
    void loop() 
    {
        static LedState_t currentState = RESET_LEDS;
        static unsigned long previousTime_ms = 0;
        static unsigned long previousBlinkTime_ms = 0;
        unsigned long currentTime_ms = 0;
        static int ledState = LOW;
    
        buttonState = digitalRead(buttonPin);
    
        switch (currentState)
        {
            case SWITCH_RELEASED:
                if (buttonState == HIGH)
                {
                    currentState = RED_LED_ON_50S;
                    digitalWrite(ledPinRed, HIGH);
                    previousTime_ms = millis();
                }
                break;
    
            case RED_LED_ON_50S:
                if (buttonState == LOW)
                {
                    currentState = RESET_LEDS;
                }
                else
                {
                    currentTime_ms = millis();
    
                    if ((currentTime_ms - previousTime_ms) >= WAIT_TIME_50S)
                    {
                        previousTime_ms = currentTime_ms;
                        previousBlinkTime_ms = currentTime_ms;
    
                        ledState = LOW;
                        digitalWrite(ledPinRed, ledState);
                        currentState = RED_LED_BLINK_10S;
                    }
                }
                break;
    
            case RED_LED_BLINK_10S:
                if (buttonState = LOW)
                {
                    currentState = RESET_LEDS;
                }
                else
                {
                    currentTime_ms = millis();
    
                    if ((currentTime_ms - previousTime_ms) >= WAIT_TIME_10S)
                    {
                        previousTime_ms = currentTime_ms;
    
                        digitalWrite(ledPinRed, LOW);
                        digitalWrite(ledPinGreen, HIGH);
    
                        currentState = GREEN_LED_ON_50S;
                    }
                    else if ((currentTime_ms - previousBlinkTime_ms) >= WAIT_TIME_1S)
                    {
                        previousBlinkTime_ms = currentTime_ms;
    
                        if (ledState == HIGH)
                        {
                            ledState = LOW;
                        }
                        else
                        {
                            ledState = HIGH;
                        }
    
                        digitalWrite(ledPinRed, ledState);
                    }
                }
                break;
    
            case GREEN_LED_ON_50S:
                if (buttonState == LOW)
                {
                    currentState = RESET_LEDS;
                }
                else
                {
                    currentTime_ms = millis();
    
                    if ((currentTime_ms - previousTime_ms) >= WAIT_TIME_50S)
                    {
                        currentState = RESET_LEDS;
                    }
                }
                break;
    
            case RESET_LEDS:
                digitalWrite(ledPinRed, LOW);
                digitalWrite(ledPinGreen, LOW);
    
                currentState = SWITCH_RELEASED;
                break;
        }
    }
    

相关问题