How to Build a Voice‑Controlled Smart Light Switch with ESP32 – A Complete DIY Guide
Ever walked into a dark room, fumbled for the switch, and thought “If only I could just say ‘lights on’ and be done”? That moment is the spark behind every smart‑home project I tackle at Smart Home Harmony. With a cheap ESP32 and a bit of code, you can turn that wish into a daily reality – and you’ll learn a lot about voice assistants while you’re at it.
What You’ll Need
The hardware
- ESP32 development board – the workhorse that talks Wi‑Fi and Bluetooth.
- Low‑voltage relay module (5 V) – lets the ESP32 safely switch the mains line.
- Momentary push button – for manual override and testing.
- Power supply – 5 V 2 A wall wart or a USB‑C charger.
- Enclosure – a small project box or a 3‑D printed case.
- Wires, solder, heat‑shrink – basic prototyping gear.
- A smart plug or a lamp – to test the switch before you replace a wall plate.
The software
- Arduino IDE – free, works on Windows, macOS, Linux.
- ESP32 board package – add via the Boards Manager.
- Google Assistant SDK (or Alexa Skill) – we’ll use the free IFTTT webhook route for simplicity.
- IFTTT account – create an applet that turns a webhook into a “turn on/off” command.
Why ESP32?
The ESP32 packs Wi‑Fi, Bluetooth, and plenty of GPIO pins in a tiny, cheap chip. It can run the same code that powers commercial smart switches, but you keep full control over privacy and features. Plus, it’s a great platform to learn about MQTT, OTA updates, and low‑power modes – all things that make a smart home feel smooth.
Wiring the Switch Safely
Safety first: If you’re not comfortable working with mains voltage, stop here and use a pre‑made smart plug. The relay isolates the high voltage from the ESP32, but a mistake can still be dangerous.
- Power the ESP32 – connect the 5 V supply to the board’s VIN pin and GND to GND.
- Connect the relay – wire the relay’s VCC to 5 V, GND to GND, and IN to a free GPIO (we’ll use GPIO 23). The relay’s COM (common) goes to the live wire of your lamp, and the NO (normally open) goes to the lamp’s hot lead. When the relay is energized, the circuit closes and the lamp lights.
- Add a button – solder a momentary push button between another GPIO (GPIO 22) and GND. This gives you a manual “toggle” while you’re testing.
- Secure everything – use heat‑shrink on exposed wires, mount the relay and ESP32 inside the enclosure, and keep the mains wires away from the low‑voltage side.
Flashing the Firmware
Open the Arduino IDE, install the ESP32 board URL (https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json) if you haven’t already, then select “ESP32 Dev Module”.
#include <WiFi.h>
#include <HTTPClient.h>
const char* ssid = "YOUR_WIFI_SSID";
const char* password = "YOUR_WIFI_PASSWORD";
const int relayPin = 23;
const int buttonPin = 22;
bool lightState = false;
unsigned long lastDebounce = 0;
void setup() {
pinMode(relayPin, OUTPUT);
pinMode(buttonPin, INPUT_PULLUP);
digitalWrite(relayPin, LOW); // start off
Serial.begin(115200);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nWiFi connected");
}
void loop() {
// Manual button handling
if (digitalRead(buttonPin) == LOW && millis() - lastDebounce > 200) {
lightState = !lightState;
digitalWrite(relayPin, lightState ? HIGH : LOW);
Serial.println(lightState ? "Manual ON" : "Manual OFF");
lastDebounce = millis();
}
// Check for IFTTT webhook
if (WiFi.status() == WL_CONNECTED) {
HTTPClient http;
http.begin("http://maker.ifttt.com/trigger/smart_light/with/key/YOUR_IFTTT_KEY");
int httpCode = http.GET();
if (httpCode == 200) {
// IFTTT sends "on" or "off" in the body
String payload = http.getString();
if (payload.indexOf("on") >= 0) {
lightState = true;
} else if (payload.indexOf("off") >= 0) {
lightState = false;
}
digitalWrite(relayPin, lightState ? HIGH : LOW);
}
http.end();
}
delay(1000);
}
A few notes:
- GPIO 23 drives the relay. HIGH closes the relay, turning the light on.
- GPIO 22 reads the button with the internal pull‑up resistor, so you don’t need an extra resistor.
- The code polls an IFTTT webhook once per second. In a production build you’d replace this with MQTT or a persistent WebSocket, but the webhook keeps the setup simple for a first build.
Hooking Up Voice Control
Using IFTTT with Google Assistant
- Create a new applet – “If Google Assistant says ‘Turn on the bedroom light’ then Webhooks → Make a web request”.
- Set the URL to
http://YOUR_ESP32_IP/turn/on(you’ll add a tiny web server later) or keep the generic IFTTT URL we used in the sketch. - Choose POST and leave the body empty.
- Repeat for the “turn off” command.
If you prefer Alexa, the steps are the same – just use the Alexa skill “Smart Home” and point it at the same webhook.
Adding a Tiny Web Server (Optional)
If you want the ESP32 to listen directly instead of polling IFTTT, add the ESPAsyncWebServer library and replace the polling block with:
#include <ESPAsyncWebServer.h>
AsyncWebServer server(80);
void setup() {
// ... previous setup ...
server.on("/turn/on", HTTP_GET, [](AsyncWebServerRequest *request){
lightState = true;
digitalWrite(relayPin, HIGH);
request->send(200, "text/plain", "ON");
});
server.on("/turn/off", HTTP_GET, [](AsyncWebServerRequest *request){
lightState = false;
digitalWrite(relayPin, LOW);
request->send(200, "text/plain", "OFF");
});
server.begin();
}
Now your voice command can hit the ESP32 directly, cutting latency to a few hundred milliseconds.
Testing and Fine‑Tuning
- Power up the ESP32 and watch the Serial Monitor. You should see “WiFi connected”.
- Press the button – the lamp should toggle. If not, double‑check the relay wiring and that the relay’s coil is getting 5 V.
- Speak the phrase you set in IFTTT. The lamp should respond. If it’s slow, consider moving from polling to the web server method.
- Mount the enclosure – drill a hole for the button if you want a wall‑mounted version, or keep it on a desk for a portable demo.
A Little Story from My Garage
When I first tried this project, I used a cheap relay that clicked loudly enough to wake the cat. I ended up adding a small piece of foam inside the box to muffle the sound. The cat, however, seemed more interested in the blinking LED on the ESP32 than the light itself. After a few weeks of “cat‑controlled lighting” I swapped the relay for a silent solid‑state version. The lesson? Small details like noise and heat can affect the user experience just as much as the code.
Next Steps
- Add OTA updates so you can push new features without opening the box.
- Integrate MQTT for a more robust home‑automation backbone (Home Assistant loves it).
- Add dimming with a MOSFET and PWM if you want more than just on/off.
Building a voice‑controlled switch with an ESP32 is a great entry point into the world of DIY smart homes. You get to choose the hardware, write the code, and keep your data private. Plus, you’ll have a brag‑worthy project to show off at the next dinner party – “Oh, that light? I made it talk to me.”
- → How to Build a Voice‑Controlled Smart Light Switch with Raspberry Pi for Under $30 @techdiyhub
- → How to Build a Raspberry Pi-Powered Smart Home Hub from Scratch @techcraftinsights
- → Build a Wi‑Fi‑Enabled 7‑Segment Clock Using ESP32 @segmentlight
- → How to Build a Smart Home Hub with a Raspberry Pi for Under $50 @techandtinker
- → Step-by-Step Guide: Build a Raspberry Pi Smart Light Switch for Under $30 @techandtinker