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);
}
}
}
Never apologize for lack of knowledge. Some would go so far as to advise never admit to a lack of knowledge.
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
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.
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);
}
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.