Introduction: Arduino Traffic Lights Using Finite State Machines

Hey guys, this is my first instructuble and it’s about an Arduino project that I realized for microprocessors unit in my University. This project aims to recreate, on a small scale, a traffic light’s system implemented in the city of Faro, Portugal. The streets in this intersection are: Aboim Ascensão street, Alportel street, General Teófilo da Trindade street and Santo Amaro street.

This project was programmed to use Finite State Machines (FSM’s) and it was divided into two parts.

In the first part I created the system of traffic lights, that through the FSM0, generates the outputs for each led of the system.

In the second part I was suggested to use ultrasonic sensors (HC-SR04) like traffic simulators in the busiest streets of the intersection (Alportel street and Amboim Ascensão street), in order to control the traffic flow. In order to satisfy the request, I created a second FSM (FSM00) which generates the times that each traffic light is active, depending on the traffic on the busiest streets.

Step 1: Intersection Scheme

1: Alportel Street Traffic Light’s (left, front, right)

2: Amboim Ascensão Street Traffic Light’s 1 (front)

3: Amboim Ascensão Street Traffic Light’s 2 (left)

4: General Teófilo da Trindade Street Traffic Light’s (front, right)

5: Santo Amaro Street Traffic Light’s (right)

TS_AMB: Amboim Ascensão Street Traffic Sensor

TS_ALP: Alportel Street Traffic Sensor

Step 2: Assembly Scheme

Step 3: Material

Arduino Uno;

2x breadboard;

5x red led;

5x yellow led;

4x green led;

14x 220 ohm resistor (red,red,brown);

2x HC-SR04 (Ultrasonic Sensor);

Breadboard wires;

Step 4: Entity

INPUTS

ECHO_ALP: Alportel Street HC-SR04 Echo

ECHO_AMB: Amboim Ascensão Street HC-SR04 Echo

OUTPUTS

[R1,Y1,G1]: Alportel Street Traffic Lights (red1,yellow1,green1)

[R2,Y2,G2]: Amboim Ascensão Street Traffic Lights 1 (red2,yellow2,green2)

[R3,Y3,G3]: Amboim Ascensão Street Traffic Lights 2 (red3,yellow3,green3)

[R4,Y4,G4]: General Teófilo da Trindade Street Traffic Lights (red4,yellow4,green4)

[R5,Y5]: Santo Amaro Street Traffic Lights (red5,yellow5)

TRIG_ALP: Alportel Street HC-SR04 Trigger

TRIG_AMB: Amboim Ascensão Street HC-SR04 Trigger

Step 5: Architecture

Blocks

FSM_0: Finite State Machine 0;

Temp_2: Timer 2;

Temp_1: Timer 1;

Temp_AMB: Amboim Ascensão Street Timer;

Temp_ALP: Alportel Street Timer ;

FSM_00: Finite State Machine 00;

Comp_AMB: Amboim Ascensão Street Comparator;

Comp_ALP: Alportel Street Comparator;

Ping_Amb: Amboim Ascensão Street Ping Ultrassonic Range Finder;

Ping_ALP: Alportel Street Ping Ultrassonic Range Finder;

Stimulus

T2_E: Timer 2 Stimulus;

T1_E: Timer 1 Stimulus;

TAMB_E: Amboim Ascensão Street Timer Stimulus;

TALP_E: Alportel Street Timer Stimulus;

TRFAMB_E: Amboim Ascensão Street Traffic Stimulus;

TRFALP_E: Alportel Street Traffic Stimulus;

Signals

ts1: Time Counting Variable 1;

ts2: Time Counting Variable 2;

HTime_ALP: Alportel Street Hold Time;

HTime_AMB: Amboim Ascensão Hold Time;

HTime_1: Hold Time 1;

HTime_2: Hold Time 2:

cm_AMB: Amboim Ascensão Street Traffic Sensor Distance;

cm_ALP: Alportel Street Traffic Sensor Distance;

Step 6: Finite State Machine 00

Step 7: Finite State Machine 0

Step 8: Operating Diagram

In this diagram we can see how the whole system works.

In state 1, the traffic light on the Alportel street is green, the time it will stay green will depend on the length of the Alportel street traffic sensor detects. The same is for the Amboim Ascensão street traffic light, represented in state 5, if the Amboim Ascensão street traffic sensor detects traffic the hold time of the green light is higher than the normal. Both sensors only detect traffic when measurements are below 15 cm. The other hold times are always the sames. HTime_2=2s (yellow lights) and HTime_1=6s (green light from Amboim Ascensão street when we turn left).

Step 9: Code

#define R1_pin 2
#define Y1_pin 3 #define G1_pin 4 #define R2_pin 5 #define Y2_pin 6 #define G2_pin 7 #define R3_pin 8 #define Y3_pin 9 #define G3_pin 10 #define R4_pin 11 #define Y4_pin 12 #define G4_pin 13 #define R5_pin 14 #define Y5_pin 15 #define T_Alp_e_pin 16 #define T_Amb_e_pin 17 #define T_Alp_t_pin 18 #define T_Amb_t_pin 19 static int FSM0_state = 1; static int FSM00_state = 1;
static unsigned long FSM00_HTime_1; static unsigned long FSM00_HTime_2; static unsigned long FSM00_HTime_Alp; static unsigned long FSM00_HTime_Amb;
static unsigned long FSM0_ts1; static unsigned long FSM0_ts2; void setup() { pinMode(R1_pin, OUTPUT);pinMode(Y1_pin, OUTPUT);pinMode(G1_pin, OUTPUT); pinMode(R2_pin, OUTPUT);pinMode(Y2_pin, OUTPUT);pinMode(G2_pin, OUTPUT); pinMode(R3_pin, OUTPUT);pinMode(Y3_pin, OUTPUT);pinMode(G3_pin, OUTPUT); pinMode(R4_pin, OUTPUT);pinMode(Y4_pin, OUTPUT);pinMode(G4_pin, OUTPUT); pinMode(R5_pin, OUTPUT);pinMode(Y5_pin, OUTPUT); pinMode(T_Alp_e_pin, INPUT);pinMode(T_Amb_e_pin, INPUT); pinMode(T_Alp_t_pin, OUTPUT);pinMode(T_Amb_t_pin, OUTPUT); Serial.begin(9600); } void loop() { int FSM0_E_time1;int FSM0_E_time2;int FSM0_E_timeAlp;int FSM0_E_timeAmb;int comp_min = 15; int FSM00_E_TrafAlp;int FSM00_E_TrafAmb;long durAlp;long durAmb;long cmAlp;long cmAmb;

cmAlp = PingAlp(durAlp,cmAlp); cmAmb = PingAmb(durAmb,cmAmb); if((cmAlp > comp_min) && (cmAmb > comp_min)) { FSM00_E_TrafAlp = 0; FSM00_E_TrafAmb = 0; } if((cmAlp <= comp_min) && (cmAmb > comp_min)) { FSM00_E_TrafAlp = 1; FSM00_E_TrafAmb = 0; } if((cmAlp > comp_min) && (cmAmb <= comp_min)) { FSM00_E_TrafAlp = 0; FSM00_E_TrafAmb = 1; } if((cmAlp <= comp_min) && (cmAmb <= comp_min)) { FSM00_E_TrafAlp = 1; FSM00_E_TrafAmb = 1; } FSM00(FSM00_E_TrafAlp,FSM00_E_TrafAmb);
if((millis() - FSM0_ts2) > FSM00_HTime_2) { FSM0_E_time2 = 1; } else { FSM0_E_time2 = 0; } if((millis() - FSM0_ts1) > FSM00_HTime_1) { FSM0_E_time1 = 1; } else { FSM0_E_time1 = 0; } if((millis() - FSM0_ts1) > FSM00_HTime_Alp) { FSM0_E_timeAlp = 1; } else { FSM0_E_timeAlp = 0; } if((millis() - FSM0_ts1) > FSM00_HTime_Amb) { FSM0_E_timeAmb = 1; } else { FSM0_E_timeAmb = 0; } FSM0(FSM0_E_time1,FSM0_E_time2,FSM0_E_timeAlp,FSM0_E_timeAmb);
} void FSM00(int FSM00_E_TrafAlp,int FSM00_E_TrafAmb)
{ FSM00_next_state(FSM00_E_TrafAlp,FSM00_E_TrafAmb); FSM00_output(); } void FSM0(int FSM0_E_time1,int FSM0_E_time2,int FSM0_E_timeAlp,int FSM0_E_timeAmb) { FSM0_next_state(FSM0_E_time1,FSM0_E_time2,FSM0_E_timeAlp,FSM0_E_timeAmb); FSM0_output(); } void FSM00_next_state(int FSM00_E_TrafAlp,int FSM00_E_TrafAmb)
{ switch(FSM00_state) { case 1: if((FSM00_E_TrafAlp == 1) && (FSM00_E_TrafAmb == 0)) { FSM00_state = 2; } if((FSM00_E_TrafAlp == 0) && (FSM00_E_TrafAmb == 1)) { FSM00_state = 3; } if((FSM00_E_TrafAlp == 1) && (FSM00_E_TrafAmb == 1)) { FSM00_state = 4; } break; case 2: if((FSM00_E_TrafAlp == 0) && (FSM00_E_TrafAmb == 0)) { FSM00_state = 1; } if((FSM00_E_TrafAlp == 0) && (FSM00_E_TrafAmb == 1)) { FSM00_state = 3; } if((FSM00_E_TrafAlp == 1) && (FSM00_E_TrafAmb == 1)) { FSM00_state = 4; } break; case 3: if((FSM00_E_TrafAlp == 0) && (FSM00_E_TrafAmb == 0)) { FSM00_state = 1; } if((FSM00_E_TrafAlp == 1) && (FSM00_E_TrafAmb == 0)) { FSM00_state = 2; } if((FSM00_E_TrafAlp == 1) && (FSM00_E_TrafAmb == 1)) { FSM00_state = 4; } break; case 4: if((FSM00_E_TrafAlp == 0) && (FSM00_E_TrafAmb == 0)) { FSM00_state = 1; } if((FSM00_E_TrafAlp == 1) && (FSM00_E_TrafAmb == 0)) { FSM00_state = 2; } if((FSM00_E_TrafAlp == 0) && (FSM00_E_TrafAmb == 1)) { FSM00_state = 3; } break; default: break; } } void FSM00_output()
{ switch(FSM00_state) { case 1: FSM00_HTime_1 = 6000; FSM00_HTime_2 = 2000; FSM00_HTime_Alp = 6000; FSM00_HTime_Amb = 6000; break; case 2: FSM00_HTime_1 = 6000; FSM00_HTime_2 = 2000; FSM00_HTime_Alp = 12000; FSM00_HTime_Amb = 6000; break; default: break; case 3: FSM00_HTime_1 = 6000; FSM00_HTime_2 = 2000; FSM00_HTime_Alp = 6000; FSM00_HTime_Amb = 12000; break; case 4: FSM00_HTime_1 = 6000; FSM00_HTime_2 = 2000; FSM00_HTime_Alp = 12000; FSM00_HTime_Amb = 12000; break; } } void FSM0_next_state(int FSM0_E_time1,int FSM0_E_time2,int FSM0_E_timeAlp,int FSM0_E_timeAmb)
{ switch(FSM0_state) { case 1: if(FSM0_E_timeAlp == 1) { FSM0_state = 2; } break; case 2: if(FSM0_E_time2 == 1) { FSM0_state = 3; } break; case 3: if(FSM0_E_time1 == 1) { FSM0_state = 4; } break; case 4: if(FSM0_E_time2 == 1) { FSM0_state = 5; } break; case 5: if(FSM0_E_timeAmb == 1) { FSM0_state = 6; } break; case 6: if(FSM0_E_time2 == 1) { FSM0_state = 1; } break; default: break; } } void FSM0_output()
{ switch(FSM0_state) { case 1: FSM0_ts2 = millis(); digitalWrite(R1_pin,LOW); digitalWrite(Y1_pin,LOW); digitalWrite(G1_pin,HIGH); digitalWrite(R2_pin,HIGH); digitalWrite(Y2_pin,LOW); digitalWrite(G2_pin,LOW); digitalWrite(R3_pin,HIGH); digitalWrite(Y3_pin,LOW); digitalWrite(G3_pin,LOW); digitalWrite(R4_pin,HIGH); digitalWrite(Y4_pin,LOW); digitalWrite(G4_pin,LOW); digitalWrite(R5_pin,HIGH); digitalWrite(Y5_pin,LOW); break; case 2: FSM0_ts1 = millis(); digitalWrite(R1_pin,LOW); digitalWrite(Y1_pin,HIGH); digitalWrite(G1_pin,LOW); digitalWrite(R2_pin,HIGH); digitalWrite(Y2_pin,LOW); digitalWrite(G2_pin,LOW); digitalWrite(R3_pin,HIGH); digitalWrite(Y3_pin,LOW); digitalWrite(G3_pin,LOW); digitalWrite(R4_pin,HIGH); digitalWrite(Y4_pin,LOW); digitalWrite(G4_pin,LOW); digitalWrite(R5_pin,HIGH); digitalWrite(Y5_pin,LOW); break; case 3: FSM0_ts2 = millis(); digitalWrite(R1_pin,HIGH); digitalWrite(Y1_pin,LOW); digitalWrite(G1_pin,LOW); digitalWrite(R2_pin,LOW); digitalWrite(Y2_pin,LOW); digitalWrite(G2_pin,HIGH); digitalWrite(R3_pin,LOW); digitalWrite(Y3_pin,LOW); digitalWrite(G3_pin,HIGH); digitalWrite(R4_pin,HIGH); digitalWrite(Y4_pin,LOW); digitalWrite(G4_pin,LOW); digitalWrite(R5_pin,HIGH); digitalWrite(Y5_pin,LOW); break; case 4: FSM0_ts1 = millis(); digitalWrite(R1_pin,HIGH); digitalWrite(Y1_pin,LOW); digitalWrite(G1_pin,LOW); digitalWrite(R2_pin,LOW); digitalWrite(Y2_pin,LOW); digitalWrite(G2_pin,HIGH); digitalWrite(R3_pin,LOW); digitalWrite(Y3_pin,HIGH); digitalWrite(G3_pin,LOW); digitalWrite(R4_pin,HIGH); digitalWrite(Y4_pin,LOW); digitalWrite(G4_pin,LOW); digitalWrite(R5_pin,HIGH); digitalWrite(Y5_pin,LOW); break; case 5: FSM0_ts2 = millis(); digitalWrite(R1_pin,HIGH); digitalWrite(Y1_pin,LOW); digitalWrite(G1_pin,LOW); digitalWrite(R2_pin,LOW); digitalWrite(Y2_pin,LOW); digitalWrite(G2_pin,HIGH); digitalWrite(R3_pin,HIGH); digitalWrite(Y3_pin,LOW); digitalWrite(G3_pin,LOW); digitalWrite(R4_pin,LOW); digitalWrite(Y4_pin,LOW); digitalWrite(G4_pin,HIGH); digitalWrite(R5_pin,LOW); digitalWrite(Y5_pin,HIGH); break; case 6: FSM0_ts1 = millis(); digitalWrite(R1_pin,HIGH); digitalWrite(Y1_pin,LOW); digitalWrite(G1_pin,LOW); digitalWrite(R2_pin,LOW); digitalWrite(Y2_pin,HIGH); digitalWrite(G2_pin,LOW); digitalWrite(R3_pin,HIGH); digitalWrite(Y3_pin,LOW); digitalWrite(G3_pin,LOW); digitalWrite(R4_pin,LOW); digitalWrite(Y4_pin,HIGH); digitalWrite(G4_pin,LOW); digitalWrite(R5_pin,LOW); digitalWrite(Y5_pin,HIGH); break; default: break; } } long PingAlp(long durAlp,long cmAlp)
{ digitalWrite(T_Alp_t_pin, LOW); delayMicroseconds(2); digitalWrite(T_Alp_t_pin, HIGH); delayMicroseconds(5); digitalWrite(T_Alp_t_pin, LOW); durAlp = pulseIn(T_Alp_e_pin, HIGH); cmAlp = microsecondsToCentimeters(durAlp); return cmAlp; } long PingAmb(long durAmb,long cmAmb)
{ digitalWrite(T_Amb_t_pin, LOW); delayMicroseconds(2); digitalWrite(T_Amb_t_pin, HIGH); delayMicroseconds(5); digitalWrite(T_Amb_t_pin, LOW); durAmb = pulseIn(T_Amb_e_pin, HIGH); cmAmb = microsecondsToCentimeters(durAmb); return cmAmb; } long microsecondsToCentimeters(long microseconds) { return microseconds / 29 / 2; }

Step 10: Images

Step 11: Video

In this video the system is showing equals hold times (green: 6s and yellow: 2s) because the two ultrasonic sensors are detecting differences greater than 15 cm as stipulated in the code.


Hope you like it!

Microcontroller Contest

Participated in the
Microcontroller Contest