Bridge Traffic Light Project

Okay, so I’m building a project that is essentially a one laned bridge with traffic signals at each end. There are motion sensors at each end of the bridge to sense when a car pulls up and sends the signal to change the lights to green on that end of the bridge. I’ve attached my code and a rough drawing of my hook ups. The resistors I used are 460 ohms. As you can see there is a programmed time that both the lights will be red while the bridge clears. My problem is this: It works for the first iteration (Light is green on north side and red on south side. Motion is sensed on the south side so it goes through the waiting and the flashing yellow light then the south light turns green and the north is red), but after this first iteration it no longer wants to work. Motion can be sensed on the North side but the lights do not change. Do you see anything in the code or my hookup that could be causing this issue?? I’m becoming lost trying to figure it out. Thanks in advance.

// what each pin is designated as and time in between flashes of the yellow light 
#define northSensor 3
#define southSensor 13
#define northRed 0
#define northYellow 1
#define northGreen 2
#define southRed 10
#define southYellow 11
#define southGreen 12
#define yellowTime 1000

// the boolean is “true” when cars coming from North and “false” when from the South
boolean carsNorth = true; 

// amount of time to let the cars clear off the bridge before the other side turns green
int  clearTime = 5000;

// amount of time delay in between color changes
int  delayChange = 1500;

void setup()
{
  // set the mode of the pins to input or output
 pinMode(northSensor, INPUT);
 pinMode(southSensor, INPUT);
 pinMode(northRed, OUTPUT);
 pinMode(northYellow, OUTPUT);
 pinMode(northGreen, OUTPUT);
 pinMode(southRed, OUTPUT);
 pinMode(southYellow, OUTPUT);
 pinMode(southGreen, OUTPUT);
 
 // initial colors of the lights will be set with North green first and South at red.
 digitalWrite(northRed, LOW);
 digitalWrite(northYellow, LOW);
 digitalWrite(northGreen, HIGH);
 digitalWrite(southRed, HIGH);
 digitalWrite(southYellow, LOW);
 digitalWrite(southGreen, LOW);
}






void loop()
{
 // signals cars at the north entrance
 if ( digitalRead(northSensor) == HIGH )  
{
  // only continue this loop if traffic is currently going through south entrance
  if ( carsNorth != true )
 {


 // change the south bound lights from green to yellow then yellow to red
 digitalWrite(southGreen, LOW);
 delay(delayChange);
 digitalWrite(southYellow, HIGH);
 delay(delayChange);
 digitalWrite(southYellow, LOW);
 digitalWrite(southRed, HIGH);

 // allow traffic to clear off the bridge before north side flashes yellow/turns green
 delay(clearTime);

// give “yield” blinking yellow light to north side to allow them to go as long as no one          // else is on the bridge
int a = 0;
 for ( int x = 0; a < 10; a++ )
{
   digitalWrite(northYellow, LOW);
   delay(delayChange);
   digitalWrite(northYellow, HIGH);
   delay(delayChange);
}

// change north lights from red to green to allow traffic flow
digitalWrite(northRed, LOW);
digitalWrite(northYellow, LOW);
digitalWrite(northGreen, HIGH);
 }
}



// signals cars at the south entrance
 if ( digitalRead(southSensor) == HIGH )  
{
  // only continue this loop if traffic is currently going through north entrance
  if ( carsNorth == true )
{
 
 // change the north bound lights from green to yellow then yellow to red
 digitalWrite(northGreen, LOW);
 delay(delayChange);
 digitalWrite(northYellow, HIGH);
 delay(delayChange);
 digitalWrite(northYellow, LOW);
 digitalWrite(northRed, HIGH);

 // allow traffic to clear off the bridge before south side flashes yellow/turns green
 delay(clearTime);

// give “yield” blinking yellow light to south side to allow them to go as long as no one          // else is on the bridge
int a = 0;
 for ( int x = 0; a < 10; a++ )
{
   digitalWrite(southYellow, LOW);
   delay(delayChange);
   digitalWrite(southYellow, HIGH);
   delay(delayChange);
}

// change south lights from red to green to allow traffic flow
digitalWrite(southRed, LOW);
digitalWrite(southYellow, LOW);
digitalWrite(southGreen, HIGH);
   }
 }
}

Please modify your post and use the code button </> so your code looks like this and is easy to copy to a text editor. Then I will study it. See How to use the Forum. Your code is too long to study quickly.

…R

Where in this code do you ever set the value of carsNorth?

// the boolean is "true" when cars coming from North and "false" when from the South
boolean carsNorth = true;

That's at the top right after I defined my pins. Is that what you meant?

wooderson123:

// the boolean is "true" when cars coming from North and "false" when from the South

boolean carsNorth = true;





That's at the top right after I defined my pins. Is that what you meant?

OK, so that's its initial value. Should that value ever change in the program? Is that supposed to represent something? Like should it be true when cars are moving north and false when cars are moving south or something like that?

Yes, at least from my understanding of writing the code, it should be true when the cars are moving north and false when they are moving south. But, like I said, I'm new at this so if it seems like I don't know what the hell I'm talking about theres a good possibility that I don't lol. Because there must be something wrong with the code.

wooderson123:
Yes, at least from my understanding of writing the code, it should be true when the cars are moving north and false when they are moving south. But, like I said, I'm new at this so if it seems like I don't know what the hell I'm talking about theres a good possibility that I don't lol. Because there must be something wrong with the code.

Then you need a line of code that sets its value when you detect cars moving one way or the other. The way you have it it will always be at its initial value as you have no code anywhere to change that value.

Could you give me an example please? I'm kinda confused as to what you mean. It sounds like that's definitely the problem but I'm not sure how to cure it.

OK, in the part of the code where you detect a car going north, put:

carsNorth = true;

and in the part of the code where you detect a car going south put

carsNorth = false;

I'm not really sure how to help you because I'm not real sure what part you aren't understanding. Surely it's not what I just wrote.

Really, it might make more sense to have two booleans here. carsNorth and carsSouth. That way, both false could mean there are simply no cars and both true means you have to make a decision which direction to let go first.

Hi,
You have three states on the bridge, not two.
State1= NO CARS ON THE BRIDGE.
State2=Cars Going North.
State3=Cars Going South.

Also you have more than 3 combinations of lights because you have to clear the bridge.

Cars travelling South
Cars travelling South and clearing
NO Cars
Cars travelling North
Cars travelling North and clearing

If there are no cars on the bridge, I'd have RED at both ends, then instantly change to GREEN the end that next gets a car.
Activation would be quick for either end.

Tom..... :slight_smile:

Hmmm. All of you bring up some good points. It's getting pretty late in my part of the world so I'll try some of the suggestions here tomorrow. Thanks for all your help so far.

OK, a lot of things this code needs and it is late for me now so I can't suss them all out in actual code (as well).

You need to break your code down into functions to make it readable. Names such as NorthRed need to be used for functions rather than pins; that function should write NRed HIGH whilst writing NYel and NGrn LOW. It is by the way, a "void" function; it has no return value.

That is one function, you write the others to match - if you want flashing yellow, then use NorthOff as well. This is "self-documenting code", when you write NorthRed(); it does just that with no confusion and no "fluff".

In the same vein, you probably want a function NorthFlashYellow containing the loop to implement this. This way, the main loop will be extremely clear in its operation steps.

And the setup() will also use the corresponding functions to initialise the lights. Best if the functions are all defined before setup() and loop().

Now whilst Tom lives in the same country as myself, and whilst his suggestion of all Red as the resting state has great merit, he will recognise that the automated road works lights (radio linked) that we have here and when using motion sensors use exactly the paradigm you have here, do indeed usually rest in the last (Green) state triggered.

When you have implemented my suggestions to make the code clearer, you should be able to see whether your code is completely symmetric; that is, the two principal phases should consist of exactly matching code differing only by exchanging North and South in every corresponding part. There is no need for a "carsNorth" switch in this code model (but it would be appropriate as part of moving to a State Machine).

Note that each phase should be re-trigerrable to a certain limit - that is, if a new car arrives to a green light, it needs to extend the period of the green in order for the car to traverse unless a car appears at the opposite end, in which case it needs to change to red but extend the delay until the other end gets green, as the car which saw green will now be traversing. (This sequence is more complex than it first appears! :astonished: )