BLOG / TUTORIALS / ESP32 WiFi Projects: 7 Practical IoT Bui…
Bài viết Blog

ESP32 WiFi Projects: 7 Practical IoT Builds for Home and Workshop

Viktor Build ~9 min read

Build 7 practical ESP32 WiFi projects for your home and workshop. Wi-Fi relay control, MQTT temperature logging, OTA updates, and more with full wiring and code.

Here is the expert, SEO-optimized blog post in English, formatted in Markdown as requested.

So, you’ve got an ESP32 and a half-formed idea bouncing around your head. You know it can do Wi-Fi, but what does that actually mean for a real project? You want something that works—something you can test, tweak, and wire up inside an hour. This is exactly where ESP32 Wi-Fi projects shine: they bridge that gap between blinking an LED and building something you’d actually use to control your home or log data in your workshop.

In this roundup, we’ll walk through seven practical builds. I’ve already covered a few on the blog—like the ESP8266 relay fan mod—but today we’re leveling up with the dual-core power of the ESP32. We’re talking Wi-Fi-controlled relays, sensor stations, and data logging rigs that you can deploy and forget. Every project here is something I’ve built and tested myself. Let’s get into the list.

Why the ESP32 for Wi-Fi Projects?

Before we dive into the builds, it’s worth understanding why the ESP32 is the first chip I reach for when a project needs Wi-Fi. Unlike its little brother (the ESP8266), the ESP32 packs two CPU cores, Bluetooth (both Classic and BLE), and built-in Wi-Fi with a soft access point mode that’s dead simple to configure.

The killer feature? You don’t need a separate microcontroller to handle the logic. The ESP32 runs both the network stack and your application code on the same chip. For ESP32 Wi-Fi projects, that means you can handle a web server, an MQTT client, and sensor reading loops all at once without dropping packets.

  • Dual-core processor: One core handles Wi-Fi and Bluetooth, the other runs your application code
  • Built-in Wi-Fi: 802.11 b/g/n, 2.4 GHz—works with any home router
  • Peripheral support: 18 ADC channels, 2 DACs, I2C, SPI, UART, and USB-OTG

If you’re newer to the platform, I’d suggest checking out the Arduino tutorial category to get your bearings—but you don’t need to be an expert to follow these builds.

1. Wi-Fi Controlled Relay Switch (Home Automation Starter)

Let’s start with the most requested build: turning a lamp, fan, or water pump on and off from your phone. This is the quintessential entry point for ESP32 Wi-Fi projects because it teaches you web server hosting and GPIO control in one go.

Parts List

Component Quantity Notes
ESP32 Dev Board (e.g., NodeMCU-32S) 1 Any variant with at least 4MB flash
5V Relay Module (1-channel) 1 Use optocoupler-equipped for isolation
Push button (momentary) 1 For local override
10kΩ resistor 1 Pull-down for the button
Jumper wires M-M As needed

Wiring

Connect the relay module's signal pin to GPIO 23 on the ESP32. Wire VCC to 5V and GND to GND. The push button connects between GPIO 22 and 3.3V, with a 10kΩ resistor to GND on that same pin (internal pull-down isn't always reliable, so I add the resistor).

Code Sketch

Here’s a minimal web server sketch. It creates an access point (AP) that lets you toggle the relay from a browser.

#include <WiFi.h>
#include <WebServer.h>

const char* ssid = "ESP32-Relay";
const char* password = "12345678";

WebServer server(80);
const int relayPin = 23;
const int buttonPin = 22;
bool relayState = false;

void handleRoot() {
  String html = "<!DOCTYPE html><html><body>";
  html += "<h1>ESP32 Relay Control</h1>";
  html += "<p>Relay is " + String(relayState ? "ON" : "OFF") + "</p>";
  html += "<a href='/toggle'><button>Toggle Relay</button></a>";
  html += "</body></html>";
  server.send(200, "text/html", html);
}

void handleToggle() {
  relayState = !relayState;
  digitalWrite(relayPin, relayState ? HIGH : LOW);
  server.sendHeader("Location", "/");
  server.send(303);
}

void setup() {
  pinMode(relayPin, OUTPUT);
  digitalWrite(relayPin, LOW);
  pinMode(buttonPin, INPUT_PULLDOWN);
  WiFi.softAP(ssid, password);
  server.on("/", handleRoot);
  server.on("/toggle", handleToggle);
  server.begin();
}

void loop() {
  server.handleClient();
  if (digitalRead(buttonPin) == HIGH) {
    delay(200); // Debounce
    relayState = !relayState;
    digitalWrite(relayPin, relayState ? HIGH : LOW);
  }
}

Deploy it, connect your phone to the ESP32-Relay network, and navigate to 192.168.4.1. The button toggles the relay. This is the same logic I used in my remote control fan mod, just ported to the ESP32.

2. Temperature and Humidity Sensor with MQTT Data Logging

For the workshop, you often want to track ambient conditions—especially if you’re soldering or storing electronics. This build uses the ubiquitous DHT22 sensor and publishes readings to an MQTT broker. From there, you can log them to a database or a dashboard like Home Assistant.

Why MQTT?

MQTT (Message Queuing Telemetry Transport) is a lightweight publish-subscribe protocol made for IoT. It’s far more efficient than HTTP polling. The ESP32 subscribes to topics and publishes data, while your broker (running on a Raspberry Pi or a cloud instance) handles distribution.

Wiring

  • DHT22 VCC: 3.3V
  • DHT22 DATA: GPIO 4 (with a 10kΩ pull-up to 3.3V)
  • DHT22 GND: GND
#include <WiFi.h>
#include <PubSubClient.h>
#include <DHT.h>

#define DHTPIN 4
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);

const char* ssid = "YourSSID";
const char* password = "YourPASS";
const char* mqtt_server = "192.168.1.100";

WiFiClient espClient;
PubSubClient client(espClient);

void reconnect() {
  while (!client.connected()) {
    if (client.connect("ESP32Sensor")) {
      client.publish("workshop/status", "connected");
    }
  }
}

void setup() {
  dht.begin();
  WiFi.begin(ssid, password);
  client.setServer(mqtt_server, 1883);
}

void loop() {
  if (!client.connected()) reconnect();
  client.loop();
  float h = dht.readHumidity();
  float t = dht.readTemperature();
  if (!isnan(h) && !isnan(t)) {
    client.publish("workshop/temperature", String(t).c_str());
    client.publish("workshop/humidity", String(h).c_str());
  }
  delay(5000);
}

Add a small OLED display to show live readings—check my OLED display Arduino guide for wiring, which transfers directly to the ESP32 via I2C pins (SDA: GPIO 21, SCL: GPIO 22).

3. Web-Based Analog Data Logger (Plot Graphs in Real Time)

Sometimes you want to see a waveform—like monitoring a battery discharge curve or a photocell’s response to light. This project streams ADC data to a web page that plots a dynamic line graph using Chart.js.

How It Works

The ESP32 reads a potentiometer on GPIO 36 (ADC1 channel 0, which is 12-bit) and serves a web page that fetches new data via a simple AJAX endpoint (/read). The browser draws the graph.

Code Outline

#include <WiFi.h>
#include <WebServer.h>

WebServer server(80);

String page = "<!DOCTYPE html><html><body><canvas id='chart'></canvas>"
"<script src='https://cdn.jsdelivr.net/npm/chart.js'></script>"
"<script>"
"var ctx=document.getElementById('chart').getContext('2d');"
"var chart=new Chart(ctx,{type:'line',data:{labels:[],datasets:[{data:[]}]}});"
"setInterval(function(){"
"fetch('/read').then(r=>r.text()).then(function(d){"
"chart.data.labels.push(Date.now());"
"chart.data.datasets[0].data.push(parseInt(d));"
"if(chart.data.labels.length>50){chart.data.labels.shift();chart.data.datasets[0].data.shift();}"
"chart.update();})},500);</script></body></html>";

void handleRead() {
  server.send(200, "text/plain", String(analogRead(36)));
}

void setup() {
  WiFi.softAP("Logger");
  server.on("/", [](){ server.send(200, "text/html", page); });
  server.on("/read", handleRead);
  server.begin();
}

void loop() { server.handleClient(); }

This is surprisingly useful for debugging sensors before you wire them into a permanent circuit. You get immediate visual feedback.

4. Over-the-Air (OTA) Firmware Updates

Manually plugging a USB cable to upload code every time you tweak a parameter gets old fast. OTA updates let you push new firmware over Wi-Fi. This is less a standalone project and more an essential pattern for all your ESP32 Wi-Fi projects.

Add the OTA library to any sketch:

#include <ArduinoOTA.h>

void setup() {
  ArduinoOTA.begin();
}

void loop() {
  ArduinoOTA.handle();
  // Your existing loop code
}

After the first upload via USB, subsequent uploads can be done through the Arduino IDE (select “ESP32” as the programmer, connect via IP) or via a web interface. This saved me hours when I was tuning the data logger above.

5. Wi-Fi Garage Door Monitor and Controller

This is a classic maker project. You mount a magnetic reed switch on the door frame and a relay on the garage door opener. The ESP32 reports the door status via a web page and triggers the opener when you press a button.

Safety Note

The ESP32 and relay run on low voltage (5V). Use a second relay module to isolate the 24V or 120V garage opener circuit. Never connect mains directly to a breadboard.

Key Code Logic

bool doorOpen = !digitalRead(reedSwitchPin); // Normally closed when door is shut
server.on("/status", [](){
  server.send(200, "text/plain", doorOpen ? "open" : "closed");
});
server.on("/trigger", [](){
  digitalWrite(relayPin, HIGH);
  delay(300);
  digitalWrite(relayPin, LOW);
  server.send(200, "text/plain", "toggled");
});

The reed switch is wired as a pull-up to GND so it reads LOW when the magnet is near (door closed). Simple and reliable.

6. RSSI-Based Proximity Detection (Workshop Tool Tracker)

For kicks, I built a system that tracks how close my soldering iron station is to the bench. The ESP32 scans for the RSSI (Received Signal Strength Indicator) of a Bluetooth Low Energy beacon or another ESP32 sending BLE advertisements. When the signal drops below a threshold, it triggers a buzzer—reminding me I left the iron on.

How to Get RSSI

#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEScan.h>

const int rssiThreshold = -70; // Approx 2 meters indoors

void setup() {
  BLEDevice::init("");
  pBLEScan = BLEDevice::getScan();
  pBLEScan->setActiveScan(true);
}

void loop() {
  BLEScanResults foundDevices = pBLEScan->start(1);
  int bestRSSI = -100;
  for (int i = 0; i < foundDevices.getCount(); i++) {
    BLEAdvertisedDevice d = foundDevices.getDevice(i);
    if (d.getAddress().toString() == targetAddress) {
      bestRSSI = d.getRSSI();
    }
  }
  if (bestRSSI < rssiThreshold) {
    digitalWrite(buzzerPin, HIGH);
  } else {
    digitalWrite(buzzerPin, LOW);
  }
}

This is a great project to pair with an OLED display to show RSSI values in real time.

7. ESP32 Web Configuration Portal (WiFiManager Integration)

The final project is a meta-build: a web configuration portal that lets you enter Wi-Fi credentials without reflashing the code. This is perfect for devices you gift to friends or deploy in different networks.

Using the WiFiManager library:

#include <WiFiManager.h>
#include <DNSServer.h>

void setup() {
  WiFiManager wm;
  wm.setConfigPortalBlocking(false);
  wm.autoConnect("ESP32-Config");
  // Continue with your sensor/relay code here
}

When the ESP32 boots and can’t connect to a saved network, it launches an AP named “ESP32-Config.” You connect to it, a captive portal pops up, and you enter the Wi-Fi SSID and password. The ESP32 saves them to non-volatile storage and reboots. This makes your ESP32 Wi-Fi projects truly portable.

Conclusion

The ESP32 turns any idea that involves “I wish I could control that from my phone” or “I want to see sensor data logged over time” into a weekend build. Each of these projects is a stepping stone: the relay switch teaches you the HTTP server; the MQTT sensor gives you a logging pipeline; the OTA update makes every future tweak frictionless.

I’ve linked back to several posts that cover the component details in depth—like how to wire up an OLED or read a potentiometer—so you can mix and match. The best part? Once you’ve got the core patterns down (Wi-Fi connection, web server, MQTT, OTA), you can iterate on your own ideas without starting from scratch every time.

The code for all these projects is available on GitHub if you want to grab the full sketches. If you hit a snag, the maker community on Discord is always happy to help debug a wiring issue or a timeout loop.

Now go build something that makes your home or workshop a little smarter.

Tham gia cộng đồng trên Discord

Đặt câu hỏi, chia sẻ dự án và giao lưu với các maker khác.

Tham gia Discord — miễn phí

Bạn thích hướng dẫn này?

Ủng hộ kênh trên Patreon để nhận quyền truy cập sớm và nhiều hơn nữa.

Ủng hộ trên Patreon →