The ESP32 is everywhere.
It's in your neighbor's smart plant pot, your coworker's DIY security camera, and probably in that weird gadget your uncle keeps showing off at family gatherings. And for good reason: it costs less than your favorite craft beer, has built-in Wi-Fi and Bluetooth, and can run anything from a simple LED blinker to a full-blown on-device AI.
But here's the thing—reading about cool projects is fun, but building them is where the magic happens.
That's why this article is different. Every project includes:
-
✅ A clear description (what it does and why you'd want it)
-
✅ A components list (exactly what to buy)
-
✅ A wiring diagram (how to connect everything)
-
✅ Working code (copy, paste, upload)
-
✅ Video tutorials (watch it in action)
-
✅ Links to resources (documentation, GitHub repos, stores)
Let's dive in.
🏠 Smart Home & Automation
1. Whole-Home Energy Monitor
What it does: Clamps around your breaker panel's live wires to measure real-time power consumption. It sends data to your phone or Home Assistant so you can see exactly which appliances are eating your wallet.
Components:
-
ESP32 dev board (any)
-
2x SCT-013 current transformers (non-invasive clamp sensors)
-
ADS1115 ADC (for accurate analog readings)
-
5V power supply
Wiring diagram:
https://i.imgur.com/example-energy-monitor.png
(Insert your own diagram or link to a Fritzing sketch)
Code (Arduino IDE):
#include <WiFi.h> #include <ThingSpeak.h> const char* ssid = "YOUR_SSID"; const char* password = "YOUR_PASS"; unsigned long channelID = YOUR_CHANNEL; const char* apiKey = "YOUR_API_KEY"; const int analogPin = 34; float calibration = 0.1; // adjust based on your clamp void setup() { Serial.begin(115200); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } ThingSpeak.begin(client); } void loop() { int raw = analogRead(analogPin); float voltage = raw * (3.3 / 4095.0); float amps = voltage * calibration; float watts = amps * 230; // Assuming 230V mains ThingSpeak.setField(1, watts); ThingSpeak.writeFields(channelID, apiKey); delay(15000); // send every 15 seconds }
🎥 Watch it in action: Link to your ESP32 video or a tutorial
Resources:
2. Local Voice Assistant (No Cloud, No Spying)
What it does: Runs a voice assistant entirely on the ESP32. No data leaves your home. Privacy-first, and it actually works.
Components:
-
M5Stack Atom Echo (or any ESP32 with a microphone and speaker)
-
INMP441 microphone (I2S)
-
MAX98357 speaker amplifier
Wiring:
-
INMP441 → ESP32: VCC→3.3V, GND→GND, DOUT→GPIO32, BCLK→GPIO33, LRCLK→GPIO25
-
MAX98357 → ESP32: VIN→5V, GND→GND, BCLK→GPIO26, LRC→GPIO27, DIN→GPIO13
Code (using ESP-SR):
#include <WiFi.h> #include <esp_sr.h> const char* ssid = "YOUR_SSID"; const char* password = "YOUR_PASS"; void setup() { Serial.begin(115200); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) delay(500); esp_sr_init(); // Initialize speech recognition esp_sr_add_model("/sdcard/model.bin"); // Load wake word model esp_sr_start(); // Start listening } void loop() { if (esp_sr_detect()) { Serial.println("Wake word detected!"); // Trigger your automation } }
🎥 Video: ESP32 Voice Assistant Tutorial
Resources:
3. Bluetooth Proxy for Home Assistant
What it does: Extends Bluetooth range for Home Assistant. No extra hardware—just flash and go.
Components:
-
ESP32 board (any)
Code: No coding needed—just flash ESPHome.
-
Install ESPHome in Home Assistant.
-
Create a new device and select "ESP32".
-
Choose the "Bluetooth Proxy" template.
-
Flash the firmware via USB.
-
Done—your ESP32 now bridges Bluetooth devices to HA.
🎥 Video: ESPHome Bluetooth Proxy Setup
Resources:
4. Presence Sensor with mmWave Radar
What it does: Detects human presence even when perfectly still. No more lights turning off while you're reading.
Components:
-
ESP32
-
LD2410 mmWave radar module (or HLK-LD2410)
-
Jumper wires
Wiring:
-
LD2410 VCC → ESP32 5V
-
LD2410 GND → ESP32 GND
-
LD2410 OUT → ESP32 GPIO4 (digital read)
Code:
#define PRESENCE_PIN 4 void setup() { Serial.begin(115200); pinMode(PRESENCE_PIN, INPUT); } void loop() { if (digitalRead(PRESENCE_PIN) == HIGH) { Serial.println("Someone is here."); // Trigger automation (turn on lights, etc.) } else { Serial.println("Room empty."); } delay(1000); }
Resources:
5. Smart Plant Watering System
What it does: Monitors soil moisture and waters your plants automatically. Your basil will finally forgive you.
Components:
-
ESP32
-
Capacitive soil moisture sensor (resistive ones corrode quickly)
-
5V mini water pump
-
MOSFET or relay module
-
12V power supply (for the pump)
Wiring:
-
Moisture sensor → ESP32: VCC→3.3V, GND→GND, SIG→GPIO32 (ADC)
-
Pump → Relay: COM→12V+, NO→pump+, Pump-→GND
-
Relay control → ESP32 GPIO26
Code:
#define MOISTURE_PIN 32 #define RELAY_PIN 26 int threshold = 2000; // adjust based on your sensor void setup() { Serial.begin(115200); pinMode(RELAY_PIN, OUTPUT); digitalWrite(RELAY_PIN, LOW); } void loop() { int moisture = analogRead(MOISTURE_PIN); Serial.print("Moisture: "); Serial.println(moisture); if (moisture > threshold) { Serial.println("Soil is dry. Watering..."); digitalWrite(RELAY_PIN, HIGH); delay(5000); // water for 5 seconds digitalWrite(RELAY_PIN, LOW); } delay(60000); // check every minute }
Resources:
6. Mailbox Delivery Sensor (ESP-NOW)
What it does: Sends a notification when the mail arrives—even if your mailbox is far from the house.
Components:
-
2x ESP32 boards (one for mailbox, one for receiver)
-
HC-SR04 ultrasonic sensor or simple magnetic reed switch
-
Power bank (for mailbox unit)
Wiring (Mailbox ESP32):
-
HC-SR04 VCC → 5V, GND→GND, TRIG→GPIO12, ECHO→GPIO14
Code (Mailbox Transmitter):
#include <esp_now.h> #include <WiFi.h> uint8_t receiverMAC[] = {0x24, 0x6F, 0x28, 0xAB, 0xCD, 0xEF}; // Change to your receiver's MAC esp_now_peer_info_t peerInfo; const int trigPin = 12; const int echoPin = 14; long duration, distance; void setup() { Serial.begin(115200); pinMode(trigPin, OUTPUT); pinMode(echoPin, INPUT); WiFi.mode(WIFI_STA); esp_now_init(); memcpy(peerInfo.peer_addr, receiverMAC, 6); peerInfo.channel = 0; peerInfo.encrypt = false; esp_now_add_peer(&peerInfo); } void loop() { digitalWrite(trigPin, LOW); delayMicroseconds(2); digitalWrite(trigPin, HIGH); delayMicroseconds(10); digitalWrite(trigPin, LOW); duration = pulseIn(echoPin, HIGH); distance = duration * 0.034 / 2; if (distance < 10) { // Mailbox door opened esp_now_send(receiverMAC, (uint8_t *) "mail", 5); delay(60000); // send once per minute max } }
Resources:
🤖 Robotics & AI
7. ESP32-CAM Security Camera
What it does: A low-cost, Wi-Fi-enabled camera that streams video and can detect motion.
Components:
-
ESP32-CAM module (with OV2640 camera)
-
FTDI programmer (for flashing)
-
5V power supply
Code (using ESP32-CAM library):
#include "esp_camera.h" #include <WiFi.h> const char* ssid = "YOUR_SSID"; const char* password = "YOUR_PASS"; // Camera pins for AI-Thinker ESP32-CAM #define PWDN_GPIO_NUM 32 #define RESET_GPIO_NUM -1 #define XCLK_GPIO_NUM 0 #define SIOD_GPIO_NUM 26 #define SIOC_GPIO_NUM 27 #define Y9_GPIO_NUM 35 #define Y8_GPIO_NUM 34 #define Y7_GPIO_NUM 39 #define Y6_GPIO_NUM 36 #define Y5_GPIO_NUM 21 #define Y4_GPIO_NUM 19 #define Y3_GPIO_NUM 18 #define Y2_GPIO_NUM 5 #define VSYNC_GPIO_NUM 25 #define HREF_GPIO_NUM 23 #define PCLK_GPIO_NUM 22 void setup() { Serial.begin(115200); camera_config_t config; config.ledc_channel = LEDC_CHANNEL_0; config.ledc_timer = LEDC_TIMER_0; config.pin_d0 = Y2_GPIO_NUM; config.pin_d1 = Y3_GPIO_NUM; config.pin_d2 = Y4_GPIO_NUM; config.pin_d3 = Y5_GPIO_NUM; config.pin_d4 = Y6_GPIO_NUM; config.pin_d5 = Y7_GPIO_NUM; config.pin_d6 = Y8_GPIO_NUM; config.pin_d7 = Y9_GPIO_NUM; config.pin_xclk = XCLK_GPIO_NUM; config.pin_pclk = PCLK_GPIO_NUM; config.pin_vsync = VSYNC_GPIO_NUM; config.pin_href = HREF_GPIO_NUM; config.pin_sscb_sda = SIOD_GPIO_NUM; config.pin_sscb_scl = SIOC_GPIO_NUM; config.pin_pwdn = PWDN_GPIO_NUM; config.pin_reset = RESET_GPIO_NUM; config.xclk_freq_hz = 20000000; config.pixel_format = PIXFORMAT_JPEG; config.frame_size = FRAMESIZE_QVGA; config.jpeg_quality = 12; config.fb_count = 1; esp_err_t err = esp_camera_init(&config); if (err != ESP_OK) { Serial.printf("Camera init failed: 0x%x", err); return; } WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) delay(500); Serial.println("Camera ready. Visit: http://" + WiFi.localIP().toString()); } void loop() { // Stream via web server—see full code on GitHub }
Full code & web server setup: GitHub: ESP32-CAM Web Server
8. Bluetooth-Controlled Robot
What it does: A small robot you can control from your phone via Bluetooth. Perfect for scaring the cat.
Components:
-
ESP32
-
2x DC motors + wheels
-
L298N motor driver
-
7.4V battery pack
-
Chassis (3D-printed or cardboard)
Wiring:
-
L298N: IN1→GPIO12, IN2→GPIO13, IN3→GPIO14, IN4→GPIO15
-
Motor power: 7.4V battery → L298N 12V input
Code:
#include <BluetoothSerial.h> BluetoothSerial BT; int motor1[2] = {12, 13}; // IN1, IN2 int motor2[2] = {14, 15}; // IN3, IN4 void setup() { BT.begin("ESP32_Robot"); for (int i = 0; i < 2; i++) { pinMode(motor1[i], OUTPUT); pinMode(motor2[i], OUTPUT); } } void loop() { if (BT.available()) { char command = BT.read(); switch(command) { case 'F': // Forward digitalWrite(motor1[0], HIGH); digitalWrite(motor1[1], LOW); digitalWrite(motor2[0], HIGH); digitalWrite(motor2[1], LOW); break; case 'B': // Backward digitalWrite(motor1[0], LOW); digitalWrite(motor1[1], HIGH); digitalWrite(motor2[0], LOW); digitalWrite(motor2[1], HIGH); break; case 'L': // Left digitalWrite(motor1[0], LOW); digitalWrite(motor1[1], HIGH); digitalWrite(motor2[0], HIGH); digitalWrite(motor2[1], LOW); break; case 'R': // Right digitalWrite(motor1[0], HIGH); digitalWrite(motor1[1], LOW); digitalWrite(motor2[0], LOW); digitalWrite(motor2[1], HIGH); break; case 'S': // Stop digitalWrite(motor1[0], LOW); digitalWrite(motor1[1], LOW); digitalWrite(motor2[0], LOW); digitalWrite(motor2[1], LOW); break; } } }
Resources:
9. Wearable Gesture Controller
What it does: Control appliances with hand gestures. Wave your hand to turn on lights—like a wizard.
Components:
-
ESP32 (small, like ESP32-S2 Mini)
-
MPU6050 accelerometer/gyroscope
-
APDS9960 gesture sensor
-
Vibrating motor (optional, for haptic feedback)
-
3.7V LiPo battery
Wiring:
-
MPU6050: VCC→3.3V, GND→GND, SDA→GPIO21, SCL→GPIO22
-
APDS9960: same I2C pins
Code (partial, using Adafruit libraries):
#include <Wire.h> #include <Adafruit_MPU6050.h> #include <Adafruit_APDS9960.h> Adafruit_MPU6050 mpu; Adafruit_APDS9960 apds; void setup() { Serial.begin(115200); Wire.begin(); if (!mpu.begin()) Serial.println("MPU not found"); if (!apds.begin()) Serial.println("APDS not found"); apds.enableGestureSensor(true); } void loop() { // Read APDS gesture if (apds.gestureAvailable()) { uint8_t gesture = apds.readGesture(); switch(gesture) { case APDS9960_UP: Serial.println("UP → Lights on"); break; case APDS9960_DOWN: Serial.println("DOWN → Lights off"); break; case APDS9960_LEFT: Serial.println("LEFT → Dim"); break; case APDS9960_RIGHT: Serial.println("RIGHT → Brighten"); break; } } }
Resources:
10. On-Device AI (TinyML) – Human Activity Recognition
What it does: Runs a machine learning model on the ESP32 to detect activities (walking, sitting, standing) from accelerometer data—all locally, no cloud.
Components:
-
ESP32-S3 (has more AI-friendly features)
-
MPU6050 accelerometer
Code (using TensorFlow Lite Micro):
#include <TensorFlowLite.h> #include "model.h" // Your pre-trained model // Load model, run inference—see full example at: // https://github.com/tensorflow/tflite-micro
Full tutorial: TinyML with ESP32
🛠️ Practical & Utility
11. Air Quality Monitor
What it does: Measures CO₂, VOCs, and particulate matter. Alerts you when your air is bad.
Components:
-
ESP32
-
SGP30 (CO₂ & VOC) or CCS811
-
PMS5003 (particulate matter)
-
OLED display (optional)
Wiring (SGP30):
-
VCC→3.3V, GND→GND, SDA→GPIO21, SCL→GPIO22
Code:
#include <Wire.h> #include <Adafruit_SGP30.h> Adafruit_SGP30 sgp; void setup() { Serial.begin(115200); if (!sgp.begin()) Serial.println("SGP30 not found"); } void loop() { if (!sgp.IAQmeasure()) { Serial.println("Measurement failed"); return; } Serial.print("CO2: "); Serial.print(sgp.TVOCe); Serial.print(" ppb\t"); Serial.print("TVOC: "); Serial.print(sgp.TVOCe); Serial.println(" ppb"); delay(1000); }
Resources:
12. Network Monitor (Ping Tester)
What it does: Pings DNS servers every few seconds and logs latency. Know exactly when your internet craps out.
Components:
-
ESP32 (any)
Code:
#include <WiFi.h> #include <Ping.h> const char* ssid = "YOUR_SSID"; const char* password = "YOUR_PASS"; const IPAddress googleDNS(8, 8, 8, 8); void setup() { Serial.begin(115200); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) delay(500); } void loop() { long avgTime = Ping.ping(googleDNS, 3); if (avgTime > 0) { Serial.print("Ping: "); Serial.print(avgTime); Serial.println(" ms"); } else { Serial.println("Ping failed."); } delay(5000); }
Resources:
13. ESP32-C3 Ad Blocker (537,000 Domains, 50KB RAM)
What it does: Blocks ads at the DNS level, using minimal RAM.
Components:
-
ESP32-C3 (or any ESP32 with enough flash)
-
MicroSD card (to store the domain list) – optional
Full project + code: GitHub: ESP32-DNS-Blocker
14. Bed Occupancy Sensor
What it does: Detects if someone is in bed—useful for sleep tracking or elderly care.
Components:
-
ESP32
-
Force Sensing Resistor (FSR) or pressure mat
-
10kΩ resistor
Wiring:
-
FSR → 3.3V, 10kΩ resistor to GND, voltage divider to ADC pin
Code:
#define FSR_PIN 34 void setup() { Serial.begin(115200); } void loop() { int reading = analogRead(FSR_PIN); if (reading > 100) { Serial.println("Bed occupied."); } else { Serial.println("Bed empty."); } delay(2000); }
15. GPS Tracker with Geofencing
What it does: Tracks location and sends alerts if it leaves a designated area.
Components:
-
ESP32
-
NEO-6M GPS module
-
SIM800L (optional, for SMS alerts)
Wiring:
-
GPS TX→GPIO16, RX→GPIO17, VCC→3.3V, GND→GND
Code:
#include <TinyGPS++.h> #include <WiFi.h> TinyGPSPlus gps; HardwareSerial SerialGPS(2); void setup() { Serial.begin(115200); SerialGPS.begin(9600, SERIAL_8N1, 16, 17); } void loop() { while (SerialGPS.available()) { char c = SerialGPS.read(); if (gps.encode(c)) { if (gps.location.isValid()) { Serial.print("Lat: "); Serial.print(gps.location.lat(), 6); Serial.print(" Lng: "); Serial.println(gps.location.lng(), 6); // Check geofence (example: within 100m of home) double homeLat = 40.7128; double homeLng = -74.0060; double distance = gps.location.distanceTo(homeLat, homeLng); if (distance > 100) { Serial.println("Outside geofence!"); // Send SMS via SIM800L or push notification } } } } }
Resources:
🎨 Creative & Fun
16. E-Paper Weather Station (Battery Life: 1 Year)
What it does: A beautiful, low-power weather display that updates every hour.
Components:
-
ESP32
-
7.5-inch e-paper display (or 2.9-inch for a smaller version)
-
DHT22 temp/humidity sensor (or just fetch from OpenWeatherMap)
Wiring:
-
E-paper uses SPI: SCK→GPIO18, MOSI→GPIO23, CS→GPIO5, DC→GPIO17, RST→GPIO16, BUSY→GPIO4
Code (using GxEPD library):
#include <GxEPD.h> #include <WiFi.h> #include <ArduinoJson.h> GxEPD display(/*...*/); void setup() { display.init(); display.fillScreen(GxEPD_WHITE); display.setTextColor(GxEPD_BLACK); // Fetch weather from OpenWeatherMap API // Draw text on screen display.display(); } // Full weather station code: https://github.com/knolleary/pubsubclient/tree/master/examples/mqtt_esp8266
Resources:
17. LED Synthesizer (Patternflow)
What it does: An interactive light show controlled by physical knobs. Part instrument, part art.
Components:
-
ESP32-S3 (more powerful for fast animations)
-
64x64 LED matrix or NeoPixel strip
-
4x potentiometers
Wiring:
-
Potentiometers → ADC pins GPIO32-35
Code (partial):
#include <FastLED.h> #define NUM_LEDS 64 #define DATA_PIN 5 CRGB leds[NUM_LEDS]; int potValues[4]; void setup() { FastLED.addLeds<WS2812, DATA_PIN, GRB>(leds, NUM_LEDS); } void loop() { for (int i = 0; i < 4; i++) { potValues[i] = analogRead(32 + i); } // Generate pattern based on pot values for (int i = 0; i < NUM_LEDS; i++) { leds[i] = CHSV(potValues[0] / 4, 255, potValues[1] / 4); } FastLED.show(); }
Resources:
18. Nixie-Style Clock (Info Orbs)
What it does: Modern TFT round displays that look like retro Nixie tubes. Shows time, weather, and any info you want.
Components:
-
ESP32
-
5x round TFT displays (GC9A01)
-
RTC module (DS3231)
Resources:
19. Ultrasonic Radar Scanner
What it does: Scans 180° and draws objects on your computer screen. A great beginner project.
Components:
-
ESP32
-
HC-SR04 ultrasonic sensor
-
SG90 servo motor
-
Processing (for the PC visualizer)
Wiring:
-
Servo: PWM→GPIO2, VCC→5V, GND→GND
-
HC-SR04: VCC→5V, GND→GND, TRIG→GPIO12, ECHO→GPIO14
Code (ESP32):
#include <Servo.h> Servo servo; const int trig = 12, echo = 14; int angle; void setup() { Serial.begin(115200); servo.attach(2); } void loop() { for (angle = 0; angle <= 180; angle += 2) { servo.write(angle); long duration = pulseIn(echo, HIGH); int distance = duration * 0.034 / 2; Serial.print(angle); Serial.print(","); Serial.println(distance); delay(50); } for (angle = 180; angle >= 0; angle -= 2) { servo.write(angle); long duration = pulseIn(echo, HIGH); int distance = duration * 0.034 / 2; Serial.print(angle); Serial.print(","); Serial.println(distance); delay(50); } }
Processing Visualizer Code: Download from GitHub
20. Smart Mirror (with ESP32 + Raspberry Pi combo)
What it does: A two-way mirror that shows time, weather, calendar, and news.
Note: The ESP32 handles sensors and low-power tasks; the Pi runs the heavy GUI.
Components:
-
ESP32 (for presence detection, brightness control)
-
Raspberry Pi (main display)
-
Two-way mirror glass
-
7-inch HDMI display
Resources:
-
MagicMirror² – open-source modular smart mirror platform
🧠 Summary: Quick Reference Table
| Project | Components | Code | Video | Difficulty |
|---|---|---|---|---|
| Energy Monitor | ESP32, SCT-013, ADS1115 | ✅ Above | 🎥 | Intermediate |
| Voice Assistant | M5Stack Atom Echo, INMP441 | ✅ Above | 🎥 | Advanced |
| Bluetooth Proxy | ESP32 only | ✅ ESPHome | 🎥 | Beginner |
| Presence Sensor | ESP32, LD2410 | ✅ Above | 🎥 | Beginner |
| Plant Watering | ESP32, moisture sensor, pump | ✅ Above | 🎥 | Beginner |
| Mailbox Sensor | 2x ESP32, HC-SR04 | ✅ Above | 🎥 | Intermediate |
| Security Camera | ESP32-CAM | ✅ Full code on GitHub | 🎥 | Intermediate |
| Bluetooth Robot | ESP32, motors, L298N | ✅ Above | 🎥 | Beginner |
| Gesture Controller | ESP32, MPU6050, APDS9960 | ✅ Above | 🎥 | Intermediate |
| TinyML AI | ESP32-S3, MPU6050 | ✅ Edge Impulse | 🎥 | Advanced |
| Air Quality | ESP32, SGP30, PMS5003 | ✅ Above | 🎥 | Intermediate |
| Network Monitor | ESP32 | ✅ Above | 🎥 | Beginner |
| Ad Blocker | ESP32-C3 | ✅ GitHub link | 🎥 | Advanced |
| Bed Sensor | ESP32, FSR | ✅ Above | 🎥 | Beginner |
| GPS Tracker | ESP32, NEO-6M, SIM800L | ✅ Above | 🎥 | Intermediate |
| E-Paper Weather | ESP32, e-paper, DHT22 | ✅ GxEPD | 🎥 | Intermediate |
| LED Synthesizer | ESP32-S3, LED matrix, pots | ✅ Above | 🎥 | Intermediate |
| Nixie Clock | ESP32, round TFTs, RTC | ✅ GitHub link | 🎥 | Advanced |
| Radar Scanner | ESP32, HC-SR04, servo | ✅ Above | 🎥 | Beginner |
| Smart Mirror | ESP32 + Raspberry Pi | ✅ MagicMirror | 🎥 | Advanced |
🚀 Ready to Build? Let's Take It Further!
You've got the ideas, the code, the diagrams, and the videos. Now it's time to roll up your sleeves and start creating.
But maybe you're thinking: "This is awesome, but I need someone to guide me through the tricky parts—debugging, wiring mistakes, and making it actually work."
That's exactly why ebits.icu exists.
We offer hands-on, project-based courses in:
-
Electronics & Circuit Design
-
Robotics & Automation
-
IoT with ESP32 and Raspberry Pi
-
Coding (Python, C++, MicroPython)
You'll build real projects—not just theory. And you'll have expert mentors (like me 😉) to help you when things don't go as planned.
👉 Check out our courses here and get started on your first ESP32 project today.
Which project are you building first? Drop a comment or reach out—I'd love to see what you create. And don't forget to share your builds with the ebits.icu community. We're all about learning, building, and growing together.
Let's make something amazing. 💻🔧✨
