← All projects

IoT Traffic Controller Light

An ESP32 traffic-light system with a crosswalk, an LCD and a remote emergency light, built in five stages.

The real Serial Monitor output after pressing the button

== Do Not Walk ==
Count =  10  == Walk ==
Count =  9  == Walk ==
Count =  8  == Walk ==
Count =  7  == Walk ==
Count =  6  == Walk ==
Count =  5  == Walk ==
Count =  4  == Walk ==
Count =  3  == Walk ==
Count =  2  == Walk ==
Count =  1  == Walk ==
== Do Not Walk ==
== Do Not Walk ==

Both light sets, the crosswalk button, the emergency light and the Serial Monitor, rebuilt so you can try them.

Course
CEIS114, DeVry University
Tools
ESP32 (DOIT DevKit V1), Arduino IDE 2, C++, LiquidCrystal_I2C, Cayenne MQTT
Timeframe
2022
Scroll for more

Overview

I built a traffic-light controller on an ESP32 and added to it one stage at a time. It started as a single red, yellow and green light. Then I added a second set of lights for a crossing street, a crosswalk button with a countdown, an LCD and buzzer for pedestrians, and finally a blue emergency light I could switch on remotely over Wi-Fi through the Cayenne MQTT dashboard.

Breadboard circuit with two sets of red, yellow and green LEDs, a lit blue LED, a push button, a buzzer and an LCD reading "CEIS114, Do Not Walk", wired to an ESP32. (open larger image)
The finished build: two traffic-light sets, the blue emergency light, a buzzer, the crosswalk button and the LCD.

How I built it

Five stages, one board. Each stage adds one feature to the last, with its photos and the setup code.

One traffic light.

I wired a red, yellow and green LED to GPIO 14, 12 and 13 and wrote a sketch that cycles them, with a two-second delay between changes.

// Module 3: one traffic light
const int red_LED1 = 14;
const int yellow_LED1 = 12;
const int green_LED1 = 13;

void setup() {
  pinMode(red_LED1, OUTPUT);
  pinMode(yellow_LED1, OUTPUT);
  pinMode(green_LED1, OUTPUT);
}

Two lights at an intersection.

I added a second set of LEDs on GPIO 25, 26 and 27 so the two directions take turns.

const int red_LED2 = 25;
const int yellow_LED2 = 26;
const int green_LED2 = 27;

Crosswalk button.

I added a push button on GPIO 19. Pressing it starts a pedestrian cycle: the Serial Monitor shows "Do Not Walk", counts down from 10, then shows "Walk".

int Xw_value;
const int Xw_button = 19; // crosswalk button

// in setup():
pinMode(Xw_button, INPUT_PULLUP); // 0 = pressed, 1 = not pressed
Serial.begin(115200);

LCD and buzzer.

I connected a 16x2 LCD over I2C (address 0x27) and a buzzer on GPIO 32. The LCD shows "CEIS114" on the top line and the walk status on the bottom line.

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 16, 2); // 16x2 LCD at I2C address 0x27
const int bzr = 32;                 // buzzer

// in setup():
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);

Emergency light over Wi-Fi.

I added a blue LED on GPIO 16 and connected the ESP32 to the Cayenne IoT platform over MQTT, so I could switch the emergency light on remotely from the Cayenne dashboard. The Serial Monitor confirms the board joins Wi-Fi and then connects to the Cayenne MQTT broker.

#define CAYENNE_PRINT Serial
#include <CayenneMQTTESP32.h>

// Wi-Fi and Cayenne credentials are set here and are not published.

int ONOFF;
const int LED0 = 16; // GPIO16 drives the emergency light

Before the first stage

  1. Gathered the parts.

    The final build uses an ESP32 board, red, yellow, green and blue LEDs, 220-ohm resistors, a push button, a 16x2 LCD with an I2C adapter, an active buzzer, wires and breadboards.

  2. Set up the board.

    I mounted the ESP32 on a breadboard, powered it over USB, and installed Arduino IDE 2 with the board set to DOIT ESP32 DEVKIT V1. A Wi-Fi scan sketch confirmed the board could see nearby networks.

These are the setup sections of each stage's sketch.

Photos from the build (3)

Challenges and what I learned

Challenges

  • At first my computer wouldn't recognize the board.Updating my USB drivers fixed it.
  • The board wouldn't connect to my Wi-Fi.Security settings on my router were blocking it.

What I learned

I learned to design and build breadboard circuits, write and upload C++ sketches in the Arduino IDE, install libraries, and troubleshoot and test a circuit when it doesn't behave. I also got a working grasp of basic electronics and of how IoT devices talk to cloud services. Building one stage at a time meant every new feature started from something that already worked.

Next project: Programming With Data →

Python scripts, a SQLite database and two weeks of NOAA weather data.