I need help

Hey guys, I need help. I am a beginner and I am trying to create a 3-way traffic light with 1 pedestrian crossing that can interrupt the loop of the traffic lights with a button. I have tried to create a debounce thing but the button does not work. I have found a long way around needing to loop the code so ill send both codes, one for the traffic lights only (it works)

int r1 = 1;
int y1 = 2;
int g1 = 3;
int r2 = 4;
int y2 = 5;
int g2 = 6;
int r3 = 7;
int y3 = 8;
int g3 = 9;

void setup() {
pinMode (r1, OUTPUT);
pinMode (y1, OUTPUT);
pinMode (g1, OUTPUT);

pinMode (r2, OUTPUT);
pinMode (y2, OUTPUT);
pinMode (g2, OUTPUT);

pinMode (r3, OUTPUT);
pinMode (y3, OUTPUT);
pinMode (g3, OUTPUT);
}

void loop() { 
    
digitalWrite(r1, HIGH);
digitalWrite(r2, HIGH);
digitalWrite(r3, HIGH);
digitalWrite(y1, LOW);
digitalWrite(y2, LOW);
digitalWrite(y3, LOW);
digitalWrite(g1, LOW);
digitalWrite(g2, LOW);
digitalWrite(g3, LOW);
delay(750);
digitalWrite(g1, HIGH);
digitalWrite(r1, LOW);
delay(5000);

digitalWrite(r1, LOW);
digitalWrite(r2, HIGH);
digitalWrite(r3, HIGH);
digitalWrite(y1, HIGH);
digitalWrite(y2, LOW);
digitalWrite(y3, LOW);
digitalWrite(g1, LOW);
digitalWrite(g2, LOW);
digitalWrite(g3, LOW);
delay(5000);
digitalWrite(r1, HIGH);
digitalWrite(r2, HIGH);
digitalWrite(r3, HIGH);
digitalWrite(y1, LOW);
digitalWrite(y2, LOW);
digitalWrite(y3, LOW);
digitalWrite(g1, LOW);
digitalWrite(g2, LOW);
digitalWrite(g3, LOW);
delay(750);
digitalWrite(g2, HIGH);
digitalWrite(r2, LOW);
delay(5000);

digitalWrite(r1, HIGH);
digitalWrite(r2, LOW);
digitalWrite(r3, HIGH);
digitalWrite(y1, LOW);
digitalWrite(y2, HIGH);
digitalWrite(y3, LOW);
digitalWrite(g1, LOW);
digitalWrite(g2, LOW);
digitalWrite(g3, LOW);
delay(5000);
digitalWrite(r1, HIGH);
digitalWrite(r2, HIGH);
digitalWrite(r3, HIGH);
digitalWrite(y1, LOW);
digitalWrite(y2, LOW);
digitalWrite(y3, LOW);
digitalWrite(g1, LOW);
digitalWrite(g2, LOW);
digitalWrite(g3, LOW);
delay(750);
digitalWrite(g3, HIGH);
digitalWrite(r3, LOW);
delay(5000);

digitalWrite(r1, HIGH);
digitalWrite(r2, HIGH);
digitalWrite(r3, LOW);
digitalWrite(y1, LOW);
digitalWrite(y2, LOW);
digitalWrite(y3, HIGH);
digitalWrite(g1, LOW);
digitalWrite(g2, LOW);
digitalWrite(g3, LOW);
delay(5000);

}

and the code for the pedestrian crossing (doesn't work)

int r1 = 1;
int y1 = 2;
int g1 = 3;
int r2 = 4;
int y2 = 5;
int g2 = 6;
int r3 = 7;
int y3 = 8;
int g3 = 9;
int button = 13;
int pedred = 10;
int pedgreen = 11;

void setup() {
  pinMode (r1, OUTPUT);
  pinMode (y1, OUTPUT);
  pinMode (g1, OUTPUT);

  pinMode (r2, OUTPUT);
  pinMode (y2, OUTPUT);
  pinMode (g2, OUTPUT);

  pinMode (r3, OUTPUT);
  pinMode (y3, OUTPUT);
  pinMode (g3, OUTPUT);

  pinMode (button, INPUT);
  pinMode (pedred, OUTPUT);
  pinMode (pedgreen, OUTPUT);
}

void loop() {
  if (digitalRead(button) == HIGH) {
    delay(15); // software debounce
    if (digitalRead(button) == HIGH) {
      // if the switch is HIGH, ie. pushed down - change the lights!
      changeLights();
    }
  }
  else
  {

    digitalWrite(r1, HIGH);
    digitalWrite(r2, HIGH);
    digitalWrite(r3, HIGH);
    digitalWrite(y1, LOW);
    digitalWrite(y2, LOW);
    digitalWrite(y3, LOW);
    digitalWrite(g1, LOW);
    digitalWrite(g2, LOW);
    digitalWrite(g3, LOW);
    digitalWrite(pedred, HIGH);
    digitalWrite(pedgreen, LOW);
    delay(750);
    digitalWrite(g1, HIGH);
    digitalWrite(r1, LOW);
    delay(5000);

    digitalWrite(r1, LOW);
    digitalWrite(r2, HIGH);
    digitalWrite(r3, HIGH);
    digitalWrite(y1, HIGH);
    digitalWrite(y2, LOW);
    digitalWrite(y3, LOW);
    digitalWrite(g1, LOW);
    digitalWrite(g2, LOW);
    digitalWrite(g3, LOW);
    delay(5000);
    digitalWrite(r1, HIGH);
    digitalWrite(r2, HIGH);
    digitalWrite(r3, HIGH);
    digitalWrite(y1, LOW);
    digitalWrite(y2, LOW);
    digitalWrite(y3, LOW);
    digitalWrite(g1, LOW);
    digitalWrite(g2, LOW);
    digitalWrite(g3, LOW);
    delay(750);
    digitalWrite(g2, HIGH);
    digitalWrite(r2, LOW);
    delay(5000);

  }

}

void changeLights() {
  delay(3000);
  digitalWrite(r1, LOW);
  digitalWrite(y1, HIGH);
  digitalWrite(g1, LOW);
  digitalWrite(r2, LOW);
  digitalWrite(y2, HIGH);
  digitalWrite(g2, LOW);
  digitalWrite(r3, LOW);
  digitalWrite(y3, HIGH);
  digitalWrite(g3, LOW);
  digitalWrite(pedred, HIGH);
  digitalWrite(pedgreen, LOW);
  delay(5000);

  digitalWrite(r1, HIGH);
  digitalWrite(y1, LOW);
  digitalWrite(g1, LOW);
  digitalWrite(r2, HIGH);
  digitalWrite(y2, LOW);
  digitalWrite(g2, LOW);
  digitalWrite(r3, HIGH);
  digitalWrite(y3, LOW);
  digitalWrite(g3, LOW);
  digitalWrite(pedred, LOW);
  digitalWrite(pedgreen, HIGH);
  delay(6500);

  digitalWrite(r1, HIGH);
  digitalWrite(r2, HIGH);
  digitalWrite(r3, HIGH);
  digitalWrite(y1, LOW);
  digitalWrite(y2, LOW);
  digitalWrite(y3, LOW);
  digitalWrite(g1, LOW);
  digitalWrite(g2, LOW);
  digitalWrite(g3, LOW);
  digitalWrite(pedred, HIGH);
  digitalWrite(pedgreen, LOW);
  delay(750);
  digitalWrite(g1, HIGH);
  digitalWrite(r1, LOW);
  delay(5000);

  digitalWrite(r1, LOW);
  digitalWrite(r2, HIGH);
  digitalWrite(r3, HIGH);
  digitalWrite(y1, HIGH);
  digitalWrite(y2, LOW);
  digitalWrite(y3, LOW);
  digitalWrite(g1, LOW);
  digitalWrite(g2, LOW);
  digitalWrite(g3, LOW);
  delay(5000);
  digitalWrite(r1, HIGH);
  digitalWrite(r2, HIGH);
  digitalWrite(r3, HIGH);
  digitalWrite(y1, LOW);
  digitalWrite(y2, LOW);
  digitalWrite(y3, LOW);
  digitalWrite(g1, LOW);
  digitalWrite(g2, LOW);
  digitalWrite(g3, LOW);
  delay(750);
  digitalWrite(g2, HIGH);
  digitalWrite(r2, LOW);
  delay(5000);

  digitalWrite(r1, HIGH);
  digitalWrite(r2, LOW);
  digitalWrite(r3, HIGH);
  digitalWrite(y1, LOW);
  digitalWrite(y2, HIGH);
  digitalWrite(y3, LOW);
  digitalWrite(g1, LOW);
  digitalWrite(g2, LOW);
  digitalWrite(g3, LOW);
  delay(5000);
  digitalWrite(r1, HIGH);
  digitalWrite(r2, HIGH);
  digitalWrite(r3, HIGH);
  digitalWrite(y1, LOW);
  digitalWrite(y2, LOW);
  digitalWrite(y3, LOW);
  digitalWrite(g1, LOW);
  digitalWrite(g2, LOW);
  digitalWrite(g3, LOW);
  delay(750);
  digitalWrite(g3, HIGH);
  digitalWrite(r3, LOW);
  delay(5000);

  digitalWrite(r1, HIGH);
  digitalWrite(r2, HIGH);
  digitalWrite(r3, LOW);
  digitalWrite(y1, LOW);
  digitalWrite(y2, LOW);
  digitalWrite(y3, HIGH);
  digitalWrite(g1, LOW);
  digitalWrite(g2, LOW);
  digitalWrite(g3, LOW);
  delay(5000);


}

the code for the pedestrian crossing is much longer as I just copy and paste the code over and over to avoid the loop but it wouldn't let me add all of it in this forum.

How is your button wired? Your current code will only work if there is a pull-down resistor on the pin attached to the button.

Because of your use of delay(), your code only reads the button once every 16.5 seconds. This might make it seem that the button is not working. This is why you should never use long delays in your code. Instead, use millis(), as demonstrated in File > Examples > 02.Digital > BlinkWithoutDelay and this tutorial:

More on the subject:
https://forum.arduino.cc/index.php?topic=223286.0

pert:
This is why you should never use long delays in your code.

"Never" is too large a generalisation. It's fine to use delays, even long ones, in cases where the code doesn't need to react to anything or interleave activities. Of course, in the current case you're right, delay is the culprit, but it's not right to say "never".

The code in this thread here, just as a f'rinstance, is fine with delays given that OP's objective. It's not very elegant though, and will be difficult to enhance and maintain, but under the limited circumstances given there, it's fine.

In years past, I wrote several sketches using long delay thinking "it doesn't matter if this code is blocking" that was true at the time, but later I wanted to add some features that would not work with the blocking code. I had to do much more work to rewrite the code to be non-blocking than I would have if I had written it non-blocking to begin with.

That's actually what happened here. They wrote some traffic light code using long blocking delays. No problem. There is no need for that code to be non-blocking. But then they tried to add a pedestrian crossing. Big problem! Now it's time to rewrite it all.

Non-blocking code is much more future proof. If you fully understand the future of your code, then go ahead with the delay(). But so often the future turns out different than we expected it to.

pert:
Because of your use of delay(), your code only reads the button once every 16.5 seconds. This might make it seem that the button is not working. This is why you should never use long delays in your code. Instead, use millis(), as demonstrated in File > Examples > 02.Digital > BlinkWithoutDelay and this tutorial:
https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay

More on the subject:
Demonstration code for several things at the same time - Project Guidance - Arduino Forum

I have no idea how to use it, can you show how?

Spend more time studying the tutorials.

Once you think you understand it, do some experiments with the code.

Change the BlinkWithoutDelay code so the LED blinks faster. Upload the modified sketch to your Arduino and make sure the change worked as expected.

Change the BlinkWithoutDelay code so the LED blinks faster when the button is pressed and slower when it's not pressed. Upload the modified sketch to your Arduino and make sure the change worked as expected.

Learning takes time. It's only been about 35 minutes since I posted about BlinkWithoutDelay. Chances are you received it after that. It's well worth investing some hours into learning this essential concept. After that, if you still have some questions, come back here with your best attempt at converting your code to be non-blocking.

const int r1 = 1;
const int y1 = 2;
const int g1 = 3;

const int r2 = 4;
const int y2 = 5;
const int g2 = 6;

const int r3 = 7;
const int y3 = 8;
const int g3 = 9;

const int pedred =  10;// the number of the LED pin
const int pedgreen =  11;// the number of the LED pin

int button =  13;// the number of the LED pin

// Variables will change:
int ledState = LOW;             // ledState used to set the LED

// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store
unsigned long previousMillis = 0;        // will store last time LED was updated

// constants won't change:
const long interval = 10000;          // interval at which to blink (milliseconds)

void setup() {
  // set the digital pin as output:
  pinMode (r1, OUTPUT);
  pinMode (y1, OUTPUT);
  pinMode (g1, OUTPUT);

  pinMode (r2, OUTPUT);
  pinMode (y2, OUTPUT);
  pinMode (g2, OUTPUT);

  pinMode (r3, OUTPUT);
  pinMode (y3, OUTPUT);
  pinMode (g3, OUTPUT);

  pinMode (button, INPUT);

  pinMode (pedred, OUTPUT);
  pinMode (pedgreen, OUTPUT);
}

void loop() {
  digitalWrite(r1, HIGH);
  digitalWrite(r2, HIGH);
  digitalWrite(r3, HIGH);
  digitalWrite(y1, LOW);
  digitalWrite(y2, LOW);
  digitalWrite(y3, LOW);
  digitalWrite(g1, LOW);
  digitalWrite(g2, LOW);
  digitalWrite(g3, LOW);
  digitalWrite(pedred, HIGH);
  digitalWrite(pedgreen, LOW);
  delay(750);
  digitalWrite(g1, HIGH);
  digitalWrite(r1, LOW);
  delay(5000);
  digitalWrite(r1, LOW);
  digitalWrite(r2, HIGH);
  digitalWrite(r3, HIGH);
  digitalWrite(y1, HIGH);
  digitalWrite(y2, LOW);
  digitalWrite(y3, LOW);
  digitalWrite(g1, LOW);
  digitalWrite(g2, LOW);
  digitalWrite(g3, LOW);
  delay(5000);
  digitalWrite(r1, HIGH);
  digitalWrite(r2, HIGH);
  digitalWrite(r3, HIGH);
  digitalWrite(y1, LOW);
  digitalWrite(y2, LOW);
  digitalWrite(y3, LOW);
  digitalWrite(g1, LOW);
  digitalWrite(g2, LOW);
  digitalWrite(g3, LOW);
  delay(750);
  digitalWrite(g2, HIGH);
  digitalWrite(r2, LOW);
  delay(5000);
  digitalWrite(r1, HIGH);
  digitalWrite(r2, LOW);
  digitalWrite(r3, HIGH);
  digitalWrite(y1, LOW);
  digitalWrite(y2, HIGH);
  digitalWrite(y3, LOW);
  digitalWrite(g1, LOW);
  digitalWrite(g2, LOW);
  digitalWrite(g3, LOW);
  delay(5000);
  digitalWrite(r1, HIGH);
  digitalWrite(r2, HIGH);
  digitalWrite(r3, HIGH);
  digitalWrite(y1, LOW);
  digitalWrite(y2, LOW);
  digitalWrite(y3, LOW);
  digitalWrite(g1, LOW);
  digitalWrite(g2, LOW);
  digitalWrite(g3, LOW);
  delay(750);
  digitalWrite(g3, HIGH);
  digitalWrite(r3, LOW);
  delay(5000);
  digitalWrite(r1, HIGH);
  digitalWrite(r2, HIGH);
  digitalWrite(r3, LOW);
  digitalWrite(y1, LOW);
  digitalWrite(y2, LOW);
  digitalWrite(y3, HIGH);
  digitalWrite(g1, LOW);
  digitalWrite(g2, LOW);
  digitalWrite(g3, LOW);
  delay(5000);

  unsigned long currentMillis = millis();

  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(r1, ledState);
    digitalWrite(y1, ledState);
  }
}

What do i do after this?
How do i cause a button to interrupt this loop to perform another function once and return to this loop?

How do i cause a button to interrupt this loop to perform another function once and return to this loop?

Take a deep breath and restructure the code to do away with the delay()s which will currently prevent the button input being read frquently.

See Using millis() for timing. A beginners guide, Several things at the same time and look at the BlinkWithoutDelay example in the IDE.

@No_Name, I just wrote a totally delay()-less sketch for a traffic light cross-roads (ns and ew, so only 2 sets of ryg not your 3) with a pedestrian button. (Is yours a cross roads with a diagonal too, or what?)

It might not be functionally identical to what you require (apart from having only 2 roads not 3): what I decided to do was have a short red-all-round to empty the intersection before either road goes green, as is common in parts of the world and is in any case good traffic engineering. Pressing the pedestrian button at any time in the cycle (it's all delay()-less) sets a pedPending flag, which essentially extends the next red-all-round by some value. (It would be crazy to suddenly change a green to red when the button is pressed, so I wait until both roads would be red anyway, then just make that a bit longer, with the pedestrian light green.)

All done with switch...case and the phase timings are in an array.

The led on pin 13 is also used as a sort of "pulse" to indicate there's no blocking.

I won't post it unless you specifically ask, on the assumption that you might want to battle bravely onward and get it all delay()-less yourself :wink:

How do i cause a button to interrupt this loop

My button doesn't actually "interrupt" the normal flow: it's read every-time through loop() and if it's pressed the flag is set to extend the red-all-round time at the next opportunity. Once the pedestrian phase starts, the flag is cleared for next time.)

@No_Name, I just wrote a totally delay()-less sketch for a traffic light cross-roads (ns and ew, so only 2 sets of ryg not your 3) with a pedestrian button. (Is yours a cross roads with a diagonal too, or what?)

A T-Junction