This project builds a functional traffic light system that coordinates vehicle and pedestrian signals using an Arduino Uno. The system cycles through red, yellow, and green phases for cars while managing pedestrian crossing requests, complete with a blue indicator LED showing when a walk request is pending.
Builders will receive a complete wiring diagram showing how to connect three LEDs for vehicle signals, two LEDs for pedestrian signals, a request button, and a status indicator LED to the Arduino pins. The guide includes a full parts list, step-by-step assembly instructions, and Arduino firmware that implements realistic traffic timing with debounced button input and safe signal transitions.
Wiring diagram

Gather all the parts
Assemble it in 6 steps
1. Προετοιμασία με αποσυνδεδεμένο USB
Χρησιμοποίησε το Arduino Uno, έξι LED (μαζί με το μπλε), έξι αντιστάσεις 330 Ω / 1⁄4 W και ένα απλό στιγμιαίο μπουτόν κανονικά ανοικτό. Κάνε όλες τις συνδέσεις με αποσυνδεδεμένο USB.
- Εκπαιδευτική μακέτα μόνο. Δεν είναι κατάλληλο για πραγματική ρύθμιση κυκλοφορίας.
2. Σύνδεση φαναριού οχημάτων
Σύνδεσε D3 → r1 → άνοδο κόκκινου LED, D4 → r2 → άνοδο κίτρινου LED και D5 → r3 → άνοδο πράσινου LED. Οι αντιστάσεις είναι 330 Ω και περιορίζουν το ρεύμα. Σύνδεσε την κάθοδο κάθε LED στο GND του Uno. Η άνοδος είναι συνήθως το μακρύ ποδαράκι, η κάθοδος το κοντό και η πλευρά με το επίπεδο χείλος.
- Μην παραλείψεις καμία αντίσταση: μπορεί να καταστραφεί το LED ή η έξοδος του Uno.
3. Σύνδεση φαναριού πεζών
Σύνδεσε D6 → r4 → άνοδο κόκκινου LED πεζών και D7 → r5 → άνοδο πράσινου LED πεζών. Σύνδεσε τις δύο καθόδους στο ίδιο GND.
4. Σύνδεση μπουτόν αιτήματος
Σύνδεσε τη μία επαφή του μπουτόν στο D2 (αίτημα διέλευσης) και την άλλη στο GND. Η εσωτερική αντίσταση του Uno κρατά την είσοδο σταθερή όταν δεν πατιέται. Σε μπουτόν με τέσσερα ποδαράκια χρησιμοποίησε επαφές που ενώνονται μόνο όταν το πατάς, όχι δύο ήδη ενωμένα ποδαράκια.
5. Μπλε ένδειξη αιτήματος
Σύνδεσε D8 → r6 (330 Ω) → άνοδο μπλε LED. Σύνδεσε την κάθοδο στο κοινό GND. Το μπλε ανάβει όταν γίνει δεκτό ένα πάτημα και σβήνει μόλις ανάψει πράσινο πεζών. Πατήματα όσο οι πεζοί έχουν πράσινο ή στο τελικό διάστημα δύο κόκκινων αγνοούνται. Το παρατεταμένο πάτημα δεν επαναλαμβάνει το αίτημα.
6. Τελικός έλεγχος καλωδίωσης
Έλεγξε τις πολικότητες, τις έξι αντιστάσεις και το κοινό GND. Η τροφοδοσία θα γίνεται μόνο από τη θύρα USB του Uno. Στην εκκίνηση ανάβουν και τα δύο κόκκινα για 2 δευτερόλεπτα. Μετά ανάβει πράσινο οχημάτων. Ο κύκλος επαναλαμβάνεται αυτόματα με 15 δευτερόλεπτα πράσινο οχημάτων, 3 δευτερόλεπτα κίτρινο, 2 δευτερόλεπτα δύο κόκκινα, 8 δευτερόλεπτα πράσινο πεζών και 2 δευτερόλεπτα δύο κόκκινα. Το μπουτόν επισπεύδει το τέλος του πράσινου οχημάτων, αλλά μόνο αφού συμπληρωθούν τουλάχιστον 5 δευτερόλεπτα από την έναρξή του. Το μπλε επιβεβαιώνει το αίτημα μέχρι να ανάψει πράσινο πεζών.
Review all connections
1. Connections between "r1" and "Arduino"
2. Connections between "car_red" and "Arduino"
3. Connections between "r2" and "Arduino"
4. Connections between "car_yellow" and "Arduino"
5. Connections between "r3" and "Arduino"
6. Connections between "car_green" and "Arduino"
7. Connections between "r4" and "Arduino"
8. Connections between "ped_red" and "Arduino"
9. Connections between "r5" and "Arduino"
10. Connections between "ped_green" and "Arduino"
11. Connections between "button1" and "Arduino"
12. Connections between "r6" and "Arduino"
13. Connections between "request_blue" and "Arduino"
Deploy the firmware
#include <Arduino.h>
constexpr uint8_t BUTTON=2, CAR_RED=3, CAR_YELLOW=4, CAR_GREEN=5,
PED_RED=6, PED_GREEN=7, REQUEST_BLUE=8;
constexpr unsigned long MIN_GREEN_MS=5000, AUTO_GREEN_MS=15000, YELLOW_MS=3000,
CLEARANCE_MS=2000, WALK_MS=8000;
enum Phase { START_CLEAR, CARS, YELLOW, BEFORE_WALK, WALK, AFTER_WALK };
Phase phase=START_CLEAR;
unsigned long phaseStart=0, rawChanged=0;
bool pending=false, rawLast=HIGH, stable=HIGH;
void enter(Phase next, unsigned long now) {
// Extinguish green signals before changing any red signal.
digitalWrite(CAR_GREEN,LOW);
digitalWrite(PED_GREEN,LOW);
digitalWrite(CAR_YELLOW,LOW);
digitalWrite(CAR_RED,HIGH);
digitalWrite(PED_RED,HIGH);
if(next==CARS) {
digitalWrite(CAR_RED,LOW);
digitalWrite(CAR_GREEN,HIGH);
} else if(next==YELLOW) {
digitalWrite(CAR_RED,LOW);
digitalWrite(CAR_YELLOW,HIGH);
} else if(next==WALK) {
digitalWrite(PED_RED,LOW);
digitalWrite(PED_GREEN,HIGH);
}
if(next==WALK) pending=false;
digitalWrite(REQUEST_BLUE,pending ? HIGH : LOW);
phase=next;
phaseStart=now;
}
void setup() {
pinMode(BUTTON,INPUT_PULLUP);
const uint8_t outputs[]={CAR_RED,CAR_YELLOW,CAR_GREEN,PED_RED,PED_GREEN,REQUEST_BLUE};
for(uint8_t pin:outputs) { digitalWrite(pin,LOW); pinMode(pin,OUTPUT); }
enter(START_CLEAR,millis());
}
void loop() {
unsigned long now=millis();
bool raw=digitalRead(BUTTON);
if(raw!=rawLast) { rawLast=raw; rawChanged=now; }
if(now-rawChanged>=40 && raw!=stable) {
stable=raw;
// Only accept new requests outside an active pedestrian crossing cycle.
if(stable==LOW && (phase==CARS || phase==START_CLEAR ||
phase==YELLOW || phase==BEFORE_WALK)) {
pending=true;
digitalWrite(REQUEST_BLUE,HIGH);
}
}
unsigned long elapsed=now-phaseStart;
switch(phase) {
case START_CLEAR: if(elapsed>=CLEARANCE_MS) enter(CARS,now); break;
case CARS:
if(elapsed>=AUTO_GREEN_MS || (pending && elapsed>=MIN_GREEN_MS)) {
enter(YELLOW,now);
}
break;
case YELLOW: if(elapsed>=YELLOW_MS) enter(BEFORE_WALK,now); break;
case BEFORE_WALK: if(elapsed>=CLEARANCE_MS) enter(WALK,now); break;
case WALK: if(elapsed>=WALK_MS) enter(AFTER_WALK,now); break;
case AFTER_WALK: if(elapsed>=CLEARANCE_MS) enter(CARS,now); break;
}
}Remix this project
Make it yours in one click
Open a full copy of this project in your own Schematik workspace, diagram, code, parts, and assembly steps included. Swap the sensor, add features, or redesign the whole thing with AI. The author's original stays untouched.




