Traffic Light Using Arduino and OLED Display
Traffic Light Using Arduino Uno and OLED Display
This project creates a realistic traffic light system with an OLED display timer, featuring custom PCB design and professional LED sequencing. The system follows standard traffic light patterns with visual countdown display for enhanced user experience.
How the System Works
- Custom traffic light-shaped PCB with vertical LED arrangement (Red, Yellow, Green)
- 0.96" OLED display shows real-time countdown timer for each light phase
- Standard traffic light sequence: Red (15s) → Green (13s) → Yellow (3s)
- Yellow light features blinking "00" display for clear warning indication
- Each 10mm LED has dedicated 220 ohm current-limiting resistor
- Professional timing with 1-second delay between Red and Green transitions
- Powered by 7.4V battery through breadboard power distribution
Materials Required
- Arduino UNO - Buy Here
- Breadboard - Buy Here
- Jumper Wires - Buy Here
- 7.4V Battery - Buy Here
- 10mm LEDs (Red, Yellow, Green) - Buy Here
- L Shape Male Header - Buy Here
- Female Header - Buy Here
- 220 Ohm Resistors - Buy Here
- OLED Display (0.96") - Buy Here
PCB Gerber Files
Download the custom traffic light PCB design files:
Google DriveManufacture your PCB using JLCPCB's professional service:
Order PCB NowTraffic Light Sequence
The system follows realistic traffic light timing patterns:
- RED Light: 15 seconds - Stop signal with countdown display
- GREEN Light: 13 seconds - Go signal with countdown display
- YELLOW Light: 3 seconds - Warning with blinking "00" display
- Transition Delay: 1 second pause between Red and Green phases
Step-by-Step Assembly
1. PCB Preparation:
- Order the custom traffic light PCB using provided Gerber files
- Solder L-shape male headers for LED connections
- Install female headers for Arduino connection
- Solder 220 ohm resistors below each LED position
2. LED Installation:
- Install 10mm LEDs in vertical order: Red, Yellow, Green
- Ensure proper polarity alignment for all LEDs
- Test each LED with resistor before final assembly
3. Electronics Wiring:
- Connect Red LED to Arduino pin 4
- Connect Yellow LED to Arduino pin 3
- Connect Green LED to Arduino pin 2
- Wire OLED display to I2C pins (SDA, SCL)
- Connect 7.4V battery through breadboard for power distribution
4. Programming & Testing:
- Upload the Arduino code with required libraries
- Verify OLED display initialization and countdown
- Test complete light sequence: Red → Green → Yellow
- Confirm blinking behavior during yellow phase
- Adjust timing values in code if needed
🎥 Watch the video above for complete assembly and demonstration.
Arduino Code
Upload this code to your Arduino after installing the required libraries (Wire, Adafruit_GFX, Adafruit_SSD1306):
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
// OLED Display setup
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// LED pins - swapped to match your physical wiring
#define RED_LED 4 // Physical red LED is connected to pin 4
#define YELLOW_LED 3 // Unchanged
#define GREEN_LED 2 // Physical green LED is connected to pin 2
// Traffic light timings (in seconds)
int redTime = 15; // 15 seconds
int yellowTime = 3; // 3 seconds
int greenTime = 13; // 12 seconds
// State variables
enum TrafficState { RED, GREEN, YELLOW }; // Changed order to match new sequence
TrafficState currentState = RED;
unsigned long stateStartTime = 0;
int remainingTime = 0;
unsigned long lastUpdateTime = 0;
bool blinkState = false;
unsigned long lastBlinkTime = 0;
bool greenDelayActive = false;
unsigned long greenDelayStartTime = 0;
void setup() {
// Initialize LED pins
pinMode(RED_LED, OUTPUT);
pinMode(YELLOW_LED, OUTPUT);
pinMode(GREEN_LED, OUTPUT);
// Initialize OLED display
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
for(;;);
}
display.clearDisplay();
display.setTextColor(SSD1306_WHITE);
// Start with red light
setLights(RED);
stateStartTime = millis();
lastUpdateTime = millis();
lastBlinkTime = millis();
remainingTime = redTime;
}
void loop() {
unsigned long currentTime = millis();
// Handle green light delay
if (greenDelayActive) {
if (currentTime - greenDelayStartTime >= 1000) { // 1 second delay
greenDelayActive = false;
changeState(GREEN);
}
return; // Don't process other logic during delay
}
// Update display every second (1000 milliseconds)
if (currentTime - lastUpdateTime >= 1000) {
lastUpdateTime = currentTime;
// Calculate elapsed time in seconds
unsigned long elapsedSeconds = (currentTime - stateStartTime) / 1000;
// Calculate remaining time based on current state - UPDATED SEQUENCE
switch(currentState) {
case RED:
remainingTime = redTime - elapsedSeconds;
if(remainingTime <= 0) {
startGreenDelay(); // Start 1-second delay before green
}
break;
case GREEN:
remainingTime = greenTime - elapsedSeconds;
if(remainingTime <= 0) {
changeState(YELLOW); // Green goes to Yellow now
}
break;
case YELLOW:
remainingTime = yellowTime - elapsedSeconds;
if(remainingTime <= 0) {
changeState(RED); // Yellow goes to Red
}
break;
}
// Ensure remaining time doesn't go below 0
if(remainingTime < 0) remainingTime = 0;
// Update display with big numbers
updateDisplay();
}
// Handle blinking for yellow light
if (currentState == YELLOW) {
if (currentTime - lastBlinkTime >= 500) { // Blink every 500ms
lastBlinkTime = currentTime;
blinkState = !blinkState;
updateDisplay();
}
}
}
void startGreenDelay() {
greenDelayActive = true;
greenDelayStartTime = millis();
// Turn off all lights during delay
digitalWrite(RED_LED, LOW);
digitalWrite(YELLOW_LED, LOW);
digitalWrite(GREEN_LED, LOW);
// Update display to show "00" during delay
display.clearDisplay();
display.setTextSize(4);
display.setTextColor(SSD1306_WHITE);
display.setCursor((SCREEN_WIDTH - 64) / 2, (SCREEN_HEIGHT - 32) / 2);
display.print("00");
display.display();
}
void changeState(TrafficState newState) {
currentState = newState;
stateStartTime = millis();
lastUpdateTime = millis();
lastBlinkTime = millis();
blinkState = true; // Start with display ON
setLights(newState);
}
void setLights(TrafficState state) {
// Turn off all LEDs first
digitalWrite(RED_LED, LOW);
digitalWrite(YELLOW_LED, LOW);
digitalWrite(GREEN_LED, LOW);
// Turn on the appropriate LED
switch(state) {
case RED:
digitalWrite(RED_LED, HIGH); // This will now activate pin 4 (your physical red LED)
remainingTime = redTime;
break;
case GREEN:
digitalWrite(GREEN_LED, HIGH); // This will now activate pin 2 (your physical green LED)
remainingTime = greenTime;
break;
case YELLOW:
digitalWrite(YELLOW_LED, HIGH); // This activates pin 3 (unchanged)
remainingTime = yellowTime;
break;
}
}
void updateDisplay() {
display.clearDisplay();
// Display big centered two-digit number
display.setTextSize(7); // Large text size
display.setTextColor(SSD1306_WHITE);
char timeStr[3];
// For yellow light, show blinking "00" instead of countdown
if (currentState == YELLOW) {
if (blinkState) {
sprintf(timeStr, "00");
} else {
// Don't display anything during off phase (creates blink effect)
display.display();
return;
}
} else {
// For red and green, show normal countdown
sprintf(timeStr, "%02d", remainingTime);
}
// Calculate position to center the text
int16_t x1, y1;
uint16_t w, h;
display.getTextBounds(timeStr, 0, 0, &x1, &y1, &w, &h);
int x = (SCREEN_WIDTH - w) / 2;
int y = (SCREEN_HEIGHT - h) / 2;
// Display the big centered number
display.setCursor(x, y);
display.print(timeStr);
display.display();
}
Code Explanation:
Setup:
Initializes LED pins (Red-pin4, Yellow-pin3, Green-pin2), OLED display, and starts with Red light state. Sets up timing variables for the traffic light sequence.
Loop:
Manages the complete traffic light cycle: Red (15s) → 1s delay → Green (13s) → Yellow (3s) → Red. Updates OLED display every second with countdown, and handles yellow light blinking with "00" display.
Why Choose This Design?
- ✅ Professional PCB: Custom traffic light-shaped board for authentic appearance
- 📱 Visual Feedback: OLED display shows real-time countdown for each phase
- 🚦 Realistic Timing: Standard traffic light sequences with proper transitions
- ⚡ Quality Components: 10mm LEDs with proper current-limiting resistors
- 🔧 Easy Assembly: Pre-designed PCB simplifies construction
- 🎯 Educational Value: Perfect for learning Arduino, PCB design, and traffic systems
Learning Outcomes
- PCB Design: Understanding custom circuit board layout and manufacturing
- Arduino Programming: State machines, timing control, and display interfaces
- OLED Integration: Working with I2C displays and graphics libraries
- LED Control: Proper current limiting and sequencing techniques
- Real-world Systems: Implementing practical traffic control logic
Comments
Post a Comment