Advice on how to improve my Traffic Light program esp32

I have just finished a Traffic Light system project and I need some advise to improve my project. Here is my issue:
How to continuously check the state of the buttonPin while the traffic lights are cycling through (the cycling process is in the void loop)?

Code:

int ledGreen = 15;
int ledRed = 16;
int ledAmber = 17;
int walkingLed = 18;
int lastbuttonState;
int greenledState;
int amberledState;

int buttonPin = 22;
int buttonVal;

void setup() {
  Serial.begin(115200);
  pinMode(ledGreen, OUTPUT);
  pinMode(ledRed, OUTPUT);
  pinMode(ledAmber, OUTPUT);
  pinMode(walkingLed, OUTPUT);
  pinMode(buttonPin, INPUT_PULLUP);

  digitalWrite(ledGreen, LOW);
  digitalWrite(ledRed, LOW);
  digitalWrite(ledAmber, LOW);
  digitalWrite(walkingLed, LOW);
}

void loop() {
  lastbuttonState = 1;
  buttonVal = digitalRead(buttonPin);
  Serial.println(buttonVal);

  CheckSwitchPressed();

  digitalWrite(ledGreen, HIGH);
  digitalWrite(walkingLed, LOW);
  Serial.println(greenledState);
  //  Serial.println("GREEN ON");
  CheckSwitchPressed();

  delay(10000);
  
  digitalWrite(ledGreen, LOW);
  digitalWrite(ledAmber, HIGH);
  //  Serial.println("AMBER ON");
  CheckSwitchPressed();

  delay(1000);
  digitalWrite(ledAmber, LOW);
  digitalWrite(ledRed, HIGH);
  digitalWrite(walkingLed, HIGH);
  //  Serial.println("RED AND WHITE ON");
  
  CheckSwitchPressed();
  delay(7000);
  digitalWrite(ledAmber, HIGH);
  digitalWrite(ledRed, HIGH);
  digitalWrite(walkingLed, LOW);
  //  Serial.println("RED AND YELLOW ON");
  
  CheckSwitchPressed();
  delay(1000);
  //  Serial.println("ALL OFF");
  digitalWrite(ledAmber, LOW);
  digitalWrite(ledRed, LOW);
  digitalWrite(walkingLed, LOW);
  digitalWrite(ledGreen, LOW);
  
  CheckSwitchPressed();
}

void CheckSwitchPressed()
{

  greenledState = digitalRead(ledGreen);
  amberledState = digitalRead(ledAmber);

  buttonVal = digitalRead(buttonPin);

  //  Serial.println("I am working");

  if (lastbuttonState != buttonVal) {
    //If button has been pressed this code will run
    Serial.println("SWITCH PRESSED");

    Serial.print("greenledState");
    Serial.println(greenledState);

    Serial.print("amberledState");
    Serial.println(amberledState);

    if (greenledState == 0) {
      digitalWrite(ledGreen, LOW);
      digitalWrite(ledAmber, HIGH);
      Serial.println("AMBER ON");

      delay(1000);
      digitalWrite(ledAmber, LOW);
      digitalWrite(ledRed, HIGH);
      digitalWrite(walkingLed, HIGH);
      Serial.println("RED AND WHITE ON BECAUSE BUTTON PRESSED");
      delay(2000);
    }
  }
}

Info about multi things

1 Like

Remove all these. Your Arduino can't continuously do anything because you are instructing it to do absolutely nothing for 10 seconds.

1 Like

So this is what I want to do, when the esp32 is in the void loop I want to cycle through green, orange and red.

While it's cycling through it should listen out for the button press (in my state change function).

I just don't know how to do it .

Excuse me for my lack of knowledge, I'm still in primary school.

1 Like

Never apologize for lack of knowledge. Some would go so far as to advise never admit to a lack of knowledge. :expressionless:

Assuming your program works like it looks, what you are asking puts you on the path to a distinctly different manner of programming, to which others have pointed you or alluded to.

Start by coming to a thorough understanding of the classic

arduino blink without delay

Just read about it, try it out, put your fingers on the code and step through it line by line until you see how it works.

The ultimate goal is to be able to do all what you are doing, and to open the possibilities of adding what you are asking for, without any use of the delay() function.

With BWOD "blink without delay" well understood, take some further good quiet time with your friend google and look at

arduino two things at once

and

arduino finite state machine

and

arduino finite state machine traffic lights

It will be hard until it is easy. Expect and wait for the Aha! moment we all experienced at some point when we were moving past the noob stage in this hobby.

a7

Reading thought the "Arduino blink without delay" is there a simpler way of doing it instead of doing:

 if (currentMillis - previousMillis >= interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;

    // if the LED is off turn it on and vice-versa:
    if (ledState == LOW) {
      ledState = HIGH;
    } else {
      ledState = LOW;
    }

    // set the LED with the ledState of the variable:
    digitalWrite(ledPin, ledState);
  }

Yes, there is a simpler way use delay(x) where x = the time you want your program to do nothing.

But if I do that the switch wont be check as pressed if I press it while I am in the delay.

It's better to learn the real approved way to do this, but you can find some hacks.

One is to write your own delay function, and have it hang things up for as long as the delay()would have done, whilst checking if you have a button pressed and just return immediately or… whatever, it's all code.

See this thread.

I searched these fora using "myDelay", as that is a popular name for this when it is done.

It is a quick, dirty and clever hack. You may or not care, the Arduino certainly does not.

HTH

a7

You wanted to know of an easier way. I presented it.

Me, with a ESP32, I'd solve the problem with freeRTOS. Much harder.

1 Like

Okay!

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