Building a Smart Energy Meter With ESP32 and MQTT Alerts

by ElectroScope Archive in Circuits > Electronics

10 Views, 0 Favorites, 0 Comments

Building a Smart Energy Meter With ESP32 and MQTT Alerts

smart energy meter.jpg

This project monitors your home's electricity usage in real time using an ESP32, PZEM-004T sensor module, and MQTT protocol. The system tracks voltage, current, power consumption, and power factor, displaying everything on a local LCD screen and a web dashboard you can access from anywhere. When voltage spikes or drops abnormally, it sends you an SMS alert automatically.

Supplies

Pzem-Module-with-CT.jpg
  1. ESP32 development board
  2. PZEM-004T module (V4.0 version with external CT)
  3. External current transformer (comes with the PZEM)
  4. 16x2 LCD display
  5. I2C adapter module for the LCD
  6. Breadboard and jumper wires
  7. USB cable for programming
  8. Arduino IDE installed

The PZEM-004T does the heavy lifting here. I tried building this with cheaper sensors first—the ACS712 current sensor and ZMPT101B voltage sensor—but they needed constant calibration and gave noisy readings. The PZEM comes pre-calibrated and handles all the complex AC measurement math internally. It measures voltage from 80-260V AC, current up to 100A, and active power up to 23kW.

Understanding the Current Transformer

Current-Transformer.jpg

The CT sensor looks like a plastic clamp with a cable. You open it up and clip it around your live wire. When AC flows through the wire, it creates a magnetic field. The CT has a coil inside that picks up this field and converts it to a smaller current the PZEM can measure.

Here's the critical part I learned the hard way: only clamp the CT around the live wire. When I first tested this, I clamped it around both live and neutral because that seemed more secure. Got zero current readings. The magnetic fields from the two wires cancel each other out perfectly. Once I moved it to just the live wire, everything worked.

Wiring the System

Circuit-Digaram-of-Energy-Meter.jpg

I built this on a breadboard first to make sure everything worked before making it permanent.

The PZEM connects to the ESP32 through UART serial. PZEM TX goes to ESP32 GPIO 16, PZEM RX goes to GPIO 17. Power and ground connect to the ESP32's 5V and GND pins.

The LCD uses I2C to keep wiring simple. I soldered the I2C adapter to the back of the LCD first. Then SDA connects to GPIO 21, SCL to GPIO 22, plus power and ground.

For mains power, the PZEM has screw terminals. Your load connects in series with the module so all current flows through it. The CT clamps around just the live wire. I started testing with a desk lamp before moving to anything more serious. If you're not comfortable with mains voltage, grab someone who is.

Setting Up Arduino IDE

Before uploading code, install these libraries through the Library Manager:

  1. LiquidCrystal_I2C
  2. PZEM004Tv30
  3. PubSubClient
  4. WiFi (comes with ESP32 board support)

My LCD's I2C address was 0x27. Yours might be 0x3F. If the screen stays blank, run an I2C scanner sketch to find the right address.

The code initializes everything at startup:

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <PZEM004Tv30.h>
#include <WiFi.h>
#include <PubSubClient.h>

LiquidCrystal_I2C lcd(0x27, 16, 2);
HardwareSerial PZEMSerial(2);
PZEM004Tv30 pzem(PZEMSerial, 17, 16);

In the main loop, the ESP32 reads measurements from the PZEM every cycle. These values update constantly as your power usage changes.

float V = pzem.voltage();
float I = pzem.current();
float P = pzem.power();
float E = pzem.energy();
float F = pzem.frequency();
float PF = pzem.pf();

I added voltage monitoring that sends me a text if things get abnormal. The system checks every loop, but only sends one SMS per cooldown period to avoid spam.

if (V > 255) {
if (millis() - lastSMS > smsCooldown) {
sendSMS();
lastSMS = millis();
}
}

The SMS feature uses Circuit Digest Cloud's API. You need an account for the API key and template ID, but the service gives you free messages for IoT projects. The code makes a secure HTTPS request with your alert data formatted as JSON.

Building the Web Dashboard

Dashboard-for-Energy-Monitoring-System.jpg

The dashboard is a single HTML file that connects to an MQTT broker through WebSocket. I chose MQTT over HTTP because it's designed for streaming live sensor data. Way less overhead, lower latency, persistent connection instead of constant polling.

I'm using HiveMQ's free public broker. It's not secure since anyone can access it, but for a home project it works fine. The dashboard subscribes to topics like "unique/energy/voltage" and updates the display whenever new data arrives.

Save the HTML file anywhere on your computer and open it in a browser. You'll see cards showing voltage, current, power, energy, frequency, and power factor. As long as your ESP32 is online and publishing, everything updates automatically.

The dashboard monitors the connection status and shows errors if something breaks. Each data card updates independently, so if one sensor reading fails, the others keep working.

Testing Everything

Real-Time-Setup-of-Energy-Meter.jpg
Real-Time-Data-Displayed-Across-Different-Interfaces.jpg
Message-Feature-in-Energy-Monitoring-System.jpg

When I first powered everything up, the LCD initialized and started cycling through readings. With no load connected, I saw voltage but zero current, which made sense. I plugged in a 60W desk lamp. Current jumped to about 0.25A at 240V. The power reading showed right around 60W.

Here's all three interfaces running simultaneously. The serial monitor, MQTT dashboard, and LCD all show identical live data:

The LCD cycles through each parameter every two seconds so you can see everything without pressing buttons. Voltage stays on screen, then current, then power factor, then frequency, then power consumption. It loops continuously.

To test SMS alerts, I temporarily lowered the voltage threshold in code to something that would definitely trigger. Got a text message within seconds:

When Things Go Wrong

My LCD showed nothing at first. Turned out I had the wrong I2C address. An I2C scanner sketch found it at 0x3F instead of 0x27. Changed one line of code and it worked.

The current reading stuck at zero even with a load running. I'd clamped the CT around both wires. Moved it to just the live wire and current appeared immediately.

The PZEM gave garbage readings initially. I had TX and RX backwards. They cross over between devices, so PZEM TX connects to ESP32 RX, and PZEM RX connects to ESP32 TX.

My ESP32 kept rebooting randomly. Power supply couldn't deliver enough current for both the ESP32 and PZEM. Switched to a better USB adapter and the reboots stopped.

The dashboard wouldn't connect at first. I had the MQTT broker URL wrong in my HTML file. Double-checked it against the ESP32 code and fixed the typo.

Running It Long-Term

I've been monitoring my home office circuit for a few weeks now. My computer setup pulls way more power than I expected when everything runs at once. The monitor, desktop, speakers, and USB hub together hit almost 200W at peak.

The SMS alert caught a voltage drop I wouldn't have noticed otherwise. Turned out to be a loose connection in my breaker panel. Fixed it before it became a real problem.

I'm thinking about adding a relay module so I could cut power remotely if needed. Would make this a complete smart power monitor with control capabilities. Could also log data to a database for long-term tracking, or integrate with Home Assistant.

Most commercial energy monitors lock you into their ecosystem. This system publishes standard MQTT messages that anything can subscribe to. Want to graph the data? Subscribe to the topics. Want to trigger automation based on power usage? Subscribe to the topics. It's completely open.

The PZEM handles the hard part, measuring AC power accurately. The ESP32 just reads values and publishes them. Adding features is straightforward because you're working with simple sensor readings, not reverse-engineering proprietary protocols.

This guide is entirely based on: Smart Energy Meter Using IoT