Project showcase
Crossroad Traffic Lights (FSM)

Crossroad Traffic Lights (FSM) © GPL3+

Includes pedestrian detection/crossing and uses an Arduino Nano, LEDs and pingers and a FSM code.

  • 1,646 views
  • 1 comment
  • 6 respects

Components and supplies

Ard nano
Arduino Nano R3
×1
09590 01
LED (generic)
2x red, 2x yellow, 2x green. more LEDs can be added in parallel for better representation of the traffic junction. 6 LEDs is just the minimum.
×6
range finder
×2
11026 02
Jumper wires (generic)
×1
12002 04
Breadboard (generic)
×1
08377 02 l
Resistor 330 ohm
×6

Apps and online services

About this project

This project was done at the university of the Algarve (ualg) as a part of the Microprocessors module on the Electrical and Electronic Engineering degree under the supervision of professor António Silva.

The Concept/Functionality

The concept of the project is to simulate (on a small scale) the control of two pairs of traffic lights applied to a crossroads with sensors to detect the presence of pedestrians that need to cross the road using the materials listed above.

  • Inputs: 2 pingers that measure the proximity of the pedestrians (for the sake of the experiment we consider 10cm of proximity).
  • Outputs: 6 leds, representing the red, green and yellow traffic lights for two sets of lights.

The code implements a finite state machine (FSM) for better functionality and simplicity.

(as each pair of traffic lights will always have the same lights on and as the pedestrians light sequence derives directly from the road traffic lights it is not necessary to represent every single light involved in a real crossroad).

The Planning and Thinking

Before creating a project like this, the proper procedure is to first plan everything out, (like flowcharts and state diagrams). And then when starting to create the project to keep doing things step by step and testing everything before moving on to the next step.

The way we solved the problem was to start by creating the state diagrams and flowcharts and then the code for the lights without considering the pedestrian crossing and focusing only on the order of the lights for the cars. This was not very difficult as it just involved defining the light output states and defining times between each transition.

Afterwards when everything was working perfectly, we moved on to the pedestrian crossing. the solution we eventually came up with was to simply create a way to alter the times between each transition and maintain the same order of states of LEDs. this made for a functional and safe way for the traffic to remain efficient. So to do this we simply added an extra state for each rotation of lights where the time would be altered so that the green light would go out faster (these additional states only come in to action if a pedestrian is present).

The Code

The C code uses a FSM method, and this project is a very good example of the advantages of an FSM and we recommend trying to recreate this project if you are interested in learning about making a finite state machine code.

The code also uses the millis() function instead of delays as this is a much more efficent way to implement delays.

Two ping functions are created which are very similar to those seen on the official arduino website at: https://www.arduino.cc/en/Tutorial/Ping but at the end of each function are a few more lines of code to use the distance calculated to mark the presence or non-presence of a pedestrian.

And then for the implementation of the FSM two more functions are created, one to define the outputs for each state and one to define which state is next and the conditions to change to the next state.

The code can be analyzed for a much better understanding, especially if you read the comments that describe all the steps.

The Circuit

This project can be re-created with the components listed above, but a more complex and life-like representation of the crossroads can be easily achieved using more LEDs in parallel to the existing ones (pedestrian lights and the lights on opposite sides of the same road can be connected to the already implemented LEDs).

Video - simulation of the project on breadboard

Advantages of using a Finite state Machine (FSM)

- Simple and fast to make

- Easy to test

  • Well developed techniques due to being relatively old
  • Quite flexible, they can be applied to various things in various different ways
  • Low processor overhead
  • Easy to analyze when someone else reads it

Code

Traffic lights with pedestrian crossingC/C++
Traffic lights with pedestrian crossing using pingers for pedestrian detection and a FSM structure for the implementation of the code
//-------------------------Traffic lights (with pingers for pedestrian crossing)----------------------
//AUTHORS:
//DANIEL TURNER
//CARLOS SILVA

//project done by sudents of the electrical and electronic engineering course at the university of the algarve
//for the microprocessors subject unde rthe supervision of professor Antnio Silva

//  The idea of this project is to control the traffic lights of a 4 way junction
//  with integrated range finders for detecting the presence of pedestrians to allow them to cross.

int red1 = 2;                             // red LED 1    - pin 2
int yellow1 = 3;                          // yellow LED 1 - pin 3 
int green1 = 4;                           // greed LED 1  - pin 4
int red2 = 5;                             // red LED 2    - pin 5
int yellow2 = 6;                          // yellow LED 2 - pin 6
int green2 = 7;                           // green LED  2 - pin 7
unsigned long PreviousMillis = 0;         // previous millisecond
unsigned long CurrentMillis;              // current millisecond
int atraso;                               // delay
int state;                                // state for FSM
const int pingPin = 8;                    // ping 1
const int pingPin2 = 9;                   // ping 2
int cross=0;                              // presence of pedestrian 1
int cross2=0;                             // presebce of pedestrian 2
long duration, cm, cm2;                   // range calculation variables

void setup ()
{
  
  pinMode(red1, OUTPUT);                  //all LED pins are set to "output"
  pinMode(yellow1, OUTPUT);
  pinMode(green1, OUTPUT);
  pinMode(red2, OUTPUT);
  pinMode(yellow2, OUTPUT);
  pinMode(green2, OUTPUT);
  state=1;                                // initiate the FSM in the first state
  Serial.begin(9600);                     // initialize serial communication
}
void loop ()
{
  CurrentMillis = millis();               // updates current millisecond
  atraso=CurrentMillis-PreviousMillis;    // calculates the delay
  
  ping();                                 // runs the first ping function
  ping2();                                // runs the second ping function
  next_state_FSM();                       // runs the FSM function (next state)
  output_FSM();                           // runs the FSM function (output)

                                          //notice the loop is almost empty due to the implementation of an FSM
}
void ping(){
                                          // The PING))) is triggered by a HIGH pulse of 2 or more microseconds.
                                          // Give a short LOW pulse beforehand to ensure a clean HIGH pulse:
  pinMode(pingPin, OUTPUT);
  digitalWrite(pingPin, LOW);
  delayMicroseconds(2);
  digitalWrite(pingPin, HIGH);
  delayMicroseconds(5);
  digitalWrite(pingPin, LOW);

                                          // The same pin is used to read the signal from the PING))): a HIGH
                                          // pulse whose duration is the time (in microseconds) from the sending
                                          // of the ping to the reception of its echo off of an object.
  pinMode(pingPin, INPUT);
  duration = pulseIn(pingPin, HIGH);

                                          // convert the time into a distance
  cm = microsecondsToCentimeters(duration);

  if(cm<10){                              //in reallity it would be aproximatly 100cm but 10cm is more practical for testing the circuit on a small scale
    cross=1;                              //if the pedestrian is close enough the "cross" variable will change to 1
  }else{
    cross=0;                              //"cross" will be 0 when there is no presence of pedestrians
  }
}

void ping2(){
                                          // The PING))) is triggered by a HIGH pulse of 2 or more microseconds.
                                          // Give a short LOW pulse beforehand to ensure a clean HIGH pulse:
  pinMode(pingPin2, OUTPUT);
  digitalWrite(pingPin2, LOW);
  delayMicroseconds(2);
  digitalWrite(pingPin2, HIGH);
  delayMicroseconds(5);
  digitalWrite(pingPin2, LOW);

                                          // The same pin is used to read the signal from the PING))): a HIGH
                                          // pulse whose duration is the time (in microseconds) from the sending
                                          // of the ping to the reception of its echo off of an object.

  pinMode(pingPin2, INPUT);
  duration = pulseIn(pingPin2, HIGH);

                                          // convert the time into a distance
  cm2 = microsecondsToCentimeters(duration);

  if(cm2<10){                             //in reallity it would be aproximatly 100cm but 10cm is more practical for testing the circuit on a small scale
    cross2=1;                             //if the pedestrian is close enough the "cross2" variable will change to 1
  }else{
    cross2=0;                             //"cross2" will be 0 when there is no presence of pedestrians
  }
}

void output_FSM(){
 switch (state){
    case 1:                               //LED outputs are defined for state 1
      digitalWrite (red1,     LOW);
      digitalWrite (yellow1,  LOW);
      digitalWrite (green1,   HIGH);
      digitalWrite (red2,     HIGH);
      digitalWrite (yellow2,  LOW);
      digitalWrite (green2,   LOW);
    break;

    case 2:                               //LED outputs are defined for state 2
      digitalWrite (red1,     LOW);
      digitalWrite (yellow1,  HIGH);
      digitalWrite (green1,   LOW);
      digitalWrite (red2,     HIGH);
      digitalWrite (yellow2,  LOW);
      digitalWrite (green2,   LOW);
    break;

    case 3:                               //LED outputs are defined for state 3
      digitalWrite (red1,     HIGH);
      digitalWrite (yellow1,  LOW);
      digitalWrite (green1,   LOW);
      digitalWrite (red2,     HIGH);
      digitalWrite (yellow2,  LOW);
      digitalWrite (green2,   LOW);
    break;

    case 4:                               //LED outputs are defined for state 4
      digitalWrite (red1,     HIGH);
      digitalWrite (yellow1,  LOW);
      digitalWrite (green1,   LOW);
      digitalWrite (red2,     LOW);
      digitalWrite (yellow2,  LOW);
      digitalWrite (green2,   HIGH);
    break;

    case 5:                               //LED outputs are defined for state 5
      digitalWrite (red1,     HIGH);
      digitalWrite (yellow1,  LOW);
      digitalWrite (green1,   LOW);
      digitalWrite (red2,     LOW);
      digitalWrite (yellow2,  HIGH);
      digitalWrite (green2,   LOW);
    break;

    case 6:                               //LED outputs are defined for state 6
      digitalWrite (red1,     HIGH);
      digitalWrite (yellow1,  LOW);
      digitalWrite (green1,   LOW);
      digitalWrite (red2,     HIGH);
      digitalWrite (yellow2,  LOW);
      digitalWrite (green2,   LOW);
    break;

    case 7:                               //LED outputs are defined for state 7
      digitalWrite (red1,     LOW);
      digitalWrite (yellow1,  LOW);
      digitalWrite (green1,   HIGH);
      digitalWrite (red2,     HIGH);
      digitalWrite (yellow2,  LOW);
      digitalWrite (green2,   LOW);
    break;

    case 8:                               //LED outputs are defined for state 8
      digitalWrite (red1,     HIGH);
      digitalWrite (yellow1,  LOW);
      digitalWrite (green1,   LOW);
      digitalWrite (red2,     LOW);
      digitalWrite (yellow2,  LOW);
      digitalWrite (green2,   HIGH);
    break;
  }
}

void next_state_FSM(){                    //this function defines when to change state and which state to change to based on the delay value and the presence of pedestrians
  switch (state){
    case 1:
       if(atraso>5000){
        state=2;
        PreviousMillis=CurrentMillis;
      }else{
        if(cross==1){
          state=7;                        // does not reset previous millis so the "timer" can keep counting
        }
      }
    break;
    
    case 2:
      if(atraso>2000){
        state=3;
        PreviousMillis=CurrentMillis;
      }
    break;
    
    case 3:
    if(atraso>2000){
      state=4;
      PreviousMillis=CurrentMillis;
    }
    break;
    
    case 4:
    if(atraso>5000){
      state=5;
      PreviousMillis=CurrentMillis;    
    }else{
      if(cross2==1){
        state=8;
      }
    }
    
    break;
    
    case 5:
      if(atraso>2000){
        state=6;
        PreviousMillis=CurrentMillis;
      }
    break;
    
    case 6:
      if(atraso>2000){
        state=1;
        PreviousMillis=CurrentMillis;
      }
    break;
    
    case 7:                                 // auxiliar state to make the green light go out sooner
      if(cross==0){
          state=1;                          // does not reset previous millis so the "timer" can keep counting
      }else{
        if(atraso>1000){
          state=2;
          PreviousMillis=CurrentMillis;
        }
      }
    break;

    case 8:                                 // auxiliar state to make the green light go out sooner
      if(cross2==0){
          state=4;                          // does not reset previous millis so the "timer" can keep counting
      }else{
        if(atraso>1000){
          state=5;
          PreviousMillis=CurrentMillis;
        }
      }
    break;
  }
}

long microsecondsToCentimeters(long microseconds) {
                                            // The speed of sound is 340 m/s or 29 microseconds per centimeter.
                                            // The ping travels out and back, so to find the distance of the
                                            // object we take half of the distance travelled.
  return microseconds / 29 / 2;
}

Custom parts and enclosures

FLOW CHART
Electric diagram
Project component connections
Project connections okt6rr5mgw

Schematics

Breadboard scheme
Breadboard Traffic_lights_pinger project implementation
Traffic lights 0mrmca14ax
Fritizing file
traffic_lights_0MAnt8Hd7W.fzz

Comments

Similar projects you might like

React and Johnny-Five Traffic Lights

by Iain

  • 2,039 views
  • 0 comments
  • 5 respects

Arduino Traffic Light Simulator

Project tutorial by Zachary Haslam

  • 8,025 views
  • 1 comment
  • 20 respects

Traffic Lights Controlled by Arduino

Project showcase by lmsousa

  • 5,094 views
  • 2 comments
  • 18 respects

Arduino Bike Blink Lights

Project showcase by Sam

  • 4,516 views
  • 3 comments
  • 13 respects

Traffic Monitor- Monitors traffic on the Go

Project tutorial by Patel Darshil

  • 3,732 views
  • 0 comments
  • 8 respects
Add projectSign up / Login