Project Overview
This project creates a gesture-controlled light switch that turns lights on and off with a simple hand wave. Using a PIR sensor, the system detects motion and toggles a relay that controls the light. A short wave turns the light on, and another wave turns it off. It’s perfect for situations where your hands are dirty or full.
Difficulty: Beginner
Estimated time: 1-2 hours
Estimated cost: $15-25
How It Works
A PIR sensor detects hand movement within a short range (10-30cm). Each time motion is detected, the Arduino toggles a relay that controls the light. The system includes a status LED to indicate the current state and a timeout to prevent rapid toggling (debounce).
Unlike traditional motion-sensing lights that turn on and then off automatically, this system maintains the state until another gesture is detected, giving you full control.
Materials Needed
- Arduino Nano or Arduino Uno (1)
- HC-SR501 PIR sensor (1) – with sensitivity set to minimum range
- Relay module (5V, single channel)
- LED (for status indication)
- Resistor (220Ω for LED)
- Jumper wires
- Power supply (5V 1A)
- Project enclosure
- Optional: AC power cord and outlet (for controlling a lamp)
Circuit Diagram
Connection Table
| Component | Pin | Arduino Pin | PIR Sensor | VCC | 5V | PIR Sensor | GND | GND | PIR Sensor | OUT | Digital Pin 2 | Relay Module | VCC | 5V | Relay Module | GND | GND | Relay Module | IN | Digital Pin 3 | Status LED | Anode | Digital Pin 13 (through 220Ω) | Status LED | Cathode | GND |
|---|
PIR Sensor Adjustment
For gesture control, you want very short range (10-30cm):
- Turn sensitivity potentiometer fully counter-clockwise (minimum range).
- Set time delay to minimum (fully counter-clockwise).
- Set jumper to non-repeatable mode (L) for single triggers.
Arduino Code
// Gesture-Controlled Light Switch
// Wave hand to toggle light on/off
const int pirPin = 2;
const int relayPin = 3;
const int ledPin = 13;
bool lightState = false;
unsigned long lastTriggerTime = 0;
const unsigned long debounceDelay = 1000; // 1 second debounce
void setup() {
Serial.begin(9600);
pinMode(pirPin, INPUT);
pinMode(relayPin, OUTPUT);
pinMode(ledPin, OUTPUT);
digitalWrite(relayPin, LOW);
digitalWrite(ledPin, LOW);
Serial.println("Gesture Light Switch Ready");
Serial.println("Wave hand to toggle light");
delay(30000); // Short warm-up (30 seconds is enough for gesture use)
}
void toggleLight() {
lightState = !lightState;
digitalWrite(relayPin, lightState ? HIGH : LOW);
digitalWrite(ledPin, lightState ? HIGH : LOW);
Serial.print("Light ");
Serial.println(lightState ? "ON" : "OFF");
}
void loop() {
bool motion = digitalRead(pirPin) == HIGH;
if (motion && (millis() - lastTriggerTime > debounceDelay)) {
lastTriggerTime = millis();
toggleLight();
}
delay(50);
}
Enhanced Version with LED Feedback
// Enhanced version with LED fade effect
const int pirPin = 2;
const int relayPin = 3;
const int ledPin = 13;
bool lightState = false;
unsigned long lastTriggerTime = 0;
const unsigned long debounceDelay = 1000;
unsigned long fadeStartTime = 0;
bool fading = false;
void fadeLED(int start, int end) {
int duration = 500; // 500ms fade
unsigned long startTime = millis();
while (millis() - startTime < duration) {
int brightness = map(millis() - startTime, 0, duration, start, end);
analogWrite(ledPin, brightness);
delay(5);
}
analogWrite(ledPin, end);
}
void toggleLight() {
lightState = !lightState;
digitalWrite(relayPin, lightState ? HIGH : LOW);
if (lightState) {
fadeLED(0, 255);
} else {
fadeLED(255, 0);
}
Serial.print("Light ");
Serial.println(lightState ? "ON" : "OFF");
}
void setup() {
Serial.begin(9600);
pinMode(pirPin, INPUT);
pinMode(relayPin, OUTPUT);
pinMode(ledPin, OUTPUT);
digitalWrite(relayPin, LOW);
digitalWrite(ledPin, LOW);
delay(30000);
}
void loop() {
bool motion = digitalRead(pirPin) == HIGH;
if (motion && (millis() - lastTriggerTime > debounceDelay)) {
lastTriggerTime = millis();
toggleLight();
}
delay(50);
}
Mounting Options
Drawer/Cabinet Lighting
- Mount PIR sensor inside the drawer or cabinet facing upward/outward.
- Install LED strip inside the drawer/cabinet.
- Connect LED strip to relay (use appropriate power supply for LED strip).
- Wave hand near the drawer to toggle lights on/off.
Desk/Workbench Lamp
- Mount PIR sensor near the lamp base.
- Connect lamp plug to relay-controlled outlet.
- Wave hand near the lamp to toggle.
Installation Steps
- Adjust PIR sensor: Set sensitivity to minimum range.
- Assemble circuit: Build on breadboard and test.
- Upload code: Test gesture detection (wave hand within 10-20cm).
- Mount sensor: Position sensor in desired location.
- Connect light: Wire the lamp or LED strip to the relay.
- Enclose electronics: Place Arduino and relay in a safe enclosure.
- Final test: Wave hand to turn light on/off.
Project Extensions
- Dimmer function: Add a second PIR sensor for dimming control (wave left to dim, right to brighten).
- Color control: Use RGB LED strip and cycle colors with multiple gestures.
- Multiple zones: Add multiple PIR sensors to control different lights.
- Smart home integration: Add ESP32 to send state to Home Assistant.
- Battery backup: Add rechargeable battery for portable use.
Troubleshooting
- Light toggles randomly: Reduce sensitivity further. Add physical shield to limit detection area.
- No detection: Adjust sensitivity upward slightly. Ensure hand is within detection zone.
- Multiple toggles per gesture: Increase
debounceDelay. - Relay not switching: Check relay wiring. Test with LED first.
Safety Notes
- If controlling AC-powered lights, ensure relay is rated for the load.
- Keep all wiring away from water.
- Use a proper enclosure to prevent electrical shock.
Conclusion
This gesture-controlled light switch adds a touch of magic to any room. It’s perfect for kitchens (hands full of dishes), workshops (hands covered in paint), or simply for the novelty of waving to control lights.
