Complete Wiring Diagram
Step-by-step guide to wire ESP32, PZEM-004T, and relay module for a complete Gridova system
Safety First!
This guide involves both low-voltage (3.3V/5V DC) and high-voltage (220V AC) connections. Always disconnect all power sources before making any connections. Have your wiring inspected by a qualified electrician before powering on. Improper wiring can cause electric shock, fire, equipment damage, or death.
System Overview
The complete Gridova hardware system consists of:
Visual Wiring Diagram
Diagram Legend
- Red lines: Power/Live voltage (AC or DC)
- Black lines: Ground/Neutral connections
- Blue lines: Signal/Data connections
- Dashed box: High-voltage danger zone
Connection Tables
ESP32 to PZEM-004T (UART Communication)
| PZEM Pin | ESP32 Pin | Wire Color | Notes |
|---|---|---|---|
| 5V | VIN (5V) | Red | Power supply for PZEM |
| GND | GND | Black | Common ground |
| RX | GPIO 17 (TX2) | Blue | PZEM receives data from ESP32 |
| TX | GPIO 16 (RX2) | Green | PZEM transmits data to ESP32 |
ESP32 to Relay Module (Control Signals)
| Relay Pin | ESP32 Pin | Wire Color | Notes |
|---|---|---|---|
| VCC | 3.3V | Red | 3.3V or 5V depending on module |
| GND | GND | Black | Common ground |
| IN1 | GPIO 25 | Yellow | Control signal for relay 1 |
| IN2 | GPIO 26 | Orange | Control signal for relay 2 (optional) |
High Voltage AC Wiring (⚠️ Danger!)
| From | To | Wire Spec | Description |
|---|---|---|---|
| AC Mains Live | Circuit Breaker IN | 14-12 AWG | Main power input |
| Circuit Breaker OUT | PZEM L in | 14-12 AWG | Protected live to sensor |
| PZEM L out | Relay COM | 14-12 AWG | Measured live to switch |
| Relay NO | Load Live | 14-12 AWG | Switched live to appliance |
| AC Mains Neutral | PZEM N in | 14-12 AWG | Neutral to sensor |
| PZEM N out | Load Neutral | 14-12 AWG | Neutral direct to appliance |
| AC Mains Ground | Load Ground | 14-12 AWG | Safety ground to appliance |
Power Supply Requirements
Shared Ground Important
All components (ESP32, PZEM, relay module) must share a common ground connection. This ensures proper communication and prevents signal issues. Connect all GND pins together.
Step-by-Step Assembly Guide
Testing Checklist
Complete Arduino Code
Full integration code combining all components:
gridova_complete_system.inocpp
#include <WiFi.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
#include <PZEM004Tv30.h>
// WiFi credentials
const char* ssid = "YOUR_WIFI_SSID";
const char* password = "YOUR_WIFI_PASSWORD";
// API configuration
const char* apiUrl = "https://api.gridova.com/data";
const char* deviceId = "ROOM_001";
// Pin definitions
#define RELAY1_PIN 25
#define RELAY2_PIN 26
// Initialize PZEM sensor
PZEM004Tv30 pzem(Serial2, 16, 17); // RX=16, TX=17
// Timing
unsigned long lastSendTime = 0;
const unsigned long sendInterval = 5000; // 5 seconds
void setup() {
Serial.begin(115200);
Serial.println("Gridova System Starting...");
// Initialize relay pins
pinMode(RELAY1_PIN, OUTPUT);
pinMode(RELAY2_PIN, OUTPUT);
digitalWrite(RELAY1_PIN, HIGH); // OFF (Active Low)
digitalWrite(RELAY2_PIN, HIGH); // OFF
// Connect to WiFi
WiFi.begin(ssid, password);
Serial.print("Connecting to WiFi");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nConnected!");
Serial.print("IP Address: ");
Serial.println(WiFi.localIP());
// Test PZEM connection
delay(1000);
float voltage = pzem.voltage();
if (!isnan(voltage)) {
Serial.println("PZEM sensor OK");
} else {
Serial.println("PZEM sensor error!");
}
Serial.println("System ready!");
}
void loop() {
unsigned long currentTime = millis();
// Send data periodically
if (currentTime - lastSendTime >= sendInterval) {
readAndSendData();
lastSendTime = currentTime;
}
// Check for relay commands
checkRelayCommands();
delay(100);
}
void readAndSendData() {
// Read all PZEM values
float voltage = pzem.voltage();
float current = pzem.current();
float power = pzem.power();
float energy = pzem.energy();
float frequency = pzem.frequency();
float pf = pzem.pf();
// Check if readings are valid
if (isnan(voltage)) {
Serial.println("Error reading PZEM sensor");
return;
}
// Create JSON payload
StaticJsonDocument<512> doc;
doc["device_id"] = deviceId;
doc["timestamp"] = millis();
JsonObject data = doc.createNestedObject("sensor_data");
data["voltage"] = voltage;
data["current"] = current;
data["power"] = power;
data["energy"] = energy;
data["frequency"] = frequency;
data["power_factor"] = pf;
JsonObject relayStatus = doc.createNestedObject("relay_status");
relayStatus["relay1"] = (digitalRead(RELAY1_PIN) == LOW);
relayStatus["relay2"] = (digitalRead(RELAY2_PIN) == LOW);
String jsonString;
serializeJson(doc, jsonString);
// Send to server
if (WiFi.status() == WL_CONNECTED) {
HTTPClient http;
http.begin(apiUrl);
http.addHeader("Content-Type", "application/json");
int httpCode = http.POST(jsonString);
if (httpCode > 0) {
Serial.printf("✓ Data sent (HTTP %d)\n", httpCode);
} else {
Serial.printf("✗ Send failed: %s\n",
http.errorToString(httpCode).c_str());
}
http.end();
}
// Display readings
Serial.println("\n========== Readings ==========");
Serial.printf("Voltage: %.2f V\n", voltage);
Serial.printf("Current: %.3f A\n", current);
Serial.printf("Power: %.2f W\n", power);
Serial.printf("Energy: %.3f kWh\n", energy);
Serial.printf("Frequency: %.1f Hz\n", frequency);
Serial.printf("PF: %.2f\n", pf);
Serial.printf("Relay1: %s\n",
digitalRead(RELAY1_PIN) == LOW ? "ON" : "OFF");
Serial.printf("Relay2: %s\n",
digitalRead(RELAY2_PIN) == LOW ? "ON" : "OFF");
Serial.println("=============================\n");
}
void checkRelayCommands() {
if (WiFi.status() != WL_CONNECTED) return;
HTTPClient http;
String url = String(apiUrl) + "/relay/status?device_id=" + deviceId;
http.begin(url);
int httpCode = http.GET();
if (httpCode == 200) {
String payload = http.getString();
StaticJsonDocument<256> doc;
DeserializationError error = deserializeJson(doc, payload);
if (!error) {
bool relay1Cmd = doc["relay1"];
bool relay2Cmd = doc["relay2"];
// Update relay states
digitalWrite(RELAY1_PIN, relay1Cmd ? LOW : HIGH);
digitalWrite(RELAY2_PIN, relay2Cmd ? LOW : HIGH);
}
}
http.end();
}
// Emergency shutoff function
void emergencyShutoff() {
digitalWrite(RELAY1_PIN, HIGH); // OFF
digitalWrite(RELAY2_PIN, HIGH); // OFF
Serial.println("EMERGENCY SHUTOFF ACTIVATED!");
}Troubleshooting Common Issues
Safety Reminders
Critical Safety Points
- ✋ Never work on live circuits - always disconnect power first
- 🔌 Use proper wire gauge - undersized wires can overheat and cause fire
- ⚡ Install circuit breaker - protect against overcurrent conditions
- 📦 Proper enclosure required - prevent accidental contact with terminals
- 🔍 Regular inspection - check for loose connections, overheating, damage
- 👷 Have it inspected - qualified electrician should verify installation
- 📋 Follow local codes - electrical work must comply with regulations
- 🚨 Emergency shutoff - know where your main breaker is located
