An IOT based project used to control home appliances (Bulb & Fan) - using ESP32, Motion and Light sensors with Cloud ML Integration and Mobile control with Google voice control (Voice control is not done since it was under Paid subscription of Blynk working on alternate method)
| Component | Price |
|---|---|
| ESP32 | ₹290 |
| USB Cable | ₹40 |
| PIR motion sensor | ₹70 |
| Light sensor (LDR) | ₹40 |
| Relay module | ₹90 |
| Bulb | ₹60 |
| Breadboard & Jumper wire | ₹200 |
| Web Simulation Tools for ESP32 | |||||
|---|---|---|---|---|---|
| Wokwi | Tinkercad Circuits | Multisim | EasyEDA | EveryCircuit | Cirkit Designer |
| Left Pins | VIN | GND | D13 | D12 | D14 | D27 | D26 | D25 | D33 | D32 | D35 | D34 | VN | VP | EN |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Right Pins | 3V3 | GND | D15 | D2 | D4 | TX2 | RX2 | D5 | D18 | D19 | D21 | RX0 | TX0 | D22 | D23 |
| Pins | AO | DO | GND | VCC |
|---|
| Pins | GND | High [or] Low (OUT) | Power (VCC) | BL - Sensitivity Adjust | BR - Time Delay | LT(H) - Repeat trigger | BR(L) - Single trigger |
|---|
Three Pins facing up
BL - Bottom Left knob
BR - Bottom Right knob
LT - Left top - High - Repeat trigger
RT - Right top - Low - Single trigger
| Component | Pin | Connects to ESP32 | Notes |
|---|---|---|---|
| LDR Module | AO | D34 | Analog light input |
| VCC | 3V3 | Power | |
| GND | GND | Ground | |
| PIR Sensor | OUT | D32 | Digital motion signal |
| VCC | 5V (or VIN) | Power | |
| GND | GND | Common ground | |
| LED | Anode (+) | D25 | Control pin |
| Cathode (–) | GND (via 220Ω resistor) |
Install all the Arduino IDE
Install all the necessary Board manager packages
1. esp32 (by Espressif Systems - version 3.3.2)
Add this url in File -> Preferences -> Additional board managers
https://espressif.github.io/arduino-esp32/package_esp32_index.json
Install all the necessary Library manager packages
1. Blynk (by Volodymyr Shymanskyy - version 1.3.2)
1. Create a new Template (ESP32 hardware and connection type WiFi)
2. Copy the Auth codes of Blynk and paste in the HomeX.ino file
3. Setup the Datastreams
To toggle between Auto (0) and Manual (1) - Virtual pin V3
To toggle LED OFF(0) and ON(1) when in Manual mode - Virtual pin V4
To control the brightness of LED when in manual mode - Virtual pin V5
4. Map the datastreams pin to the Switch and Slider
Switch 1 - Virtual pin V3
Switch 2 - Virtual pin V4
Slider - Virtual pin V5
5. Save the Dashboards
1. Create a new google sheet online
2. Add this code in Extensions -> App Scripts
function doPost(e) {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var data = JSON.parse(e.postData.contents);
// Columns: Time | Mode | LDR | PIR | LED
sheet.appendRow([new Date(), data.mode, data.ldr, data.pir, data.led]);
return ContentService.createTextOutput("OK");
}3. Click new deployment
Select Execute as - your mail ID
Who has access - Anyone
4. Authorise the access so ESP32 can send the data to spreadsheet
Set this variable to true if you want Neural Network to control the LED
bool deep_learning_mode = true;
(1st collect the data to train the Neural Network)
if not set it to false it will work on Conditonal based
Creating the virtual environment
python -m venv .venv
Activating the virtual environment
.\.venv\Scripts\activate
Install the required packages
pip install -r requirements.txt
1. Collect the data then download that sheet as csv and store inside data folder
[OR]
Run the synthetic_data.py to create synthetic data to train
2. Run the model_train.py it will train a simple Neural Network
3. The weights are saved in HomeX folder inside src folder so those can be used for Inference
HomeX - Wokwi
Baud: 115200
Serial monitor input:
5 -> Switch between Auto and Manual mode
(Manual model)
0 -> Switch off LED
1 -> Switch on LED
Relay working:
LDR
Case 1: If LDR sensor doesnt detects Light then Relay will be OFF
Case 2: If LDR sensor detects the light then
├── Subcase 1: If PIR module detects motion (Infra red) then the Relay will be ON
├── Subcase 2: If PIR module detects no motion then the Relay will be OFF
Serial monitor output:
AUTO: No Motion or Light present → Relay OFF
Relay -> OFF
AUTO: No Motion or Light present → Relay OFF
Relay -> ON
AUTO: No Motion or Light present → Relay OFF
Relay -> OFF
Switched to MANUAL Mode (use 0=OFF, 1=ON)
Relay -> ON
Manual: Relay ON
Relay -> ON
Manual: Relay ON
Connect the components as follows:
| ESP32 Pin | Component Pin | Component | Notes |
|---|---|---|---|
5V |
VCC |
Relay Module Power | Relay requires 5V supply. |
GND |
GND |
Relay Ground | Common ground with ESP32. |
GPIO4 |
IN |
Relay Control | Drives relay (HIGH = ON). |
NIL |
COM |
Relay Common | Connect external +5V supply. |
NIL |
NO |
Relay Normally Open | Goes to LED Anode via resistor. |
NIL |
GND |
LED Cathode | Connect to ESP32 GND. |
3V3 |
+ |
PIR Power | PIR runs fine at 3.3V in Wokwi. |
GND |
- |
PIR Ground | Common ground. |
GPIO14 |
D |
PIR Output | Goes HIGH when motion detected. |
3V3 |
VCC/+ |
LDR Module Power | Power for LDR sensor. |
GND |
GND/- |
LDR Module Ground | Common ground. |
GPIO34 |
DO |
LDR Digital Output | LOW = Dark, HIGH = Light. |
Wokwi for individual components
For HomeX project Hardware check out the Testing folder (Testing.md) for connections
Note - Simulated via Serial Monitor due to WiFi limitations in simulation.
USE SERIAL MONITOR
Baud: 115200
Commands:
0 → LED OFF
1 → LED ON
Connect the components as follows:
| ESP32 Pin | Relay Pin | Component | Notes |
|---|---|---|---|
5V |
VCC |
Relay Power | Must match relay voltage (5V). |
GND |
GND |
Relay Ground | Common ground for stability. |
GPIO4 |
IN |
Relay Control | Active HIGH (HIGH = ON). |
NIL |
COM |
Power Source (+5V) |
Load power (e.g., external 5V). |
NIL |
NO |
Resistor → LED (+) |
Connects to LED anode when triggered. |
NIL |
NIL |
LED (-) → GND |
Cathode to ground. |
Baud: 115200
Serial monitor output:
PIR Motion Sensor Test
2s: Motion Detected!
20s: No Motion
22s: Motion Detected!
30s: No Motion
Simulating the motion in Wokwi using the PIR module simulate button
Connect the components as follows:
| ESP32 Pin | PIR Pin | Component | Notes |
|---|---|---|---|
3V3 |
+ |
PIR Power | Use 3.3V (stable for PIR in Wokwi). |
GND |
- |
PIR Ground | Common ground (ESP32 + PIR + LED). |
GPIO14 |
D |
PIR Output | Gives HIGH on motion, LOW when idle. |
GPIO2 |
NIL |
Resistor → LED (+) |
220Ω resistor between GPIO2 & LED (+). |
GND |
NIL |
LED (-) |
Direct to ESP32 ground. |
Baud: 115200
Serial monitor output:
LDR Light Sensor Test
Darkness detected → LED ON
Light detected → LED OF
Simulating the light in Wokwi using the LDR module slider
(There is an issue in wokwi so had to put the NOT gate to invert the behaviour of LED)
Connect the components as follows:
| ESP32 Pin | LDR Module Pin | Component | Notes |
|---|---|---|---|
3V3 |
VCC |
LDR Module Power | Power the LDR module at 3.3V. |
GND |
GND |
LDR Module Ground | Common ground with ESP32 & LED. |
GPIO34 |
DO |
LDR Digital Output | HIGH/LOW based on light vs dark. |
GPIO2 |
NIL |
Resistor → LED (+) |
220Ω resistor between GPIO2 & LED (+). |
GND |
NIL |
LED (-) |
Connect directly to ESP32 GND. |
Testing codes for the components
Server running on Port 80
Link - Displayed in serial monitor open that on other device (make sure they are connected to same WiFi)
ledPin = 2 (Controlling BuiltIn LED)
Baud: 115200
Serial monitor output:
12:08:27.566 -> WiFi connected.
12:08:27.566 -> IP address:
12:08:27.614 -> 10.222.94.154
12:08:46.061 -> New Client.
12:08:46.061 -> GET / HTTP/1.1
12:08:46.061 -> Host: 10.222.94.154
12:08:46.093 -> Connection: keep-alive
12:08:46.093 -> Upgrade-Insecure-Requests: 1
12:08:46.093 -> User-Agent: Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Mobile Safari/537.36
12:08:46.093 -> Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8
12:08:46.093 -> Sec-GPC: 1
12:08:46.093 -> Accept-Language: en-US,en;q=0.5
12:08:46.093 -> Accept-Encoding: gzip, deflate
| LDR Sensor (Module) | ||
|---|---|---|
| LDR Pin | Connects to ESP32 | Description |
| VCC | 3V3 | Power for the sensor |
| GND | GND | Common ground |
| AO | D34 | Analog output (reads light intensity) |
| DO | (optional, not needed) | Digital output (threshold-based) |
| Note: ESP32 analog pins: 32–39. Here, we use D34 (input-only pin, perfect for sensors). | ||
| External LED | ||
| LED Pin | Connects to ESP32 | Description |
| Anode (+) | D25 | GPIO for LED control |
| Cathode (-) | GND (via 220Ω resistor) | Limits current |
| PIR Sensor (Module) | ||
|---|---|---|
| PIR Pin | Connects to ESP32 | Description |
| VCC | VIN | Power for the sensor (5V from ESP32 VIN pin) |
| GND | GND | Common ground connection |
| OUT | D32 | Digital output (HIGH when motion detected) |
| Note: Allow the PIR sensor to stabilize for about 30–60 seconds after powering up. | ||
| External LED | ||
| LED Pin | Connects to ESP32 | Description |
| Anode (+) | D25 | GPIO for LED control |
| Cathode (-) | GND (via 220Ω resistor) | Limits current to protect LED |