Programming Traffic light 3 way junction with pedestrian light.

Hi, I'm new to the arduino world and I'm working on my current project. I got all of my coding's working but the problem is my switch. After void setup, the coding will go to void loop right? Before starting the void loop, I ask for the input of my switch but my problem now is i have to long-press my switch button to make the input HIGH. if I press it only once, it won't read my switch input. Yes I did find on how the button can act like a toggle switch. But using that coding, my traffic light won't move smoothly, it stop to get the input from the switch. I hope you guys can help me with this one.

int carRed1 = 3; //car lights being assigned
int carYellow1 = 4;
int carGreen1 = 5;
int carRed2 = 6;
int carYellow2 = 7;
int carGreen2 = 8;
int carRed3 = 9;
int carYellow3 = 10;
int carGreen3 = 11;
int pedRed = 12; //ped lights being assigned
int pedGreen = 13; 
int button = 2; // button pin
int crossTime = 5000;  //crossing time given to pedestrians
int var;
unsigned long changeTime ; // collects the time since the button was last pressed
int state;
void setup () {
  
  pinMode(carRed1, OUTPUT);      
  pinMode(carYellow1, OUTPUT);
  pinMode(carGreen1, OUTPUT);
  pinMode(pedRed, OUTPUT);
  pinMode(pedGreen, OUTPUT);
  pinMode(carRed2, OUTPUT);      
  pinMode(carYellow2, OUTPUT);
  pinMode(carGreen2, OUTPUT);
  pinMode(carRed3, OUTPUT);      
  pinMode(carYellow3, OUTPUT);
  pinMode(carGreen3, OUTPUT);
  pinMode(button, INPUT);

  
  digitalWrite(carGreen1,HIGH); //start with green car light on
  digitalWrite(pedRed, HIGH); //start with red ped light on
 

 


  } 
  

void loop(){
 // read the state of the pushbutton value:
     
   state = digitalRead(button);
  if(state==HIGH && (millis() - changeTime) >5000) {
    Serial.println("pressed");
    delay(10000);
    changeLights();
  }
  if(state== LOW && (millis() - changeTime) >5000) {
    Serial.println("released");
    normalLights();
  }

 
} 


void normalLights(){
  digitalWrite(carGreen1,HIGH);
  digitalWrite(carRed2,HIGH); //start with green car light on
  digitalWrite(carRed3,HIGH); //start with green car light on
  delay(2000);

  digitalWrite(carYellow1, HIGH);
  digitalWrite(carGreen1, LOW);
  delay(3000);
  
 
  digitalWrite(carGreen2,HIGH); //start with green car light on
  digitalWrite(pedRed, HIGH); //start with red ped light on
  digitalWrite(carRed1,HIGH); //start with green car light on
  digitalWrite(carYellow1,LOW);
  digitalWrite(carRed2,LOW);
  digitalWrite(carRed3,HIGH); //start with green car light on
  delay(7000);

  
  
  digitalWrite(carYellow2, HIGH);
  digitalWrite(carGreen2, LOW);
  delay(3000);

  digitalWrite(carGreen3,HIGH); //start with green car light on
  digitalWrite(pedRed, HIGH); //start with red ped light on
  digitalWrite(carRed1,HIGH); //start with green car light on
  digitalWrite(carYellow2,LOW);
  digitalWrite(carRed2,HIGH);
  digitalWrite(carRed3,LOW); //start with green car light on
  delay(7000);

  digitalWrite(carGreen3, LOW);
  digitalWrite(carYellow3, HIGH);
  delay(3000);

  digitalWrite(carRed3, HIGH);
  digitalWrite(carYellow3,LOW);
  delay(8000);
  }
void changeLights() {
  digitalWrite(carRed3, HIGH);
  digitalWrite(carGreen1,LOW);  //green car light off
  digitalWrite(carYellow1,HIGH); // yellow car light on
  digitalWrite(carGreen2,LOW);  //green car light off
  digitalWrite(carGreen3,LOW);  //green car light off
  delay(2000); //wait 2 seconds

  digitalWrite(carYellow1,LOW); // yellow car light off
  digitalWrite(carRed1,HIGH); //red car light on
  digitalWrite(carYellow2,LOW); // yellow car light off
  digitalWrite(carRed2,HIGH);
  digitalWrite(carYellow3,LOW); // yellow car light off
  digitalWrite(carRed3,HIGH);
  delay(1000); //wait 1 second to turn on ped light

  digitalWrite(pedRed,LOW); //red ped light off
  digitalWrite(pedGreen,HIGH); //green ped light on. allow crossing
 
  delay(crossTime); //delay preset time of 5 seconds
  //flashing of ped green light
  for (int x=0; x<10; x++){
    digitalWrite(pedGreen,HIGH);
    delay(250);
    digitalWrite(pedGreen,LOW);
    delay(250);
  }
 
  digitalWrite(pedRed, HIGH); //turn red ped light on
  digitalWrite(carRed1, LOW);
  delay(100);
  
   
  
  digitalWrite(carGreen1,HIGH); //car green light on
  digitalWrite(carRed1,LOW); //car red light off
 
  setup;
  changeTime = millis(); //record time since last lights change
  
  }

sketch_oct26b.ino (3.68 KB)

You're going to want to get rid of the delays in your code.

You'll want to check the buttons and set some state variable based on the button presses. A separate section of code will act on these state variables.

There's an example of traffic light code in this thread. I think a lot of the concepts apply to your program.

DuaneDegn:
You're going to want to get rid of the delays in your code.

not required.
once you change from green to jello to red.....
you want no interruptions. there is nothing that would need to be done.
no buttons, no car sensors....
one loop to look for car or button activation, but once the change has occurred, there is no need to do two things at once.
personally, I am surprised that in 2015, the fire/medial/police do not have remote buttons that can change lights.
it would seem that a fast light to allow traffic to get out of the way of a fire truck or ambulance would be a good thing. as well as a red light to block traffic to stop a bad guy.

dave-in-nj:
not required.
once you change from green to jello to red.....
you want no interruptions. there is nothing that would need to be done.
no buttons, no car sensors....
one loop to look for car or button activation, but once the change has occurred, there is no need to do two things at once.
personally, I am surprised that in 2015, the fire/medial/police do not have remote buttons that can change lights.
it would seem that a fast light to allow traffic to get out of the way of a fire truck or ambulance would be a good thing. as well as a red light to block traffic to stop a bad guy.

Thanks for the correction. I assumed there was more going on.

I'd think you'd want to know if there's are cars waiting at the light.

What happens when the light turns green for the cars and someone immediately presses the walk button? Shouldn't there be some sort of time interval to allow any stopped cars to pass? I suppose this isn't up to us to decide.

DuaneDegn:
You're going to want to get rid of the delays in your code.

but you are correct that he is mixing both millis() and delay.
if you delay for 10 seconds, a 5 second millis() call is waste.

DuaneDegn:
Thanks for the correction. I assumed there was more going on.

I'd think you'd want to know if there's are cars waiting at the light.

What happens when the light turns green for the cars and someone immediately presses the walk button? Shouldn't there be some sort of time interval to allow any stopped cars to pass? I suppose this isn't up to us to decide.

yes.
but, you CAN do it either way.
digital write - green light
delay (10000)
if (senseo == HIGH ) // means button or car wants to cross
then start to cycle through the program.
if you want to do just one loop, it is not that large of a program.
if you jump from loop to loop, it is not that hard to do either.
considder
if (last color == red && newColor==GREEN)
delay(10 seconds)
it would only delay for 10 seconds after it went green
then the switch would come into play for cross traffic.

this is just cobbled together

use millis() as you noted, because it was easier for the timing of forcing the green light to stay on for a bit.
then, the rest of the code is basically just a step, delay, step, delay...
then it comes back to wait for a switch.

I would add more mills() timings.
to see how long since the last cross car tripped the switch, give them 2-3 seconds before changing.

a note here is that if there were 10 cars, by the time 5 went, the timing and spacing between cars would get longer and longer. also, if the game let out, there might be 100's of cars, so there should be a maximum for each the cross street.

void loop() {

  duration = (millis() - then); // then is set when cross green goes off
    if duration <= 9999) {
       delay(10000);
  }

  if (pedestrianSwitch = HIGH) { // include any other sensors
  changeFlag = HIGH;
}

if (phaseOneFlag == LOW) {   // goes low after crossRed is on.
  if (changeFlag == HIGH) {
      digitalWrite (mainGreen = OFF );
      digitalWrite (mainYellow = ON );
      delay(5000):
      digitalWrite(mainYellow, OFF);
      digitalWrite(mainRed, ON);
      delay(500);
      digitalWrite(crossGreen, ON);
      delay(5000); // holds cross green on for the first car.
      phaseOneFlag = HIGH);
      phaseTwoFlag = HIGH);

      }
    }

  if (phaseTwoFlag == HIGH) {
     if (crossSensor = HIGH) {  // checks to see if there are more cars
       delay (3000); // keeps checking and keeps green if lots of cars
    }
  }

  if (crossSensor == LOW) { // no cars sensed
    phaseTwoFlag == LOW); // stops looking for cars
    digitalWrite(crossGreen, OFF;
    digitalWrite(crossYellow, ON);
    delay(3000);
    digitalWrite(crossYellow, OFF);
    digitalWrite(crossRed, ON);
    delay(500);
    phaseOneFlag = LOW;
    then = millis();
  }
}

Here's an example of some of my code - just for the pedestrian crossing.

It includes a couple of necessary features, a guaranteed minimum "green" time for the traffic and a lesser delay after the button is pressed to forestall "chicken" gaming.

I'll let you figure what pin 13 does. :grinning:

// Pedestrian crossing lights

const int led13Pin =  13;    // LED pin number
const int PgrnPin =  2;      // Pedestrian Green
const int PredPin =  3;
const int RgrnPin =  5;      // Road Green
const int RyelPin =  6;
const int RredPin =  7;
const int button1 =  10;

int led13State = LOW;        // initialise the LED
int PgrnState = LOW;
int PredState = LOW;
int RgrnState = LOW;
int RyelState = LOW;
int RredState = LOW;
char bstate1 = 0;
boolean press = false;

unsigned long count1 = 0;   // will store last time LED was updated
unsigned long count2 = 0;
unsigned long count3 = 0;
unsigned long count4 = 0;
unsigned long count5 = 0;
unsigned long bcount1 = 0; // button debounce timer.  Replicate as necessary.

// Have we completed the specified interval since last confirmed event?
// "marker" chooses which counter to check 
boolean timeout(unsigned long *marker, unsigned long interval) {
  if (millis() - *marker >= interval) { 
    *marker += interval;    // move on ready for next interval
    return true;       
  } 
  else return false;
}

void setout(unsigned long *marker) {
  *marker = millis();             // initialise
}

// Deal with a button read; true if button pressed and debounced is a new event
// Uses reading of button input, debounce store, state store and debounce interval.
boolean butndown(char button, unsigned long *marker, char *butnstate, unsigned long interval) {
  switch (*butnstate) {               // Odd states if was pressed, >= 2 if debounce in progress
  case 0: // Button up so far, 
    if (button == HIGH) return false; // Nothing happening!
    else { 
      *butnstate = 2;                 // record that is now pressed
      *marker = millis();             // note when was pressed
      return false;                   // and move on
    }

  case 1: // Button down so far, 
    if (button == LOW) return false; // Nothing happening!
    else { 
      *butnstate = 3;                 // record that is now released
      *marker = millis();             // note when was released
      return false;                   // and move on
    }

  case 2: // Button was up, now down.
    if (button == HIGH) {
      *butnstate = 0;                 // no, not debounced; revert the state
      return false;                   // False alarm!
    }
    else { 
      if (millis() - *marker >= interval) {
        *butnstate = 1;               // jackpot!  update the state
        return true;                  // because we have the desired event!
      }
      else 
        return false;                 // not done yet; just move on
    }

  case 3: // Button was down, now up.
    if (button == LOW) {
      *butnstate = 1;                 // no, not debounced; revert the state
      return false;                   // False alarm!
    }
    else { 
      if (millis() - *marker >= interval) {
        *butnstate = 0;               // Debounced; update the state
        return false;                 // but it is not the event we want
      }
      else 
        return false;                 // not done yet; just move on
    }
  default:                            // Error; recover anyway
    {  
      *butnstate = 0;
      return false;                   // Definitely false!
    }
  }
}


void setleds() {
  digitalWrite(led13Pin, led13State);
  digitalWrite(PredPin, PredState);
  digitalWrite(PgrnPin, PgrnState);
  digitalWrite(RredPin, RredState);
  digitalWrite(RyelPin, RyelState);
  digitalWrite(RgrnPin, RgrnState);
}

boolean ispress() { // One-directional read of button - sets but does not clear!
  if (butndown(digitalRead(button1), &bcount1, &bstate1, 10UL )) {
    press = true;
  } 
  return(press);
}

void setup() {
  Serial.begin(9600);
  pinMode(led13Pin, OUTPUT);      
  pinMode(PgrnPin, OUTPUT);      
  pinMode(PredPin, OUTPUT);      
  pinMode(RgrnPin, OUTPUT);      
  pinMode(RyelPin, OUTPUT);      
  pinMode(RredPin, OUTPUT);      
  pinMode(button1, INPUT);      
  digitalWrite(button1,HIGH);        // internal pullup all versions
  press = false;
  Serial.println("Starting ...");
}

void loop() {
  // All red phase
  RredState = HIGH;
  RyelState = LOW; 
  RgrnState = LOW; 
  PredState = HIGH;
  PgrnState = LOW; 
  setleds();
  Serial.println("Red phase");
  setout(&count3);  
  while (!timeout(&count3, 3000UL )) {
    ispress();  // Check on the button
  }

  // Road Green
  RredState = LOW;
  RyelState = LOW; 
  RgrnState = HIGH; 
  PredState = HIGH;
  PgrnState = LOW; 
  setleds();
  Serial.println("Road green");
  setout(&count3);  
  while (!timeout(&count3, 8000UL )) { // Reasonable time on green
    ispress();  // Check on the button
  }
  Serial.println("Green stale, wait on button");

  while ( press == false )  // Now wait for the button 
  {
    if (timeout(&count2, 300UL )) {
      if (led13State == LOW) {
        led13State = HIGH;
      }
      else {
        led13State = LOW; 
      } 
      digitalWrite(led13Pin, led13State);
    }
    ispress();   
  }
  led13State = LOW; 
  digitalWrite(led13Pin, led13State);

  Serial.println("Button sensed");
  setout(&count3);  
  while (!timeout(&count3, 4000UL )) { // Do not respond immediately!
  }

  // Road Yellow
  RredState = LOW;
  RyelState = HIGH; 
  RgrnState = LOW; 
  PredState = HIGH;
  PgrnState = LOW; 
  setleds();
  Serial.println("Road yellow");
  setout(&count3);  
  while (!timeout(&count3, 5000UL )) {
  }

  // Road Red
  RredState = HIGH;
  RyelState = LOW; 
  RgrnState = LOW; 
  PredState = HIGH;
  PgrnState = LOW; 
  setleds();
  Serial.println("Road red");
  setout(&count3);  
  while (!timeout(&count3, 3000UL )) {
  }

  // Walk Green
  RredState = HIGH;
  RyelState = LOW; 
  RgrnState = LOW; 
  PredState = LOW;
  PgrnState = HIGH; 
  setleds();
  press = false;  
  Serial.println("Walk");
  setout(&count3);  
  while (!timeout(&count3, 6000UL )) {
  }

  // Flash Don't Walk
  RredState = HIGH;
  RyelState = LOW; 
  RgrnState = LOW; 
  PgrnState = LOW; 
  Serial.println("Flash Don't Walk");
  setout(&count3);  
  while (!timeout(&count3, 7000UL )) {
    if (timeout(&count2, 500UL )) {
      if (PredState == LOW) {
        PredState = HIGH;
      }
      else {
        PredState = LOW; 
      } 
      setleds();
    }
    ispress();  // Check on the button
  }

}

void oldloop() {
  // Toggle LED if button debounced
  if (butndown(digitalRead(button1), &bcount1, &bstate1, 10UL )) {
    if (led13State == LOW) {
      led13State = HIGH;
    }
    else {
      led13State = LOW; 
    } 
    digitalWrite(led13Pin, led13State);
  } 

  // Act if the latter time (ms) has now passed on this particular counter,
  if (timeout(&count2, 300UL )) {
    if (PgrnState == LOW) {
      PgrnState = HIGH;
    }
    else {
      PgrnState = LOW; 
    } 
    digitalWrite(PgrnPin, PgrnState);
  } 

  if (timeout(&count3, 600UL )) {
    if (PredState == LOW) {
      PredState = HIGH;
    }
    else {
      PredState = LOW; 
    } 
    digitalWrite(PredPin, PredState);
  } 

  if (timeout(&count4, 400UL )) {
    if (RgrnState == LOW) {
      RgrnState = HIGH;
    }
    else {
      RgrnState = LOW; 
    } 
    digitalWrite(RgrnPin, RgrnState);
  } 

  if (timeout(&count5, 800UL )) {
    if (RredState == LOW) {
      RredState = HIGH;
    }
    else {
      RredState = LOW; 
    } 
    digitalWrite(RredPin, RredState);
  } 
}