Advertisement
Beginner Time: 1–2 weeks Electrical Engineering

Automatic Street Light Controller

Build an intelligent street light system that automatically turns on at dusk and off at dawn, with IoT monitoring.

LDRRelayTimerIoTEnergy SavingArduino
DifficultyBeginner
Duration1–2 weeks
Components12 items
Steps8 steps

Introduction

An Automatic Street Light Controller is an intelligent system that automatically switches street lights on and off based on ambient light levels, time schedules, and optionally traffic conditions. Traditional manually operated or timer-based street lights waste significant energy by operating during daylight hours or at full brightness when traffic is minimal. This project implements a smart control system using Light Dependent Resistors (LDR) or photoresistor sensors combined with a real-time clock (RTC) module and an Arduino microcontroller. The system can also incorporate motion detection for adaptive dimming — reducing brightness to 30% during low-traffic hours and increasing to 100% when motion is detected, saving up to 60% of energy compared to conventional systems. This project is an excellent introduction to sensor interfacing, relay control, analog-to-digital conversion, and embedded C programming. Municipal corporations and smart city initiatives extensively use such systems, making this a highly relevant and practically deployable project.

Theory & Background

Light Dependent Resistors (LDRs) are photosensitive semiconductor devices whose resistance changes inversely with incident light intensity — high resistance in darkness (>1MΩ), low resistance in bright light (<100Ω). When connected in a voltage divider configuration with a fixed resistor, the voltage at the midpoint varies with light levels, which the Arduino's analog input reads and converts to a 10-bit digital value (0–1023). The Arduino's onboard ADC (Analog-to-Digital Converter) has a reference voltage of 5V, so each bit represents 4.88mV. A relay acts as an electrically controlled switch — the Arduino drives the relay's coil through a transistor (since the relay requires more current than the Arduino can provide), and the relay's contacts switch the high-voltage AC supply to the street light. The real-time clock (DS3231) maintains accurate time even during power outages using a coin cell backup battery, enabling time-based override rules. PWM (Pulse Width Modulation) output from the Arduino can be used to control LED driver brightness by varying the duty cycle.

Advertisement

Components & Requirements

12 components required for this project.

#ComponentPurposeQty
1Arduino Uno R3Main microcontrollerx1
2LDR (GL5528) PhotoresistorAmbient light sensing (redundant pair)x2
3DS3231 RTC ModuleAccurate real-time clock with alarmx1
45V Relay Module (Single Channel)Switching street light circuitsx4
5HC-SR501 PIR Motion SensorTraffic/pedestrian detection for dimmingx2
610kΩ ResistorsLDR voltage dividerx4
7BC547 NPN TransistorRelay driver (if not using relay module)x4
81N4007 Freewheeling DiodeBack-EMF protection for relay coilx4
9ESP8266 WiFi ModuleIoT data reportingx1
10LED Street Light (12V, 10W)Prototype lighting loadsx4
1112V 2A DC AdapterSystem powerx1
12OLED 0.96" Display (I2C)Status displayx1

Step-by-Step Implementation

Follow these 8 steps carefully.

1
Circuit Design and LDR Calibration

Build a voltage divider circuit: connect LDR between 5V and a node, then 10kΩ resistor from that node to GND. Connect the node to Arduino A0. Record ADC values in different conditions: full daylight, indoor lighting, twilight, and complete darkness. Set a threshold value (typically ADC ~400–600 for dusk/dawn transition) in your code.

2
RTC Module Integration

Connect DS3231 to Arduino via I2C (SDA→A4, SCL→A5). Install the RTClib library in Arduino IDE. First, run the RTC set time sketch to sync the RTC to your computer's current time. The DS3231 maintains ±2 ppm accuracy (about 1 minute per year). Use RTC.now() to get current time object with hour(), minute(), second() methods.

3
Relay Circuit Wiring

For each relay module: connect IN pin to Arduino digital output, VCC to 5V, GND to GND. The relay module typically includes the transistor driver and freewheeling diode onboard. Connect the relay NC (Normally Closed) contacts to the street light circuit — this ensures lights are ON during controller failure (fail-safe). Wire the COM terminal to the 12V supply positive.

4
Control Logic Programming

Implement a state machine with three states: FORCED_ON (nighttime by RTC), FORCED_OFF (daytime by RTC), and LDR_CONTROLLED (twilight transition ±30 min around sunset/sunrise). Add hysteresis to LDR threshold (e.g., turn ON below 400, turn OFF above 600) to prevent rapid switching during clouds. Implement a debounce delay of 5 seconds before state changes.

5
PIR Integration for Adaptive Dimming

Connect PIR sensors (HC-SR501) to digital input pins. When street light is ON and no PIR activity for >5 minutes, engage dimming by reducing PWM duty cycle to 30% (use analogWrite for LED drivers). When PIR detects motion, immediately return to 100% brightness. This adaptive dimming can save 50–70% energy during late-night low-traffic periods.

6
IoT Monitoring with ESP8266

Connect ESP8266 to Arduino via SoftwareSerial (pins 10, 11). Program Arduino to send status string: LIGHT:ON,LDR:345,TIME:22:30,PIR:0 every minute. Program ESP8266 to receive this string and POST to ThingSpeak or IFTTT. Set up alerts via email or SMS when a light fails (current sensor reading zero when relay is closed indicates lamp failure).

7
Fault Detection System

Add a non-invasive current sensor (ACS712) in series with each lamp circuit. If relay is closed but current sensor reads zero, generate a fault flag and send an alert via ESP8266. Log fault timestamp and location ID. This enables predictive maintenance — identifying and replacing failed lamps before manual inspection. Store fault log in Arduino EEPROM.

8
Testing and Deployment

Test in a darkened room by covering the LDR to simulate night conditions. Verify relay activates within 5 seconds of LDR threshold crossing. Check RTC time accuracy over 24 hours. Test PIR dimming by standing still for 5 minutes. Simulate a lamp failure by disconnecting one lamp and verifying fault alert. If deploying outdoors, enclose electronics in an IP65-rated waterproof box.

Code & Implementation

Core code for street_light.ino:

street_light.ino C/C++
#include <Wire.h> #include <RTClib.h>  RTC_DS3231 rtc;  #define LDR_PIN    A0 #define RELAY_PIN  7 #define PIR_PIN    6 #define DIM_PWM    9     #define LDR_ON     450   #define LDR_OFF    600    bool lightOn = false; unsigned long lastPIR = 0;  void setup() {   Serial.begin(9600);   pinMode(RELAY_PIN, OUTPUT);   pinMode(PIR_PIN, INPUT);   pinMode(DIM_PWM, OUTPUT);      if (!rtc.begin()) { Serial.println("RTC not found!"); while(1); }               digitalWrite(RELAY_PIN, LOW);  }  void loop() {   DateTime now = rtc.now();   int ldr = analogRead(LDR_PIN);   bool pir = digitalRead(PIR_PIN);      if (pir) lastPIR = millis();         bool daytime = (now.hour() >= 7 && now.hour() < 18);      bool nighttime = (now.hour() >= 19 || now.hour() < 6);      if (daytime) {     lightOn = false;   } else if (nighttime) {     lightOn = true;   } else {          if (!lightOn && ldr < LDR_ON)  lightOn = true;     if (lightOn  && ldr > LDR_OFF) lightOn = false;   }      digitalWrite(RELAY_PIN, lightOn ? HIGH : LOW);         if (lightOn) {     bool motionRecent = (millis() - lastPIR < 300000UL);      int brightness = motionRecent ? 255 : 77;      analogWrite(DIM_PWM, brightness);   }         Serial.print("Time: "); Serial.print(now.hour());   Serial.print(":"); Serial.print(now.minute());   Serial.print(" LDR: "); Serial.print(ldr);   Serial.print(" Light: "); Serial.println(lightOn ? "ON" : "OFF");      delay(1000); }

Testing & Troubleshooting

Test LDR response by covering and uncovering the sensor while monitoring Serial Monitor readings. Verify the relay clicks at the configured LDR threshold. Test time override by temporarily changing the RTC time to 12:00 PM and confirming lights stay off despite covering the LDR. Test PIR dimming by waiting 5 minutes without movement and verifying brightness reduction, then moving and verifying immediate return to full brightness. Measure actual current consumption with and without PIR dimming using a clamp meter — dimmed current should be 25–35% of full current. If deploying multiple poles, test the central IoT dashboard shows all pole statuses correctly.

!
Troubleshooting Tips

Verify power voltages, check ground connections, use serial monitor for debug.

Real-World Applications

*Municipal street lighting networks
*Campus and university pathway lighting
*Parking lot lighting automation
*Industrial facility perimeter lighting
*Highway and road lighting
*Smart city infrastructure
*Solar-powered street lights
*Residential colony common area lighting

Extensions & Next Steps

  • Add GPS-based sunset/sunrise time calculation for any location
  • Implement LoRa (Long Range) radio for large-scale deployment without WiFi
  • Add a GSM module for SMS alerts in areas without internet
  • Integrate energy metering to calculate and bill energy per pole
  • Use machine learning to predict optimal dim schedule from traffic patterns
  • Add camera module for real-time traffic counting

Interactive Playground

Coming Soon

An interactive simulator will be available here — simulate circuits and run code in-browser without hardware.

Frequently Asked Questions

Why is there sometimes rapid on-off switching of the street light at dusk?
This is called chattering and occurs when the LDR reading fluctuates around the threshold during twilight due to passing clouds or wind-blown trees. The solution is hysteresis — setting a different threshold for turning on (e.g., ADC < 400) versus turning off (ADC > 600). This creates a dead band where the light maintains its current state, preventing rapid switching.
Can this system control multiple street lights from one controller?
Yes! One Arduino can directly control 4–6 lights using separate relay channels. For larger networks (100+ lights), use a master controller communicating with slave nodes via RS485 or LoRa radio. Each slave node controls 4–8 lights and responds to commands from the central master that has RTC and LDR.
How accurate is LDR-based dusk/dawn detection compared to GPS-based calculation?
LDR is highly accurate for the actual local light conditions including weather effects — it turns on during a dark cloudy day and off during a bright full moon night. GPS-calculated sunset times are astronomically precise but don't account for local obstructions, clouds, or nearby structures. Best practice is to use GPS as a hard override (no light before 5 AM or after 11 PM) and LDR for twilight control.
What is the typical power consumption of this controller circuit?
The Arduino Uno consumes about 46mA at 5V (0.23W). Each relay module coil draws 60–80mA when energized. The ESP8266 draws up to 200mA during WiFi transmission. Total controller consumption including one relay and ESP8266: approximately 0.35W in normal operation. Over a year, this is less than 3 kWh — negligible compared to the energy saved by adaptive dimming.
How do I handle power interruptions to prevent the RTC from losing time?
The DS3231 RTC module has an onboard coin cell battery (CR2032) backup. Even with main power removed, the RTC continues keeping time using the coin cell for 3–5 years. On power restoration, the Arduino reads the current time from the RTC — no manual resetting is needed. For added reliability, optionally sync the RTC via NTP through the ESP8266 when internet is available.
Advertisement