Daniel TurnerCarlos Silva
Published © GPL3+

Crossroad Traffic Lights (FSM)

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

IntermediateShowcase (no instructions)2 hours9,776
Crossroad Traffic Lights (FSM)

Things used in this project

Hardware components

Arduino Nano R3
Arduino Nano R3
×1
LED (generic)
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
Jumper wires (generic)
Jumper wires (generic)
×1
Breadboard (generic)
Breadboard (generic)
×1
Resistor 330 ohm
Resistor 330 ohm
×6

Software apps and online services

Arduino IDE
Arduino IDE

Story

Read more

Custom parts and enclosures

FSM

FLOW CHART

Electric diagram

Project component connections

Schematics

Breadboard scheme

Breadboard Traffic_lights_pinger project implementation

Fritizing file

Code

Traffic lights with pedestrian crossing

C/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;
}

Credits

Daniel Turner

Daniel Turner

1 project • 2 followers
Carlos Silva

Carlos Silva

1 project • 2 followers
Engineering student of electronics and energy systems

Comments