An elegant, interrupt-driven firmware architecture engineered for ultra-low-power deployment. Designed natively for the Arduino Uno/Nano architecture, and physically unified to scale directly to the ESP32 platform, this repository contains a non-blocking state machine that controls transistor load based on sensor motion and ambient daylight gating. This lighting system is ideal for indoor stairways, hallways, and other low-light residential applications.
- Asynchronous State Machine: Employs non-blocking
millis()timing loops instead of blockingdelay()calls, allowing the system to handle dynamic real-time retriggers effortlessly. - Hardware Interrupt Wake: Maps motion tracking across native AVR hardware interrupt line (
INT0) to shock the CPU core back to life the exact millisecond motion occurs. - Streamlined Unified Architecture: Utilizes an optimized empty Interrupt Service Routine (ISR) as a pure hardware wake-up portal. This design unifies the edge-detection logic so the same code pattern ports flawlessly across both AVR (paused-line) and ESP32 (cold-reboot) architectures.
- Daylight Gating: Samples an Analog-to-Digital Converter (ADC) pipeline connected to an LDR circuit, preventing unnecessary load deployment during daytime hours.
- Anti-Lockup Sleep Guard: Features a smart validation engine that performs fresh, live reads on physical pins at the absolute last line of execution. This prevents the system from entering an infinite sleep lock on a stale
RISINGedge snapshot.
| Component Reference | Description |
|---|---|
| Arduino Uno R3 (Microcontroller) | ElEGOO UNO R3 |
| HC-SR501 (Sensor) | HC-SR501 Passive Infrared Sensor |
| LED1 - LED3 & R3 (Diode) | LED Light |
| Q1 (Transistor) | PN 2222A NPN Transistor |
| R1 (Resistor) | Photoresistor |
| R2 (Resistor) | 10K Ohm Resistor |
| R4 (Resistor) | 220 Ohm Resistor |
| V1 (Voltage) | 9V Power Adapter |
Note
The LED light is a standalone device that essentially consists of the represented components and a two-AA battery holder system wired in series to provide 3V. I originally intended to keep the LED light on its own independent power supply, which was the primary reason for modifying the device with a PN2222A NPN transistor, but ultimately ended up wiring the positive terminal directly to the Arduino's 3.3V rail. Additionally, the device features an integrated hardware power button (permanently kept in the "ON" state) which was omitted from the schematic.
| Arduino Pin | Peripheral Component | Configuration | Notes |
|---|---|---|---|
| Pin 2 | PIR Sensor | INPUT |
Maps to Hardware Interrupt INT0 |
| Pin 9 | Transistor Gate / Driver | OUTPUT |
Drives load (e.g., LED arrays, relays) |
| Pin 13 | Built-in Status LED | OUTPUT |
Blinks on motion detection |
| Pin A0 | LDR (Light Dependent Resistor) | INPUT (Analog) |
Tracks ambient light levels against threshold |
+-----------------------+
| Deep Sleep State | <------------------------------------+
| (CPU Halts, Timers | |
| Off, Drawing <0.5µA) | |
+-----------------------+ |
| |
[Motion Trips HW Pin] |
v |
+-----------------------+ |
| Empty ISR Wake-Up | |
| (Processor Re-Clocks) | |
+-----------------------+ |
| |
v |
+-----------------------+ |
| Edge-Detection & | |
| LDR Gating | |
+-----------------------+ |
| | |
[Daytime] [Nighttime] |
| v |
| +-------------------+ |
| | Turn On Load & | |
| | Start 30s Timer | |
| +-------------------+ |
| | |
| [Timer Counting] |
| (Retriggers Allowed) |
| v |
| +-------------------+ |
| | Timer Expires & | |
| | Turn Off Load | |
| +-------------------+ |
| | |
+-------->--------+ |
| |
v |
+----------------------------+ |
| Smart Sleep Decision | |
| - Is timer finished? | |
| - Are physical pins LOW? | |
+----------------------------+ |
| |
[Yes, Secure] |
+-----------------------------------------+
When compiling and flashing this code onto a bare development board without the physical PIR sensors wired up, the input pins (2 and 3) will be left in a high-impedance "floating" state.
In this configuration, the un-terminated pins act as microscopic antennas—picking up ambient electrostatic fields and electromagnetic interference from nearby electronics. This will cause the hardware interrupts to trigger continuously, logging ghost events to the Serial Monitor and preventing the chip from sleeping.
- To fix this during testing: Use jumper wires to bridge Pin 2 and Pin 3 directly to a GND pin. This ties the voltage reference securely to 0V, mimicking a quiet room and allowing you to safely observe the sleep transitions.
For optimal power profiling on standalone deployments, swap your primary development board for an Arduino Pro Mini (3.3V) or a bare ATmega328P IC circuit. Removing peripheral board burdens (like integrated USB-to-Serial chips and always-on power LEDs) allows the deep sleep command (SLEEP_MODE_PWR_DOWN) to successfully plummet your current consumption into the microamp range—extending standard 18650 battery runtime from days to months.
- Migrate to an ESP32 Platform: Port the core architecture to an ESP32 SoC to leverage its advanced deep sleep capabilities and achieve even lower overall power consumption.
- Implement an Intelligent Battery Management System (BMS): Design an automated power-path switching circuit to integrate a robust UPS backup battery (such as a Forza 12V 7.0AH or Forza FUB-1245 12V 4.5AH battery) to seamlessly maintain system operation when primary utility power is lost.
