Control LED blinking events with limit switch. *HELP*

Hey all,

So I am trying to make a thing where every time a micro limit switch is HIGH (pressed) , it turns on a red LED for about 50 seconds and begins to blink. The blinking only lasts for a short time and afterwards a green LED turns on and stays lit for 50 seconds.

The big problem is that every time the micro limit switch is LOW, I need it to break the initial loop. In the following example, I use the delay method, which I know cannot be used because I have to wait for the entire LED process to end before it can recognize any further button states.

Also, it is important to mention that I am relatively new to Arduino, so every bit of help is appreciated.

Here is my current code that I mentioned above:

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

int buttonState = 0;
int lastButtonState = 0;

void setup() {
  // initialize the digital pin as an output.
  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);
  }

}

Hey, all

I am trying to make this thing where every time a micro limit switch is HIGH (pressed), it starts this process that turns on a red LED for fifty seconds, then blinks the LED for about ten seconds, and then finally turns off the red, and turns on a green LED for about 50 seconds.

The big problem that I am having pertains to breaking the loop every time the limit switch is not pressed. I want this series of LED events only to occur when the switch is pressed. The code below uses the 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 it below just so you all can understand what I am trying to achieve.

Also, I am relatively new to the Arduino so every bit of help is greatly appreciated. Thanks.

Here is the code that 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);
  }

}

I thought the last time I tried to post this did not work so now there are two topics, so sorry about that.

Try this and than figure out what is wrong with your flow. And if this is your REAL spec, pay no attention to "blink without delay" recommendations you will receive soon.

HIGH (pressed), it starts this process that turns on a red LED for fifty seconds, then blinks the LED for about ten seconds, and then finally turns off the red, and turns on a green LED for about 50 seconds.

Hint - in digital word the values are either high or low, if checked for HIGH no need to have } else if low { checked again. it will be low. And when you got it working look-up "for" loop for your flashing LED code.

Than we can talk about why it is better to have button push = LOW to activate things.

Good luck

[code]

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) {

    Serial.print("ledPin on ");
    digitalWrite(ledPin, HIGH);
    delay(50000);
    Serial.print("ledPin off ");

    Serial.print("flash ledPin on ");
    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);
    Serial.print("flash ledPin on ");

    Serial.print("ledPin1 on ");
    digitalWrite(ledPin1, HIGH);
    delay(50000);
    Serial.print("ledPin1 on ");
  }

  else if (buttonState == LOW) {
   // check your COM output first add than some delay here for good measure 
    Serial.print("ledPin1 off ");
    Serial.print("ledPin1 off ");
    digitalWrite(ledPin, LOW);
    digitalWrite(ledPin1, LOW);
  }

}

[/code]

look at the blink with out delay example included with the arduino program. file-example-digital-blinkWithOutDelay

Think about implementing a Finite State Machine. This will give you the 'stateness' that you are looking for in the code.

If I understand your logic requirements, while the input is not active, all you are looking for is an active input. Once the input is active, you are going to pass through all the different LED states, any of which may be aborted by the original input becoming inactive.

This is a classic (very simple) Finite State Machine application.

I threw this together to illustrate the finite state machine and blink without delay methods. They are, in my somewhat novice opinion, two of the most important to understand. I have tested this code and it works. I used your pin numbers but changed the switch wiring to: switch to ground and pin 2 and internal pullup enabled. Input is LOW for a pushed button. Change the longDelay variable to suit your timing. I can't wait 50 seconds so set it to 5 seconds.

Red LED lights for 5 (50) seconds Red LED flashes 10 times for approximately 10 seconds and goes off Green LED turns on for 5 (50) seconds If at ANY time the button is released (to off) both LEDs go off pretty much immediately (which will not happen using delay()) Sequence will repeat as long as the switch is held on.

const byte buttonPin = 2;
const byte redLedPin = 12;
const byte greenLedPin = 9;

boolean buttonState = 0;
unsigned long timer;
byte state = 0;
unsigned long longDelay = 5000;  
unsigned long shortDelay = 500;
byte blinkCount = 0;
boolean redLedState = LOW;

void setup()
{
    pinMode(buttonPin, INPUT_PULLUP);
    pinMode(redLedPin, OUTPUT);
    pinMode(greenLedPin, OUTPUT);
    digitalWrite(redLedPin, LOW);
    digitalWrite(greenLedPin, LOW);
    Serial.begin(9600);
    timer = millis();
}

void loop() {
    buttonState = digitalRead(buttonPin);
    // if button not pushed go to state 5 
    if(buttonState == HIGH)
    {
        digitalWrite(redLedPin, LOW);
        state = 5;
    }
    if (state == 0) // if button first pressed turn on red led and go to next state
    {
        digitalWrite(redLedPin, HIGH);
        timer = millis();
        state = 1;
        Serial.println("button on, timing red");
    }
    // wait for longDelay, turn off red led, go to next state
    if (state == 1)
    {
        if(millis() - timer >= longDelay)
        {
            digitalWrite(redLedPin, LOW);            
            state = 2;
            Serial.println("red led timed out");
            Serial.println("flashing red led");
            timer = millis();
        }
    }
    // blink red led 10 times with short delay    
    if(state == 2)
    {
        if(millis() - timer >= shortDelay)
        {
            redLedState = !redLedState;
            digitalWrite(redLedPin, redLedState);
            timer = millis();
            blinkCount++;
        }
        if(blinkCount > 10)
        {
            state = 3;
            Serial.println("button on, timing green");
            digitalWrite(redLedPin, LOW);
            blinkCount = 0;
            timer = millis();
        }
    }
    // tunr off red led and turn on green for dongDelay
    if(state == 3)
        digitalWrite(greenLedPin, HIGH);        
    {
        if(millis() - timer  > longDelay)
        {
            digitalWrite(greenLedPin, LOW);
            Serial.println("green led timed out");
            timer = millis();
            state = 4;
        }
    }
    // sequence done ready to start over
    if(state == 4)
    {
        Serial.println("sequence finished");
        state = 0;
    }
    // button off.  turn off leds and start over
    if(state == 5)
    {
        digitalWrite(redLedPin, LOW);
        digitalWrite(greenLedPin, LOW);
        //Serial.println("button off");
        timer = millis();
        state = 0;
    }
    //delay(200);
}

Threads merged.

quick easy code that looks at timing a different way. This only really works on outputs because once set they stay set. The same idea could be used on different timing codes using if arguments instead of a switch

const int buttonPin = 2;
const int ledPin = 12;
const int ledPin1 = 9;
int buttonState = 0;
int counter = 0;
unsigned long previousMillis = 0;
unsigned long currentMillis = 0;

void setup() {

  pinMode(buttonPin, INPUT);
  pinMode(ledPin, OUTPUT);
  pinMode(ledPin1, OUTPUT);
  Serial.begin(9600);
}

void loop() {

  buttonState = digitalRead(buttonPin);


  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis > 1000L) {//every second do this
  //this is add one to counter
    counter++;//this is being constantly reset to 0 when buttonstate is low
    previousMillis = currentMillis;
  }

  if (buttonState == HIGH) {
    switch (counter) {
      //great thing with outputs are once set they stay set 
      case 1:
        Serial.println("ledPin on ");
        digitalWrite(ledPin, HIGH);
        break;
        Serial.println("ledPin off ");
      case 50:
        Serial.println("flash ledPin on ");
        digitalWrite(ledPin, LOW);
        break;
      case 51:
        digitalWrite(ledPin, HIGH);
        break;
      case 52:
        digitalWrite(ledPin, LOW);
        break;
      case 53:
        digitalWrite(ledPin, HIGH);
        break;
      case 54:
        digitalWrite(ledPin, LOW);
        break;
      case 55:
        Serial.println("flash ledPin off ");
        Serial.println("ledPin1 on ");
        digitalWrite(ledPin1, HIGH);
        break;
      case 105:
        digitalWrite(ledPin1, LOW);
        break;
    }
  }
  else {
    
    Serial.println("ledPin1 off ");
    digitalWrite(ledPin, LOW);
    digitalWrite(ledPin1, LOW);
    counter = 0;//this is the reset part
  }

  counter = constrain (counter, 0, 120);//this just stops counter getting to large and rolling over
  Serial.println(counter);//this just shows that its timing/counting
}

was playing so I upgraded the code I posted to make the led flash with out repeating the same lines

const int buttonPin = 2;
const int ledPin = 13;
const int ledPin1 = 9;
int buttonState = 0;
int counter = 0;
unsigned long previousMillis = 0;
unsigned long currentMillis = 0;

int repeat;
int repeatTimes;
void setup() {

  pinMode(buttonPin, INPUT);
  pinMode(ledPin, OUTPUT);
  pinMode(ledPin1, OUTPUT);
  Serial.begin(9600);
}

void loop() {

  buttonState = digitalRead(buttonPin);

  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis > 100L) {//every tenth of a second
    //this is add one to counter
    counter++;//this is being constantly reset to 0 when buttonstate is low
    previousMillis = currentMillis;
  }



  if (buttonState == HIGH) {

    if (repeat == 1) {
      counter = 500;
      repeat = 0;
      repeatTimes++;
    } 

    switch (counter) {
      //great thing with outputs are once set they stay set
      case 1:
        Serial.println("ledPin on ");
        digitalWrite(ledPin, HIGH);
        break;
        Serial.println("ledPin off ");
      case 500:
        Serial.println("flash ledPin on ");
        digitalWrite(ledPin, LOW);
        break;
      case 510:
        digitalWrite(ledPin, HIGH);
        break;
      case 520:
        if (repeatTimes <= 10) {
          repeat = 1;
        } else {
          counter=530;
          digitalWrite(ledPin, LOW);
        }
        break;
      case (530):
        Serial.println("flash ledPin off ");
        Serial.println("ledPin1 on ");
        digitalWrite(ledPin1, HIGH);
        break;
      case (1050):
        digitalWrite(ledPin1, LOW);
        break;
    }
  }
  else {

    Serial.println("ledPin1 off ");
    digitalWrite(ledPin, LOW);
    digitalWrite(ledPin1, LOW);
    counter = 0;//this is the reset part
    repeat = 0;
    repeatTimes = 0;
  }


  counter = constrain (counter, 0, 1120);//this just stops counter getting to large and rolling over
  Serial.println(counter);//this just shows that its timing/counting
}

Damn. Thank you all so much for your help. I finally got it to work.