Advertisement
arduino traffic lights

Arduino Traffic Light System for Intersections

Here is a traffic light system based on Arduino that can be used in a 3-way ond 4-way intersections. It has an additional blinking orange led that is used to signal when the pedestrians can cross the street. The code is a little bit complicated but I think you can understand how it works, right?

Check out this video below to see how the traffic lights system is working.

The code is written based on 4 situations:

  1. the first traffic light (TF1) has the red signal and the pedestrians ON; the second one (TF2) has green ON.
  2. TF1 has red and yellow ON; TF2 has yellow ON
  3. TF1 is green now and TF2 is red and pedestrians ON
  4. TF1 is yellow and TF2 is red and yellow

The schematic is too easy, all you have to do is connect the leds in series with a 470Ω resistor between the ground and the Arduino pins mentioned in the code.

arduino traffic lights

Code of the Arduino Traffic Lights Sketch

// Source: http://www.electroschematics.com/10178/arduino-traffic-light-system/
int trafficLights1[] = {2,3,4,5};	// red, yellow, green, pedestrians led pins
int trafficLights2[] = {6,7,8,9};	// red, yellow, green, pedestrians led pins
int situations = 4;
int duration[] = {8000,3000,10000,3000}; // duration of each situation
long previousCars = 0;
long previousPeds = 0;
long interval = 300;	//blink interval for pedestrians
int ledState = LOW;
int state;
int i = 0;

void setup()
{
  for(int i = 0; i < 4; i++) {
	  pinMode(trafficLights1[i], OUTPUT);
	  pinMode(trafficLights2[i], OUTPUT);
  }
	Serial.begin(9600);
}

void loop()
{	
	unsigned long currentMillis = millis();		
	if(currentMillis - previousCars < duration[i]) {			
		situation(i);		
	} else { 
		previousCars = currentMillis; 
		if(i >= situations) {
			i = 0;
			} else {
			i++;
		}		
	}
}

void activateTrafficLight1(String lights, int pedestrians) 
{	
	for(int x = 0; x < 3; x++) 
	{
		if(lights[x] == '0') state = LOW;
		if(lights[x] == '1') state = HIGH;
		digitalWrite(trafficLights1[x], state);	
	}
	if(pedestrians == 1) {
		blinkPed(trafficLights1[3]);
	} else {
		digitalWrite(trafficLights1[3], LOW);
	}
}

void activateTrafficLight2(String lights, int pedestrians)
{	
	for(int x = 0; x < 3; x++)
	{
		if(lights[x] == '0') state = LOW;
		if(lights[x] == '1') state = HIGH;
		digitalWrite(trafficLights2[x], state);
	}
	if(pedestrians == 1) {
		blinkPed(trafficLights2[3]);
	} else {
		digitalWrite(trafficLights2[3], LOW);
	}
}

void situation(int i)
{
	switch(i){
		case 0: 
			activateTrafficLight1("100",1); // 100 means red ON, yellow OFF, green OFF
			activateTrafficLight2("001",0); // the second parameter is for pedestrians
			break;							// 1 is ON and 0 is OFF
		case 1: 
			activateTrafficLight1("110",0); // 110: red ON, yellow ON, green OFF
			activateTrafficLight2("010",0);
			break;	
		case 2: 
			activateTrafficLight1("001",0);
			activateTrafficLight2("100",1);
			break;
		case 3:	
			activateTrafficLight1("010",0);
			activateTrafficLight2("110",0);
			break;	
	}
}

void blinkPed(int ped) {
	unsigned long currentMillis = millis();
	if(currentMillis - previousPeds > interval) {		
		previousPeds = currentMillis;		
		if (ledState == LOW)
		ledState = HIGH;
		else
		ledState = LOW;
		digitalWrite(ped, ledState);
	}	
}

24 Comments

Join the conversation!

Error! Please fill all fields.
  • memudgal

    I want to do a project named as “density based traffic signal with remote override in emergency”. Can someone give me code and pin diagram for this project please?

    • jim-brownzagmail-com

      @memudgal nobody in the world is likely to have an off-the-shelf solution to the level of code and schematics. Besides, there’s way too little info in your post for anyone to give a solution even if they had one.

  • jim-brownzagmail-com

    It’s the South African model.

    So let’s say it’s green for go ahead, then it’s green off/yellow on for caution and then yellow off/red on for stop. No overlap of any of the RYG. It’s customary to have a slight overlap of reds on cross-streets though, in an attempt to empty the intersection.

    Pedestrian is green then flashing red, which means no new pedestrians may step off, but those already in the intersections are kosher.

    Flashing turn filters, ie right turns across traffic same as you, and on mine I have a flashing yellow after the filter; I made that one up, it’s usually solid yellow.

    Filters may legally lead or lag the normal green, leading being more common for traffic engineering reasons, but mine happens to lag.

    I’ve got the RFID working: scan a tag then you’re asked to press a switch to enter emergency mode, when I simply set red all round. That has a non-blocking timer during which you may press the button, after which it times out and requires rescan of tag. In emergency mode, rescan tag and repress button to return to normal mode, which has an orderly restart since it would have been in the middle of some random phase when emergency mode started. (On second thoughts, it should check that and complete the current phase when emergency button pressed, or even complete a cycle. That’s next Christmas’ project…. )

    At the moment a scan of an unacceptable tag causes a slight block, need to fix that, but a good tag and waiting for the switch press is non-blocking.

    Sending you the code so far….

  • wl888bigpond-com

    Thats cool…will be very interested to see your full code when you are finished, I can then compare it to my version and get a better understanding of the enhancements.it should be great.
    out of curiosity…what country are you modelling the lights for?? My version is for Australia
    Doug

  • jim-brownzagmail-com

    Ok let me try that again… seems I deleted a chunk before posting last time.

    Nothing major compared to the original Doug. I have 6 LEDs per “light fitting”: the normal RYG, an extra G for turn filter, and an R and G for pedestrians, in that order. So in this phase…..

    case 2:
    #ifdef DEBUG
    Serial.println(“phase2”);
    #endif
    doNS(“000210”); //NS turn filter
    doEW(“100010”);
    break;

    …. the 4th LED, the turn filter, is set to blink since it’s a “2”.

    (My lights are NS for NorthSouth, and EW.)

    But of course such a blink needs to be delay-less, as we all know…..

    So doNS is this:

    void doNS(String lights)
    {
    for (int x = 0; x blinkInterval)
    {
    previousMillisBlink= currentMillisBlink;
    if (ledBlinkState==LOW)
    {
    ledBlinkState=HIGH;
    }
    else
    {
    ledBlinkState=LOW;
    }
    digitalWrite(z, ledBlinkState);
    }

    }

    Next step (long weekend ? ) is to:
    * add RTC and then have say 3 timing regimes, for am/pm peaks and rest of day
    *add RFID tag access for say emergency services to over-ride timing to another regime, say flash red all round.

    I just spent a while soldering LEDs and resistors to some DIP sockets for clip-in deployment to breadboard. (Soldered a wire along the cathodes to common them, so only needs one connection to ground.).When this project’s done they’ll be handy for any project needing LED indicators. (I might solder a couple of RGBs in to one as well: can never have too many blinkenlights.)

    Jim

    • jim-brownzagmail-com

      Ok I have no idea what’s going on, the exact same chunk went missing but I know it was there just before I hit submit.

      I’ll decipher your email addy and send it to you direct.

  • jim-brownzagmail-com

    Nothing major compared to the original Doug. I have 6 LEDs per “light fitting”: the normal RYG, an extra G for turn filter, and an R and G for pedestrians, in that order. So in this phase…..

    case 2:
    #ifdef DEBUG
    Serial.println(“phase2”);
    #endif
    doNS(“000210”); //NS turn filter
    doEW(“100010”);
    break;

    …. the 4th LED, the turn filter, is set to blink since it’s a “2”.

    (My lights are NS for NorthSouth, and EW.)

    But of course such a blink needs to be delay-less, as we all know…..

    So doNS is this:

    void doNS(String lights) //no pedestrian int anymore
    {
    for (int x = 0; x blinkInterval)
    {
    previousMillisBlink= currentMillisBlink;
    if (ledBlinkState==LOW)
    {
    ledBlinkState=HIGH;
    }
    else
    {
    ledBlinkState=LOW;
    }
    digitalWrite(z, ledBlinkState);
    }

    }

    Next step (long weekend 😉 ) is to:
    * add RTC and then have say 3 timing regimes, for am/pm peaks and rest of day
    *add RFID tag access for say emergency services to over-ride timing to another regime, say flash red all round.

    I just spent a while soldering LEDs and resistors to some DIP sockets for clip-in deployment to breadboard. (Soldered a wire along the cathodes to common them, so only needs one connection to ground.).When this project’s done they’ll be handy for any project needing LED indicators. (I might solder a couple of RGBs in to one as well: can never have too many blinkenlights.)

    Jim

    • jim-brownzagmail-com

      Hang on something went screwy in that last post…. let me try again, stand by.

  • wl888bigpond-com

    Thanks Jim
    I’m glad the sketch was of help. I would be interested in seeing your version of the code , always interested in improvements and learning new ways.
    thanks for the feedback
    Doug

  • jim-brownzagmail-com

    Nice approach, thanks. I made a subtle change: instead of having a separate field for the pedestrian blinker, as in activateTrafficLight1(“100”,1); , I used a value of 2 to mean blink, as in activateTrafficLight1(“200”,); That way, any pin can be blinked, like a flashing green for an across traffic turn, or flashing red all round for an emergency, etc etc.

  • wl888bigpond-com

    Hi all, sorry I forgot I had posted here, I have expanded the sketch to include Pedestrian Lights as well, there are now 18 different events, this has been fully tested on a prototype circuit board and works correctly. Enjoy.

    //Credits for Original Source: http://www.electroschematics.com/10178/arduino-traffic-light-system/
    //Arduino UNO R3
    //I made minor modifications to add a 3rd set of lights to give a “T” intersection
    //with pedestrian crossing when all lights are red
    //this version also has a RED arrow on 1 and 2.
    //the lights will eventually be powered from a port extender chip MCP23017 which gives 16 extra I/O ports
    //WL888
    #include // Comes with Arduino IDE
    #include “Adafruit_MCP23017.h”
    Adafruit_MCP23017 mcp;

    int trafficLights1[] = {8,9,10,7,12}; // red, yellow, green, red arrow, pedestrians led pins
    int trafficLights2[] = {4,5,6,3,11}; // red, yellow, green, red arrow, pedestrians led pins
    int trafficLights3[] = {0,1,2,11}; // red, yellow, green, pedestrians led pins
    int sequence = 19;
    int duration[] = {4000,4000,4000,4000,4000,3000,10000,7500,5000,3000,3000,3000,3000,4000,4000,3000,3000,4000,4000}; //largest is the WALK,DONT WALK, STOP WALK then RED arrow durations
    long previousCars = 0;
    long previousPeds = 0;
    long previousLight = 0;
    long walk = 5; //walk interval for pedestrians
    long dontwalk = 335; //dontwalk interval for flashing pedestrians
    long stopwalk = 5; //stop walk interval
    int ledState = LOW;
    int state;
    int i = 0;
    int x;
    void setup() {
    Serial.begin(9600); // debugging
    mcp.begin(); // use default address 0

    for(int i = 0; i < 6; i++) {
    mcp.pinMode(trafficLights1[i], OUTPUT);
    }
    for(int i = 0; i < 6; i++) {
    mcp.pinMode(trafficLights2[i], OUTPUT);
    }
    for(int i = 0; i < 5; i++) {
    mcp.pinMode(trafficLights3[i], OUTPUT);
    }
    for (int P=0;P<16;P++) {
    mcp.pullUp(P, HIGH); // turn on a 100K pullup internally
    mcp.digitalWrite(P,LOW);
    }
    mcp.digitalWrite(11, HIGH);
    }

    void loop()
    {
    unsigned long currentMillis = millis();
    if(currentMillis – previousCars = sequence) {
    i = 0;
    } else {
    i++;
    }
    }
    }

    void activateTrafficLight1(String lights, int pedestrians)
    {
    for(int x = 0; x < 4; x++)
    {
    if(lights[x] == '0') state = LOW;
    if(lights[x] == '1') state = HIGH;
    mcp.digitalWrite(trafficLights1[x], state);
    }
    if(pedestrians == 1) {
    pedWalk();
    } else {
    mcp.digitalWrite(trafficLights1[x], LOW);
    }
    }
    void activateTrafficLight2(String lights, int pedestrians)
    {
    for(int x = 0; x < 4; x++)
    {
    if(lights[x] == '0') state = LOW;
    if(lights[x] == '1') state = HIGH;
    mcp.digitalWrite(trafficLights2[x], state);
    }
    if(pedestrians == 1) {
    pedDontWalk();
    }
    }
    void activateTrafficLight3(String lights, int pedestrians)
    {
    for(int x = 0; x walk) {
    previousPeds = currentMillisPed;
    ledState = HIGH;
    mcp.digitalWrite(12, ledState);
    }
    }
    void pedDontWalk() {
    mcp.digitalWrite(12, LOW);
    unsigned long currentMillisPed = millis();
    if(currentMillisPed – previousPeds > dontwalk) {
    previousPeds = currentMillisPed;
    if (ledState == LOW)
    ledState = HIGH;
    else
    ledState = LOW;
    mcp.digitalWrite(11, ledState);
    }
    }
    void pedStopWalk() {
    unsigned long currentMillisPed = millis();
    if(currentMillisPed – previousPeds > stopwalk) {
    previousPeds = currentMillisPed;
    ledState = HIGH;
    mcp.digitalWrite(11, ledState);
    }
    }

  • sivaguruEM

    Dear Marian,
    What needs to be modified for a 3 signal light junction? I am adding sensors and a camera trigger later and will work on it myself. But for now, I need help on using 3 traffic lights as the base system.

  • wl888bigpond-com

    Firstly…Thanks to P.Marion for the original code.
    Runs on UNO R3
    I have modified this project to use on my model railway, it suits my own requirements, which others seem to be looking for as well.
    The version listed below is for a T intersection with Pedestrian WALK, WALK CAUTION & STOP WALK indication per Australian style, it does not have turn indication, but you could add that if required.
    Timing is adjustable.
    I am still learning so please NO technical questions.
    There is NO video and all connections can be derived from code.
    Look at the I/O expander chip MCP23017, this is what i will eventually use to drive this circuit with the UNO R3

    //Credits for Original Source: http://www.electroschematics.com/10178/arduino-traffic-light-system/
    //Arduino UNO R3
    //I made minor modifications to add a 3rd set of lights to give a “T” intersection
    //with pedestrian crossing when all lights are red
    //the lights will be powered from a port extender chip MCP23017 which gives 16 extra I/O ports
    //extra turning signals could be added for more realism but this now suits my needs.
    // WL888

    int trafficLights1[] = {2,3,4,11}; // red, yellow, green, pedestrians led pins
    int trafficLights2[] = {5,6,7,12}; // red, yellow, green, pedestrians led pins
    int trafficLights3[] = {8,9,10,12}; // red, yellow, green, pedestrians led pins
    int situations = 10;
    int duration[] = {3000,3000,3000,3000,3000,10000,7500,5000,3000,3000}; //largest is the WALK,DONT WALK, STOP WALK durations
    long previousCars = 0;
    long previousPeds = 0;
    long previousLight = 0;
    long walk = 5; //walk interval for pedestrians
    long dontwalk = 333; //dontwalk interval for flashing pedestrians
    long stopwalk = 5; //stop walk interval
    int ledState = LOW;
    int state;
    int i = 0;

    void setup()
    {
    for(int i = 0; i < 4; i++) {
    pinMode(trafficLights1[i], OUTPUT);
    pinMode(trafficLights2[i], OUTPUT);
    pinMode(trafficLights3[i], OUTPUT);
    }
    digitalWrite(12, HIGH);
    Serial.begin(9600);
    }

    void loop()
    {
    unsigned long currentMillis = millis();
    if(currentMillis – previousCars = situations) {
    i = 0;
    } else {
    i++;
    }
    }
    }

    void activateTrafficLight1(String lights, int pedestrians)
    {
    for(int x = 0; x < 3; x++)
    {
    if(lights[x] == '0') state = LOW;
    if(lights[x] == '1') state = HIGH;
    digitalWrite(trafficLights1[x], state);
    }
    if(pedestrians == 1) {
    pedWalk();
    } else {
    digitalWrite(trafficLights1[3], LOW);
    }
    }
    void activateTrafficLight2(String lights, int pedestrians)
    {
    for(int x = 0; x < 3; x++)
    {
    if(lights[x] == '0') state = LOW;
    if(lights[x] == '1') state = HIGH;
    digitalWrite(trafficLights2[x], state);
    }
    if(pedestrians == 1) {
    pedDontWalk();
    }
    }
    void activateTrafficLight3(String lights, int pedestrians)
    {
    for(int x = 0; x walk) {
    previousPeds = currentMillisPed;
    ledState = HIGH;
    digitalWrite(11, ledState);
    }
    }
    void pedDontWalk() {
    digitalWrite(11, LOW);
    unsigned long currentMillisPed = millis();
    if(currentMillisPed – previousPeds > dontwalk) {
    previousPeds = currentMillisPed;
    if (ledState == LOW)
    ledState = HIGH;
    else
    ledState = LOW;
    digitalWrite(12, ledState);
    }
    }
    void pedStopWalk() {
    unsigned long currentMillisPed = millis();
    if(currentMillisPed – previousPeds > stopwalk) {
    previousPeds = currentMillisPed;
    ledState = HIGH;
    digitalWrite(12, ledState);
    }
    }

    • sivaguruEM

      Hello wl888bigpond….. Your posted code is missing some parts. For example “void pedWalk()” is missing. And “currentmillisPed” is only declared as a local variable, so error shows that it is not defined in the main loop.

      Thanks for your help. I am trying to use a similar method for my project with modifications, but the base code shown here does not compile.

Looking for the latest from TI?