How can i stops immediately the loop with a Button?

int red = 7;
int yellow = 4;
int green = 2;
int botaoInc = 8;
int botaoFim = 6;
int buttonState = 0;
int buttonState2 = 0;

void setup() {

  pinMode(red, OUTPUT);
  pinMode(yellow, OUTPUT);
  pinMode(green, OUTPUT);
  pinMode(botaoInc, INPUT);
  pinMode(botaoFim, INPUT);

}


void loop() {

  buttonState = digitalRead(botaoInc);
  buttonState2 = digitalRead(botaoFim);

  while ( buttonState == HIGH && buttonState2 == LOW) {
    // Verde on, por 10 segundos, vermelho off e amarelo off
    digitalWrite(green, HIGH);
    digitalWrite(yellow, LOW);
    digitalWrite(red, LOW);
    delay(2000);

    if (buttonState2 == HIGH) {
      break;
    }

    // Verde off, vermelho off, amarela on por 2s
    digitalWrite(green, LOW);
    digitalWrite(yellow, HIGH);
    digitalWrite(red, LOW);
    delay(2000);

    if (buttonState2 == HIGH) {
      break;
    }

    // Vermelho on por 5 segundos, verde e amarelo off
    digitalWrite(green, LOW);
    digitalWrite(yellow, LOW);
    digitalWrite(red, HIGH);
    delay(2000);

    if (buttonState2 == HIGH) {
      break;
    }
  }
}

this traffic lights project has two buttons, 1 to start and other to Stop in any moment.
I try everything that I know in other languages.

don't use delay, use a state machine with button events and millis() to handle time

For extra information and examples on using millis() look at Using millis() for timing. A beginners guide and Several things at the same time

PS: you are not updating the conditions in your while() loop so this is an infinite loop..

2 Likes

Looks like you need an Interrupt

1 Like

This is the problem. What that means is "do nothing for 2 seconds, even if a button is pressed". The delays have to go!

The code you have now is like riding a bicycle with stabilisers ("training wheels"). Time to take that next step and up your coding skill level.

1 Like

No.

2 Likes

this meets the requirement of "stops immediately the loop with a Button" so could be considered but that won't achieve what the real question is - as OP likely wants to break out of his while() loop and continue the loop() and keep processing the traffic light. Not just be stuck in an ISR.

So probably not the answer. State machine + millis is much better

1 Like

With 6 seconds where the CPU can be doing nothing, stopping immediately the loop with a button is not possible with a Uno and using delay(). Instead use a State Machine and millis() for timing.

Use the search to find out more info on state machine and millis().

Look in File|Examples|02.Digital|BlinkWithoutDelay of your Arduino IDE.

1 Like
const byte red = 7;
const byte yellow = 4;
const byte green = 2;
const byte botaoInc = 8;
const byte botaoFim = 6;

void setup() {
  pinMode(red, OUTPUT);
  pinMode(yellow, OUTPUT);
  pinMode(green, OUTPUT);
  pinMode(botaoInc, INPUT);
  pinMode(botaoFim, INPUT);
}

void loop() {
  static bool isRun = true;
  static  unsigned long Timer = 0;

  while (!isRun )
    if ( digitalRead(botaoInc) == HIGH)isRun = true;

  while ( isRun) {
    // Verde on, por 10 segundos, vermelho off e amarelo off
    digitalWrite(green, HIGH);
    digitalWrite(yellow, LOW);
    digitalWrite(red, LOW);
    Timer = millis();
    while (millis() - Timer < 2000UL)
      if ( digitalRead(botaoFim == HIGH))isRun = false;
    if (!isRun)  break;

    // Verde off, vermelho off, amarela on por 2s
    digitalWrite(green, LOW);
    digitalWrite(yellow, HIGH);
    digitalWrite(red, LOW);
    Timer = millis();
    while (millis() - Timer < 2000UL)
      if ( digitalRead(botaoFim == HIGH))isRun = false;
    if (!isRun)  break;

    // Vermelho on por 5 segundos, verde e amarelo off
    digitalWrite(green, LOW);
    digitalWrite(yellow, LOW);
    digitalWrite(red, HIGH);
    Timer = millis();
    while (millis() - Timer < 2000UL)
      if ( digitalRead(botaoFim == HIGH))isRun = false;
    if (!isRun)  break;
  }
}
1 Like

Works partially. but the loop stops even i dont press the button

int red = 7;
int yellow = 4;
int green = 2;
int botaoInc = 8;
int botaoFim = 6;
int buttonState = 0;
int buttonState2 = 0;

void setup() {

  pinMode(red, OUTPUT);
  pinMode(yellow, OUTPUT);
  pinMode(green, OUTPUT);
  pinMode(botaoInc, INPUT);
  pinMode(botaoFim, INPUT);
  digitalWrite(green, LOW);
  digitalWrite(red, LOW);
  digitalWrite(yellow, LOW);

}


void loop() {

  buttonState = digitalRead(botaoInc);
  buttonState2 = digitalRead(botaoFim);

  while (buttonState == HIGH && buttonState2 == LOW) {
    changeLights();
    if (digitalRead(botaoFim == HIGH)) {
      break;
    }
  }
  digitalWrite(green, LOW);
  digitalWrite(red, LOW);
  digitalWrite(yellow, LOW);
}

// Método para controle das leds;
void changeLights() {
  // Verde on, por 10 segundos, vermelho off e amarelo off
  digitalWrite(green, HIGH);
  digitalWrite(yellow, LOW);
  digitalWrite(red, LOW);
  for (long int i = 0; i < 20000; i++) {
    if (digitalRead(botaoFim) == HIGH) {
      return;
    }
  }

  // Verde off, vermelho off, amarela on por 2s
  digitalWrite(green, LOW);
  digitalWrite(yellow, HIGH);
  digitalWrite(red, LOW);
  for (long int i = 0; i < 20000; i++) {
    if (digitalRead(botaoFim) == HIGH) {
      return;
    }
  }

  // Vermelho on por 5 segundos, verde e amarelo off
  digitalWrite(green, LOW);
  digitalWrite(yellow, LOW);
  digitalWrite(red, HIGH);
  for (long int i = 0; i < 20000; i++) {
    if (digitalRead(botaoFim) == HIGH) {
      return;
    }
  }
}

This isn’t doing what you think.

    if (digitalRead(botaoFim == HIGH)) {
      break;

You didn’t see that syntax anywhere.

Review digitalRead().

a7

works now

int red = 7;
int yellow = 4;
int green = 2;
int botaoInc = 8;
int botaoFim = 6;
int buttonState = 0;
int buttonState2 = 0;

void setup() {

  pinMode(red, OUTPUT);
  pinMode(yellow, OUTPUT);
  pinMode(green, OUTPUT);
  pinMode(botaoInc, INPUT);
  pinMode(botaoFim, INPUT);
  digitalWrite(green, LOW);
  digitalWrite(red, LOW);
  digitalWrite(yellow, LOW);

}


void loop() {

  buttonState = digitalRead(botaoInc);

  while (buttonState == HIGH) {
    changeLights();
    if (digitalRead(botaoFim) == HIGH) {
      digitalWrite(green, LOW);
      digitalWrite(red, LOW);
      digitalWrite(yellow, LOW);
      break;
    }
  }
}

// Método para controle das leds;
void changeLights() {
  // Verde on, por 10 segundos, vermelho off e amarelo off
  
  digitalWrite(green, HIGH);
  digitalWrite(yellow, LOW);
  digitalWrite(red, LOW);
  for (long int i = 0; i < 250000; i++) {
    if (digitalRead(botaoFim) == HIGH) {
      return;
    }
  }

  // Verde off, vermelho off, amarela on por 2s
  digitalWrite(green, LOW);
  digitalWrite(yellow, HIGH);
  digitalWrite(red, LOW);
  for (long int i = 0; i < 60000; i++) {
    if (digitalRead(botaoFim) == HIGH) {
      return;
    }
  }

  // Vermelho on por 5 segundos, verde e amarelo off
  digitalWrite(green, LOW);
  digitalWrite(yellow, LOW);
  digitalWrite(red, HIGH);
  for (long int i = 0; i < 100000; i++) {
    if (digitalRead(botaoFim) == HIGH) {
      return;
    }
  }
}

thanks everyone !!

1 Like

neverever :nerd:

Very clever…

for (long int i = 0; i < 60000; i++) {
    if (digitalRead(botaoFim) == HIGH) {
      return;
    }
  }

but you could do those like the below and get a bit better control over how long that “delay” is.

    for (int i = 0; i < 1000; i++) {
        delay(1);
        if (digitalRead(botaoFim) == HIGH) {
            return;
        }
    }

You could also put that logic into a custom function, since it is just the same code repeated.

Try or don’t. If you try and fail or succeed, tell us about it.

a7

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.