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
Loops 当开关处于高位时,如何触发一系列LED事件,以及当开关处于低位时如何停止这些事件?_Loops_Arduino_Led - Fatal编程技术网

Loops 当开关处于高位时,如何触发一系列LED事件,以及当开关处于低位时如何停止这些事件?

Loops 当开关处于高位时,如何触发一系列LED事件,以及当开关处于低位时如何停止这些事件?,loops,arduino,led,Loops,Arduino,Led,我试着让这个东西,每当一个微型限位开关处于高位(按下),它就会启动这个过程,打开一个红色LED 50秒,然后闪烁LED大约10秒,最后关闭红色,然后打开一个绿色LED大约50秒。同时,我在Arduino上做这一切 我遇到的最大问题是每次未按下限位开关时都会断开回路。我希望这一系列LED事件仅在按下开关时发生。下面的代码使用延迟方法,我知道该方法不适用于此项目,因为在LED事件期间无法识别按钮状态更改。我把它放在下面,只是为了让你们都能理解我想要实现的目标 另外,我对Arduino还比较陌生,所以

我试着让这个东西,每当一个微型限位开关处于高位(按下),它就会启动这个过程,打开一个红色LED 50秒,然后闪烁LED大约10秒,最后关闭红色,然后打开一个绿色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);
  }

}

实现所需的最简单方法是将
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);
    }
}
一旦每个等待都有一个函数,您就可以重构代码以避免重复,但我把它作为练习留给您:)

例如,您也可以使用特殊的库来处理事件,但对于初学者,我建议使用更简单的方法。事件很难调试,尤其是在Arduino上。但是如果你对Arduino感到更舒服,你应该试着用它们来做实验


顺便说一下:我想你应该在最后关掉
led1

对于这些类型的问题,我非常喜欢使用
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;
    }
}
#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;
    }
}