Project Overview
This project creates a smart night light that turns on when motion is detected and gradually dims over time. The light uses an RGB LED or LED strip and features smooth fade-out effects, making it perfect for bedrooms, hallways, and children’s rooms.
Difficulty: Beginner
Estimated time: 1-2 hours
Estimated cost: $15-25
How It Works
A PIR sensor detects motion. When motion is detected, the LED turns on at full brightness. After a set period without motion, the light gradually dims over several seconds rather than turning off abruptly. An optional ambient light sensor (LDR) can be added so the light only activates when it is dark enough.
Materials Needed
- Arduino Nano or Arduino Uno (1)
- HC-SR501 PIR sensor (1)
- RGB LED (common cathode) or WS2812B LED strip (3-5 LEDs)
- LDR photoresistor (optional)
- 10kΩ resistor (for LDR voltage divider)
- 220Ω resistors (3 for RGB LED)
- Project enclosure
- Jumper wires
- USB power supply (5V 1A)
Circuit Diagram
Connection Table (RGB LED Version)
| Component |
Pin |
Arduino Pin |
PIR Sensor |
VCC
5V
PIR Sensor |
GND
GND
PIR Sensor |
OUT
Digital Pin 2
RGB LED (Red) |
Anode
Digital Pin 9 (via 220Ω)
RGB LED (Green) |
Anode
Digital Pin 10 (via 220Ω)
RGB LED (Blue) |
Anode
Digital Pin 11 (via 220Ω)
RGB LED |
Cathode
GND
LDR |
One leg
5V
LDR |
Other leg
Analog Pin A0 and 10kΩ to GND
表
Arduino Code
// PIR Night Light with Auto Dimming
const int pirPin = 2;
const int redPin = 9;
const int greenPin = 10;
const int bluePin = 11;
const int ldrPin = A0;
int redValue = 255;
int greenValue = 180;
int blueValue = 100;
unsigned long lastMotionTime = 0;
const unsigned long holdTime = 30000;
const unsigned long fadeDuration = 5000;
bool lightsOn = false;
int currentBrightness = 0;
unsigned long fadeStartTime = 0;
void setup() {
Serial.begin(9600);
pinMode(pirPin, INPUT);
pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);
setBrightness(0);
Serial.println("Night Light Ready");
delay(60000);
}
void setColor(int r, int g, int b) {
analogWrite(redPin, r);
analogWrite(greenPin, g);
analogWrite(bluePin, b);
}
void setBrightness(int percent) {
int r = map(percent, 0, 100, 0, redValue);
int g = map(percent, 0, 100, 0, greenValue);
int b = map(percent, 0, 100, 0, blueValue);
setColor(r, g, b);
currentBrightness = percent;
}
bool isDark() {
int ldrValue = analogRead(ldrPin);
return ldrValue < 500;
}
void fadeOut() {
unsigned long elapsed = millis() - fadeStartTime;
if (elapsed >= fadeDuration) {
setBrightness(0);
lightsOn = false;
} else {
int brightness = 100 - (elapsed * 100 / fadeDuration);
setBrightness(brightness);
}
}
void loop() {
if (!isDark() && lightsOn) {
setBrightness(0);
lightsOn = false;
}
bool motionDetected = digitalRead(pirPin) == HIGH;
if (motionDetected && isDark()) {
lastMotionTime = millis();
if (!lightsOn) {
setBrightness(100);
lightsOn = true;
} else if (currentBrightness < 100) {
setBrightness(100);
}
fadeStartTime = 0;
}
if (lightsOn) {
if (millis() - lastMotionTime > holdTime) {
if (fadeStartTime == 0) {
fadeStartTime = millis();
}
fadeOut();
} else {
fadeStartTime = 0;
}
}
delay(50);
}
WS2812B LED Strip Version
#include <FastLED.h>
#define LED_PIN 6
#define NUM_LEDS 5
#define BRIGHTNESS 128
CRGB leds[NUM_LEDS];
const int pirPin = 2;
const int ldrPin = A0;
unsigned long lastMotionTime = 0;
const unsigned long holdTime = 30000;
const unsigned long fadeDuration = 5000;
bool lightsOn = false;
int currentBrightness = 0;
unsigned long fadeStartTime = 0;
void setup() {
FastLED.addLeds<WS2812B, LED_PIN, GRB>(leds, NUM_LEDS);
FastLED.setBrightness(0);
pinMode(pirPin, INPUT);
delay(60000);
}
void setBrightness(int percent) {
int brightness = map(percent, 0, 100, 0, BRIGHTNESS);
FastLED.setBrightness(brightness);
FastLED.show();
currentBrightness = percent;
}
void setColor(CRGB color) {
for (int i = 0; i < NUM_LEDS; i++) {
leds[i] = color;
}
FastLED.show();
}
void loop() {
int ldrValue = analogRead(ldrPin);
bool isDark = ldrValue < 500;
bool motionDetected = digitalRead(pirPin) == HIGH;
if (motionDetected && isDark) {
lastMotionTime = millis();
if (!lightsOn) {
setColor(CRGB::White);
setBrightness(100);
lightsOn = true;
} else if (currentBrightness < 100) {
setBrightness(100);
}
fadeStartTime = 0;
}
if (lightsOn) {
if (millis() - lastMotionTime > holdTime) {
if (fadeStartTime == 0) {
fadeStartTime = millis();
}
unsigned long elapsed = millis() - fadeStartTime;
if (elapsed >= fadeDuration) {
setBrightness(0);
lightsOn = false;
} else {
int brightness = 100 - (elapsed * 100 / fadeDuration);
setBrightness(brightness);
}
}
}
delay(50);
}
Installation Steps
- Assemble circuit on breadboard and test with USB power
- Upload code and adjust color values as desired
- Calibrate LDR threshold based on ambient light
- Test motion detection by walking past the sensor
- Place components in a small enclosure
- Drill holes for PIR sensor lens and LED
- Position unit at 0.5-1m height facing the area to monitor
Project Extensions
- Use addressable LED strip for longer runs
- Add color temperature sensing to match room lighting
- Add Bluetooth module for color control from phone
- Use deep sleep to reduce power consumption during the day
- Add microphone module for sound-reactive lighting
Conclusion
This smart night light provides gentle illumination when you need it and automatically fades out, making it perfect for bedrooms and hallways. The gradual dimming effect is much more pleasant than abrupt switching off.