How can I initiate a series of LED events when the switch is HIGH, and how can I stop them when the switch is LOW?

I am trying to do this when every time the micro limit switch is HIGH (pressed) it starts this process which turns on the red LED for fifty seconds then flashes the LED for about ten seconds and then finally turns off the red light and turn on the green LED for about 50 seconds. Also, I do all of this on Arduino.

The big problem I am facing is to break the loop every time the limit switch is not pressed. I want this series of LED events to only happen when a switch is pressed. The code below uses a delay method which I know will not work for this project because the button state change will not be recognized during the LED events. I put this below so you can all understand what I am trying to achieve.

Also, I'm relatively new to Arduino, so any help is greatly appreciated. Thank.

Here is the code I mentioned above:

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

}

      

+3


source to share


2 answers


The easiest way to get what you want is to break the function loop()

into several small functions and split the delays into many small delays. For example, to deal with the first wait, you need something like this:

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

      

Other wait functions can be written in a similar way: you check your button every 10 milliseconds N times, if HIGH

you continue, if it LOW

returns false. After you're done, you call the next function. The last function in the sequence will simply return true

:

bool wait50secondsOnHighLed1()
{
    for (int counter = 0; counter < 5000; counter++)
    {
        if (digitalRead(buttonPin) == LOW)
        {
            return false;
        }

        digitalWrite(ledPin1, HIGH);
        delay(10);
    }

    return true;
} 

      



Once you have a function for each wait, you can refactor the code to avoid duplication, but I'll leave that as an exercise for you :)

You can also use special event handling libraries like http://playground.arduino.cc/Code/QP , but for beginners, I would recommend a simpler approach. Events are difficult to debug, especially on Arduino. But with what you like best with the Arduino, you should try experimenting with them.

By the way: I think you should disable led1

at the end.

+1


source


For these types of problems, I really like to use operators switch()

to create a state machine. I would also recommend that you don't use the function at all delay()

, but rather calculate how much time has passed since the last loop. Here is a quick example I came up with ... I'm sorry if there are any mistakes in it, I was in a little rush. If you have any problems with the logic, let me know and I will add additional comments.



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

      

0


source







All Articles