Mains voltage (230 V) — can kill. The low-voltage side (board, sensors, display, relay module) is safe to build yourself. The mains side must be wired by a licensed electrician, and tested with the circuit switched off at the MCB.
- Never switch a motor with a relay module. Motors pull several times their running current at start-up; hobby relay contacts weld or overheat. The relay only drives a contactor’s coil (or your pump starter’s coil input).
- Contactor rated for motors (AC-3) at or above the load’s nameplate current.
- Protect and earth: MCB on live, RCCB/ELCB on the circuit, metal bodies earthed. Switch live only — never neutral or earth.
- Keep the two worlds apart: mains and low-voltage wiring in separate compartments of a closed, non-metallic enclosure; no bare 230 V terminals.
- Fail safe: the code switches the load off when a sensor stops answering. Still fit a manual override at the starter.
Parts list
| Part | Qty | Approx. | Buy |
|---|---|---|---|
| ESP32 DevKit V1 (30-pin) | 1 | ₹380 | Buy ESP32 DevKit V1 (30-pin) |
| HC-SR501 PIR motion sensor | 1 | ₹90 | Buy HC-SR501 PIR motion sensor |
| 1-channel relay module, 5 V coil, 3.3 V-trigger (active-LOW) | 1 | ₹70 | Buy 1-channel relay module, 5 V coil, 3.3 V-trigger (active-LOW) |
| Enclosed lamp holder + LED bulb (≤ 1 A) | 1 | ₹150 | Buy Enclosed lamp holder + LED bulb (≤ 1 A) |
| 5 V 1 A USB adapter + cable | 1 | ₹120 | Buy 5 V 1 A USB adapter + cable |
| Jumper wires | 1 | ₹30 | Buy Jumper wires |
| Total | ₹840 |
Affiliate disclosure: “Buy” links may earn FlashReady a small commission at no extra cost to you. Prices are indicative.
Wiring
| ESP32 DevKit V1 | Part · pin | Wire | Notes |
|---|---|---|---|
| — | 1-channel relay module (5 V coil) · COM | — | To Lamp circuit, live in (230 V, electrician only) (not drawn) |
| — | 1-channel relay module (5 V coil) · NO | — | To Lamp circuit, live to lamp (230 V, electrician only) (not drawn) |
| VIN | HC-SR501 PIR motion sensor · VCC | red | The HC-SR501 needs 4.5–20 V; VIN is 5 V from USB |
| D27 | HC-SR501 PIR motion sensor · OUT | yellow | 3.3 V output — safe for the ESP32 |
| GND | HC-SR501 PIR motion sensor · GND | black | |
| VIN | 1-channel relay module (5 V coil) · DC+ | red | |
| GND | 1-channel relay module (5 V coil) · DC− | black | |
| D26 | 1-channel relay module (5 V coil) · IN | green | Active-LOW |
Board quirks: The HC-SR501 has two trimmers: sensitivity (range) and its own hold time. Turn the hold time to minimum — the sketch handles the 60 s timer. Set the jumper to “H” (repeat trigger) so the output stays high while people keep moving.
Code
// Motion-activated light — ESP32 DevKit V1 + HC-SR501 PIR + 1-channel relay module.
// The lamp switches on when the PIR sees movement and off 60 s after the last movement.
// Relay module IN on D26 (active-LOW). PIR OUT on D27 (the HC-SR501 output is 3.3 V — safe for the ESP32).
constexpr uint8_t PIR_PIN = 27;
constexpr uint8_t RELAY_PIN = 26;
constexpr bool RELAY_ACTIVE_LOW = true;
constexpr unsigned long ON_TIME_MS = 60UL * 1000; // keep the lamp on this long after the last motion
bool lampOn = false;
unsigned long lastMotion = 0;
void setLamp(bool on) {
lampOn = on;
digitalWrite(RELAY_PIN, (on != RELAY_ACTIVE_LOW) ? HIGH : LOW);
Serial.println(on ? "Motion — lamp ON" : "Quiet — lamp OFF");
}
void setup() {
digitalWrite(RELAY_PIN, HIGH); // relay off before the pin becomes an output
pinMode(RELAY_PIN, OUTPUT);
pinMode(PIR_PIN, INPUT);
Serial.begin(115200);
setLamp(false);
// The HC-SR501 needs 30–60 s after power-up before its output can be trusted.
Serial.println("PIR warming up for 30 s…");
delay(30000);
Serial.println("Ready");
}
void loop() {
if (digitalRead(PIR_PIN) == HIGH) {
lastMotion = millis();
if (!lampOn) setLamp(true);
}
if (lampOn && millis() - lastMotion > ON_TIME_MS) setLamp(false);
delay(50);
}// Motion-activated light — ESP32 DevKit V1 + HC-SR501 PIR + 1-channel relay module.
// The lamp switches on when the PIR sees movement and off 60 s after the last movement.
// Relay module IN on D26 (active-LOW). PIR OUT on D27 (the HC-SR501 output is 3.3 V — safe for the ESP32).
constexpr uint8_t PIR_PIN = 27;
constexpr uint8_t RELAY_PIN = 26;
constexpr bool RELAY_ACTIVE_LOW = true;
constexpr unsigned long ON_TIME_MS = 60UL * 1000; // keep the lamp on this long after the last motion
bool lampOn = false;
unsigned long lastMotion = 0;
void setLamp(bool on) {
lampOn = on;
digitalWrite(RELAY_PIN, (on != RELAY_ACTIVE_LOW) ? HIGH : LOW);
Serial.println(on ? "Motion — lamp ON" : "Quiet — lamp OFF");
}
void setup() {
digitalWrite(RELAY_PIN, HIGH); // relay off before the pin becomes an output
pinMode(RELAY_PIN, OUTPUT);
pinMode(PIR_PIN, INPUT);
Serial.begin(115200);
setLamp(false);
// The HC-SR501 needs 30–60 s after power-up before its output can be trusted.
Serial.println("PIR warming up for 30 s…");
delay(30000);
Serial.println("Ready");
}
void loop() {
if (digitalRead(PIR_PIN) == HIGH) {
lastMotion = millis();
if (!lampOn) setLamp(true);
}
if (lampOn && millis() - lastMotion > ON_TIME_MS) setLamp(false);
delay(50);
}Compiled for esp32 on esp32 3.3.12 · 3 Nov 2026
How it works
The HC-SR501 watches for changes in infrared — a warm body walking across its field of view. When it sees one, its OUT pin goes HIGH at 3.3 V, which the ESP32 reads directly.
The sketch keeps the lamp on while motion keeps happening and starts a 60-second countdown from the last movement it saw. Sitting still at a desk for a minute will switch the light off; a small wave brings it back. Change ON_TIME_MS to taste.
The relay module isolates the lamp’s 230 V wiring from the ESP32. Keep the build to a lamp within the relay’s rating, put the mains side in a closed, non-metallic enclosure, and have an electrician wire it into a ceiling or wall circuit.
For the first 30 seconds after power-up the sketch ignores the sensor while it warms up — otherwise you’d get a burst of false triggers every time the power comes back.
Troubleshooting
The light turns on by itself
PIR sensors react to warm air and sunlight. Point it away from windows, heaters and AC vents, and lower the sensitivity trimmer.
It triggers for the first minute after power-up
That’s the PIR settling. The sketch waits 30 s before acting; some sensors need closer to 60 s.
The light never turns off
Check the HC-SR501 jumper and hold-time trimmer. If its own timer is set to several minutes, the output stays high that long regardless of the sketch.
Upgrades
- Add an LDR module so the light only comes on when it’s dark.
- Log motion events to Google Sheets or MQTT.
- Use a second PIR for a long corridor.



