Are you tired of high electricity bills and wondering where all your energy is going? In this comprehensive guide, I'll show you how to build a professional-grade smart energy monitor using the powerful ESP32 microcontroller and the new Matter protocol. This DIY project costs less than $25 and can help you save up to 30% on your energy bills!
- How to monitor real-time electricity consumption
- Integration with Matter protocol (works with Apple, Google & Alexa)
- Building a web dashboard for remote monitoring
- Advanced automation based on power usage
- Troubleshooting common issues
Why Build Your Own Energy Monitor?
Commercial energy monitors like the Sense or Emporia Vue cost $200-$400. With this DIY approach, you get:
- 💰 Cost-effective: Total build cost under $25
- 🔧 Fully customizable: Add features as needed
- 📱 Smart home integration: Works with Matter, HomeKit, Google Home
- 🔒 Privacy-focused: Your data stays on your network
- 📚 Educational: Learn electronics and programming
Components You'll Need
| Component | Specification | Approx. Price |
|---|---|---|
| ESP32-C6 Dev Board | With Matter support | $6 |
| PZEM-004T Sensor | AC voltage/current/power | $8 |
| 0.96" OLED Display | I2C SSD1306 | $3 |
| 5V Relay Module | For automation | $2 |
| Jumper Wires | Male-Female | $2 |
| Power Supply | 5V 2A USB | $4 |
Understanding the PZEM-004T Energy Sensor
The PZEM-004T is a non-invasive AC energy monitoring module that can measure:
- Voltage: 80-260V AC
- Current: 0-10A (or 0-100A with external CT)
- Power: Real, reactive, and apparent power
- Energy: Cumulative kWh consumption
- Power Factor: Efficiency metric
- Frequency: 45-65 Hz
The sensor communicates via UART (serial) at 9600 baud, making it easy to interface with the ESP32.
Step 1: Wiring the Circuit
Follow this wiring diagram carefully. ⚠️ WARNING: Working with mains voltage is dangerous. Always turn off the circuit breaker before making connections.
Connection Table:
| PZEM-004T Pin | ESP32-C6 Pin | Wire Color |
|---|---|---|
| VCC | 5V | Red |
| GND | GND | Black |
| TX | GPIO4 (RX) | Yellow |
| RX | GPIO5 (TX) | Orange |
OLED Display Connections:
- VCC → 3.3V
- GND → GND
- SCL → GPIO6
- SDA → GPIO7
Relay Module Connections:
- VCC → 5V
- GND → GND
- IN → GPIO8
Step 2: Installing Required Libraries
Open Arduino IDE and install these libraries via Library Manager:
- PZEM-004T-v30: For energy sensor communication
- Adafruit SSD1306: For OLED display
- Adafruit GFX: Graphics library for display
- ArduinoJson: For JSON data handling
- ESP32 Matter: Built-in Matter protocol support
Step 3: The Complete Code
Here's the full Arduino sketch that reads energy data, displays it on the OLED, creates a web server, and integrates with Matter:
#include <PZEM004Tv30.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <WiFi.h>
#include <WebServer.h>
#include <ArduinoJson.h>
#include <Matter.h>
#include <MatterOnOffLight.h>
// WiFi credentials
const char* ssid = "YOUR_WIFI_SSID";
const char* password = "YOUR_WIFI_PASSWORD";
// Pin definitions
#define PZEM_RX 4
#define PZEM_TX 5
#define RELAY_PIN 8
// Create objects
PZEM004Tv30 pzem(Serial1, PZEM_RX, PZEM_TX);
Adafruit_SSD1306 display(128, 64, &Wire, -1);
WebServer server(80);
// Matter device
MatterOnOffLight smartPlug;
// Energy data variables
float voltage = 0;
float current = 0;
float power = 0;
float energy = 0;
float frequency = 0;
float pf = 0;
void setup() {
Serial.begin(115200);
// Initialize relay
pinMode(RELAY_PIN, OUTPUT);
digitalWrite(RELAY_PIN, LOW);
// Initialize OLED
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
for(;;);
}
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
// Connect to WiFi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi...");
}
Serial.println("Connected to WiFi");
Serial.println(WiFi.localIP());
// Initialize Matter
Matter.begin();
smartPlug.begin();
// Setup web server routes
server.on("/", handleRoot);
server.on("/data", handleData);
server.on("/control", handleControl);
server.begin();
Serial.println("HTTP server started");
}
void loop() {
// Read energy data
voltage = pzem.voltage();
current = pzem.current();
power = pzem.power();
energy = pzem.energy();
frequency = pzem.frequency();
pf = pzem.pf();
// Update display
updateDisplay();
// Update Matter device
if (power > 0) {
smartPlug.setOnOff(true);
}
// Handle web server
server.handleClient();
delay(1000);
}
void updateDisplay() {
display.clearDisplay();
display.setCursor(0, 0);
display.println("Energy Monitor");
display.println("----------------");
display.print("V: "); display.print(voltage, 1); display.println("V");
display.print("I: "); display.print(current, 2); display.println("A");
display.print("P: "); display.print(power, 1); display.println("W");
display.print("E: "); display.print(energy, 2); display.println("kWh");
display.display();
}
void handleRoot() {
String html = "<html><head>";
html += "<meta http-equiv='refresh' content='5'>";
html += "<style>body{font-family:Arial;text-align:center;margin:20px;}";
html += "h1{color:#007bff;}";
html += ".data{font-size:24px;margin:10px;}";
html += "</style></head><body>";
html += "<h1>Smart Energy Monitor</h1>";
html += "<div class='data'>Voltage: " + String(voltage, 1) + " V</div>";
html += "<div class='data'>Current: " + String(current, 2) + " A</div>";
html += "<div class='data'>Power: " + String(power, 1) + " W</div>";
html += "<div class='data'>Energy: " + String(energy, 2) + " kWh</div>";
html += "<div class='data'>Frequency: " + String(frequency, 1) + " Hz</div>";
html += "<div class='data'>Power Factor: " + String(pf, 2) + "</div>";
html += "<button onclick=\"fetch('/control?state=on')\">Turn ON</button>";
html += "<button onclick=\"fetch('/control?state=off')\">Turn OFF</button>";
html += "</body></html>";
server.send(200, "text/html", html);
}
void handleData() {
StaticJsonDocument<200> doc;
doc["voltage"] = voltage;
doc["current"] = current;
doc["power"] = power;
doc["energy"] = energy;
doc["frequency"] = frequency;
doc["pf"] = pf;
String json;
serializeJson(doc, json);
server.send(200, "application/json", json);
}
void handleControl() {
if (server.hasArg("state")) {
String state = server.arg("state");
if (state == "on") {
digitalWrite(RELAY_PIN, HIGH);
} else if (state == "off") {
digitalWrite(RELAY_PIN, LOW);
}
}
server.send(200, "text/plain", "OK");
}
Step 4: Matter Protocol Integration
Matter is the new unified smart home standard that works with Apple HomeKit, Google Home, Amazon Alexa, and Samsung SmartThings. Here's how to set it up:
- Commission the device: Use your smartphone's Matter-compatible app (Google Home, Apple Home, etc.)
- Scan QR code: The ESP32 will display a QR code on first boot
- Add to network: Follow the app's instructions to add the device
- Control remotely: Now you can control and monitor from anywhere!
Step 5: Advanced Automation Features
Now that you have real-time energy data, you can create powerful automations:
Example 1: High Power Alert
Send a notification when power exceeds a threshold:
if (power > 2000) {
// Send alert via email, Telegram, or push notification
Serial.println("WARNING: High power consumption detected!");
// Add your notification code here
}
Example 2: Auto-Shutoff
Automatically turn off devices after reaching energy limit:
if (energy > 10.0) { // 10 kWh limit
digitalWrite(RELAY_PIN, LOW);
Serial.println("Energy limit reached. Device turned off.");
}
Example 3: Time-of-Use Optimization
Run high-power devices during off-peak hours:
#include <NTPClient.h>
#include <WiFiUdp.h>
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org", 0, 60000);
void loop() {
timeClient.update();
int currentHour = timeClient.getHours();
// Run during off-peak hours (10 PM - 6 AM)
if (currentHour >= 22 || currentHour < 6) {
if (power < 1500) {
digitalWrite(RELAY_PIN, HIGH);
}
}
}
Step 6: Building a Home Assistant Dashboard (Optional)
For advanced users, you can integrate with Home Assistant for beautiful dashboards and complex automations:
- Install Home Assistant on a Raspberry Pi or old PC
- Add ESPHome integration
- Create custom sensors for voltage, current, power
- Build graphs and history tracking
- Set up automations with Node-RED
Troubleshooting Common Issues
| Problem | Solution |
|---|---|
| No data from PZEM | Check TX/RX wiring, ensure correct baud rate (9600) |
| OLED not displaying | Verify I2C address (usually 0x3C), check SDA/SCL pins |
| WiFi connection fails | Double-check SSID/password, ensure 2.4GHz network |
| Matter commissioning fails | Ensure phone and ESP32 on same network, check Matter app |
| Inaccurate readings | Calibrate sensor, check CT clamp orientation |
Cost Breakdown & Savings
Total Build Cost: ~$25
Potential Annual Savings: $100-$300 (depending on usage)
ROI Period: 1-3 months
Conclusion
Building your own smart energy monitor with ESP32 and Matter protocol is a rewarding project that combines electronics, programming, and smart home technology. Not only will you save money on your energy bills, but you'll also gain valuable skills and have a fully customizable system.
Next Steps:
- Add solar panel monitoring
- Integrate with battery storage systems
- Build a multi-channel monitor for different circuits
- Create a mobile app for remote monitoring
FAQ
Q: Can I use this with 110V systems?
A: Yes! The PZEM-004T supports 80-260V AC, so it works with both 110V and 220V systems.
Q: How accurate is the energy measurement?
A: The PZEM-004T has an accuracy of ±0.5%, which is comparable to commercial meters.
Q: Can I monitor multiple circuits?
A: Yes, you can add multiple PZEM sensors and use different UART pins on the ESP32.
Q: Is this safe to use?
A: Always follow electrical safety guidelines. Use proper insulation, turn off power when wiring, and consider using a professional enclosure.
.jpg)



