Step-by-Step Guide to Building a Home Energy Monitoring System with ESP32
Ever wondered exactly how much power your coffee maker is sucking while you’re still half asleep? I did, and the answer was a shocking 1.2 kWh a month—enough to power a small LED strip for weeks. That little surprise pushed me to build a simple, cheap energy monitor that lives on my Wi‑Fi and sends data straight to my phone. If you’ve ever wanted to see the real cost of that night‑time TV binge, this guide is for you.
What You Need
Before we dive in, gather these items. All of them are easy to find on a hobbyist site or at your local electronics store.
- ESP32 development board – the brain of the project. It has Wi‑Fi, Bluetooth, and plenty of GPIO pins.
- Current transformer (CT) sensor – a small clamp that measures AC current without cutting any wires. A 100 A/30 mA model works well for most home circuits.
- Burden resistor – typically 10 Ω, 0.5 W, placed across the CT’s output to turn the tiny current into a readable voltage.
- Voltage divider – two resistors (10 kΩ and 1 kΩ) to step down the 120 V/230 V line to a safe 3.3 V range for the ESP32’s ADC.
- Breadboard and jumper wires – for quick prototyping.
- Optional: OLED display – a 0.96‑inch I2C screen to see numbers at a glance.
- Power supply – a 5 V USB charger or a small 5 V wall wart.
- Enclosure – a plastic project box to keep everything tidy and safe.
Understanding the Basics
ESP32 in a nutshell
The ESP32 is a tiny computer with built‑in Wi‑Fi. It runs Arduino code, MicroPython, or ESP‑IDF. For this project we’ll use the Arduino IDE because it’s the most beginner‑friendly.
How a CT sensor works
A CT sensor is a donut‑shaped coil that you slip around a live wire. The current flowing through the wire creates a magnetic field, which induces a tiny current in the CT’s secondary winding. That secondary current is proportional to the line current, but it’s only a few milliamps—hence the need for a burden resistor to turn it into a voltage we can read.
From voltage to power
Power (in watts) is simply voltage times current (P = V × I). The ESP32 will read the voltage across the burden resistor (which tells us current) and the scaled line voltage from the divider. Multiplying those two gives instantaneous power. By averaging over time we get energy in kilowatt‑hours (kWh).
Wiring the Sensors
1. Hook up the CT sensor
- Clip the CT around the live (hot) wire of the circuit you want to monitor. Never clip it around both live and neutral; the sensor will read zero.
- Solder the CT’s two leads to the burden resistor. Connect one lead to one side of the resistor, the other lead to the opposite side.
- Take the two points across the burden resistor and wire them to the ESP32’s ADC pin (e.g., GPIO34) and GND respectively.
2. Build the voltage divider
- Connect the 10 kΩ resistor between the line (L) and a node called V_DIV.
- Connect the 1 kΩ resistor between V_DIV and neutral (N).
- Wire V_DIV to another ADC pin (e.g., GPIO35) and GND to the ESP32 ground.
Safety note: The divider only sees a fraction of the line voltage, but you are still working with mains. Double‑check connections, use insulated tools, and consider adding a small fuse.
3. Add the OLED (optional)
Hook the OLED’s SDA to GPIO21 and SCL to GPIO22. Power it from 3.3 V and GND. The screen will show real‑time watts and kWh.
Programming the ESP32
Install the Arduino libraries
- Open the Arduino IDE, go to Boards Manager, and install “ESP32 by Espressif Systems.”
- Add the Adafruit SSD1306 and Adafruit GFX libraries if you’re using the OLED.
- Install PubSubClient for MQTT (we’ll use it to push data to a broker).
Sketch outline
#include <WiFi.h>
#include <PubSubClient.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
// Wi‑Fi credentials
const char* ssid = "YOUR_SSID";
const char* password = "YOUR_PASS";
// MQTT broker
const char* mqtt_server = "broker.hivemq.com";
WiFiClient espClient;
PubSubClient client(espClient);
Adafruit_SSD1306 display(128, 64, &Wire, -1);
// Pin definitions
const int ctPin = 34; // ADC1_6
const int voltPin = 35; // ADC1_7
// Calibration constants
const float CT_RATIO = 100.0; // 100 A primary -> 30 mA secondary
const float BURDEN = 10.0; // Ω
const float VOLT_DIV = 0.0909; // (1k / (10k+1k))
float readCurrent() {
int raw = analogRead(ctPin);
float voltage = (raw / 4095.0) * 3.3; // ESP32 ADC is 12‑bit, 3.3 V ref
float secondary = voltage / BURDEN; // I = V / R
float primary = secondary * CT_RATIO; // Scale back to line current
return primary; // Amps
}
float readVoltage() {
int raw = analogRead(voltPin);
float voltage = (raw / 4095.0) * 3.3;
return voltage / VOLT_DIV; // Scale up to line voltage
}
void setup() {
Serial.begin(115200);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) delay(500);
client.setServer(mqtt_server, 1883);
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.clearDisplay();
}
void loop() {
if (!client.connected()) {
while (!client.connect("esp32_energy_monitor")) delay(500);
}
client.loop();
float I = readCurrent(); // Amps
float V = readVoltage(); // Volts
float P = I * V; // Watts
static float energy = 0.0;
static unsigned long last = millis();
unsigned long now = millis();
float dt = (now - last) / 3600000.0; // hours
energy += P * dt / 1000.0; // kWh
last = now;
// Publish to MQTT
char payload[64];
snprintf(payload, sizeof(payload), "{\"watts\":%.1f,\"kwh\":%.3f}", P, energy);
client.publish("home/energy", payload);
// Show on OLED
display.clearDisplay();
display.setCursor(0,0);
display.setTextSize(1);
display.print("Power: ");
display.print(P,1);
display.println(" W");
display.print("Energy: ");
display.print(energy,3);
display.println(" kWh");
display.display();
delay(2000); // update every 2 seconds
}
Key points in the code
- ADC scaling – The ESP32’s analog‑to‑digital converter (ADC) reads 0‑3.3 V over 4095 steps. We convert that back to voltage.
- Calibration – Adjust
CT_RATIO,BURDEN, andVOLT_DIVif you use different parts. A quick test with a known load (like a 60 W bulb) will let you fine‑tune. - Energy accumulation – We integrate power over time to get kWh. The
dtvariable converts milliseconds to hours.
Putting It All Together
- Test on a low‑risk circuit – Start with a lamp or a phone charger. Clip the CT, power the ESP32, and watch the OLED. You should see a few watts when the lamp is on, near zero when it’s off.
- Secure the wiring – Once you’re confident, solder the connections onto a perf board or a small PCB. Use heat‑shrink tubing on the CT leads.
- Mount in an enclosure – Drill a small hole for the CT’s cable to pass through. Keep the ESP32 and OLED inside, away from any metal that could short the board.
- Connect to your home network – The ESP32 will automatically reconnect after power loss. Your MQTT broker can be a cloud service or a Raspberry Pi running Mosquitto.
- Visualize the data – Use Home Assistant, Node‑RED, or a simple web dashboard to plot watts and kWh over days. Seeing a spike when the dryer runs is oddly satisfying.
Next Steps and Tweaks
- Add multiple CTs – The ESP32 has several ADC pins, so you can monitor a few circuits at once (kitchen, HVAC, etc.).
- Battery backup – A small Li‑Po cell and a charging circuit let the monitor stay alive during outages, so you never lose a data point.
- Alerting – Set up an MQTT trigger that sends a push notification if power exceeds a threshold (great for catching a stuck heater).
- Calibration wizard – Write a small routine that asks you to plug in a known load and then auto‑adjusts the constants. Saves a lot of trial‑and‑error.
Building this monitor reminded me of the first time I tried to measure my fridge’s draw with a multimeter. I ended up with a blown fuse and a very loud “ding” from the kitchen. The ESP32 approach is far safer—no direct contact with mains, just a clamp and a few resistors. Plus, the data lives in the cloud, so you can finally answer the age‑old question: “Why is my electric bill higher this month?” without guessing.
Happy hacking, and may your watts be low and your insights high.
- → Designing Energy‑Efficient LED Segment Displays for Portable Projects @segmentlight
- → DIY Guide: Build a Reliable Temperature Sensor for Your Workshop @thermotechinsights
- → Step-by-step guide to building a 4-bit binary counter with basic ICs @logiclab
- → How to Choose the Right IDC Terminal for High-Current DIY Projects @idctermlog
- → Choosing the Right Ground Terminal Block for Reliable Electrical Wiring @groundcircuit