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:

ESP32
Main controller - connects to WiFi, reads PZEM data, controls relay, communicates with backend API
PZEM-004T
Energy sensor - measures voltage, current, power, energy, frequency, and power factor of AC load
Relay Module
Power switch - allows ESP32 to remotely turn AC appliances ON/OFF via mobile app or automation

Visual Wiring Diagram

ESP32 to PZEM-004T Wiring Diagram
Connect your ESP32 to PZEM sensor and relay module
ESP32GPIO16 (RX2)GPIO17 (TX2)5VGNDGPIO25PZEM-004TRXTX5VGNDRelay ModuleINVCC (5V)GNDCOM/NO/NC5V PowerSupplyTX2 → RXRX2 → TXGPIO25 → IN

Pin Connections:

ESP32 to PZEM-004T
GPIO16 (RX2)PZEM TX
GPIO17 (TX2)PZEM RX
5VPZEM 5V
GNDPZEM GND
ESP32 to Relay
GPIO25Relay IN
5VRelay VCC
GNDRelay GND

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 PinESP32 PinWire ColorNotes
5VVIN (5V)RedPower supply for PZEM
GNDGNDBlackCommon ground
RXGPIO 17 (TX2)BluePZEM receives data from ESP32
TXGPIO 16 (RX2)GreenPZEM transmits data to ESP32

ESP32 to Relay Module (Control Signals)

Relay PinESP32 PinWire ColorNotes
VCC3.3VRed3.3V or 5V depending on module
GNDGNDBlackCommon ground
IN1GPIO 25YellowControl signal for relay 1
IN2GPIO 26OrangeControl signal for relay 2 (optional)

High Voltage AC Wiring (⚠️ Danger!)

FromToWire SpecDescription
AC Mains LiveCircuit Breaker IN14-12 AWGMain power input
Circuit Breaker OUTPZEM L in14-12 AWGProtected live to sensor
PZEM L outRelay COM14-12 AWGMeasured live to switch
Relay NOLoad Live14-12 AWGSwitched live to appliance
AC Mains NeutralPZEM N in14-12 AWGNeutral to sensor
PZEM N outLoad Neutral14-12 AWGNeutral direct to appliance
AC Mains GroundLoad Ground14-12 AWGSafety ground to appliance

Power Supply Requirements

Low Voltage DC (5V)
  • ESP32: ~200-500mA (WiFi active)
  • PZEM: ~30-50mA
  • Relay: ~70-100mA per relay
  • Total: Minimum 1A, recommended 2A
  • Source: USB power adapter, 5V DC supply, or AC-DC converter
High Voltage AC (220V)
  • Input: 220V AC (or local mains voltage)
  • Frequency: 50/60 Hz
  • Circuit Breaker: Rated for load + 20% margin
  • Wire Gauge: 14 AWG (15A) or 12 AWG (20A)
  • Protection: GFCI/RCD recommended for safety

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

1Prepare Components and Tools

Required tools:

  • Screwdrivers (Phillips and flat-head)
  • Wire strippers and cutters
  • Multimeter (for testing)
  • Soldering iron and solder (for permanent connections)
  • Heat shrink tubing or electrical tape
  • Jumper wires or solid core wires (22-18 AWG for signals)
  • AC wiring (14-12 AWG for high voltage)
2Connect Low Voltage Components First
  1. Mount ESP32 on breadboard or PCB
  2. Connect PZEM 5V and GND to ESP32 VIN and GND
  3. Connect PZEM RX to ESP32 GPIO 17 (TX2)
  4. Connect PZEM TX to ESP32 GPIO 16 (RX2)
  5. Connect relay VCC to ESP32 3.3V (or 5V if needed)
  6. Connect relay GND to common ground
  7. Connect relay IN1 to ESP32 GPIO 25
  8. Double-check all connections with multimeter
3Test Low Voltage System
  1. Upload test code to ESP32 (without AC power connected)
  2. Open Serial Monitor and verify PZEM communication
  3. Test relay clicking with digitalWrite commands
  4. Verify WiFi connection and API communication
  5. Fix any issues before proceeding to high voltage
4Wire High Voltage AC (Extreme Caution!)

Power Off Required

Turn OFF and UNPLUG all AC power sources before proceeding. Use a non-contact voltage tester to verify power is off.
  1. Install circuit breaker/fuse in electrical box
  2. Connect AC Live from mains to breaker input
  3. Connect breaker output to PZEM L in
  4. Connect PZEM L out to relay COM terminal
  5. Connect relay NO to appliance Live wire
  6. Connect AC Neutral from mains to PZEM N in
  7. Connect PZEM N out to appliance Neutral
  8. Connect ground wire to appliance ground terminal
  9. Secure all terminals tightly with screwdriver
  10. Verify no exposed conductors or loose wires
5Final Testing and Enclosure
  1. Place everything in proper electrical enclosure
  2. Label all wires and terminals clearly
  3. Close enclosure but don't seal yet (for testing)
  4. Power on ESP32 via USB (not AC yet)
  5. Verify relay is in OFF state (open circuit)
  6. Use multimeter to test for continuity
  7. Plug in AC power to PZEM/Relay side
  8. Test relay operation without load first
  9. Connect small load (lamp) and test full system
  10. Monitor for several hours to ensure stability
  11. If all tests pass, seal enclosure properly

Testing Checklist

Pre-Power Testing

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

PZEM Shows NaN Values
  • Check RX/TX wiring (may be swapped)
  • Ensure PZEM has stable 5V power
  • Verify PZEM is connected to AC power (needed for readings)
  • Try adding delay(1000) after Serial2.begin()
Relay Doesn't Switch Load
  • Verify using COM and NO terminals (not NC)
  • Check relay current rating vs load current
  • Test relay with multimeter (continuity test)
  • Ensure relay gets proper control signal
ESP32 Keeps Rebooting
  • Power supply may be insufficient (use 2A adapter)
  • Add capacitor (100µF) across power pins
  • Check for short circuits
  • Reduce WiFi transmission power in code
Incorrect Power Readings
  • Ensure current flows through L in → L out only
  • Neutral should bypass PZEM internal CT
  • Check for multiple loads on same circuit
  • Verify load is actually powered on

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

Next Steps

API Integration
Connect your hardware to Gridova backend via REST API and WebSocket
Mobile App Setup
Install and configure Gridova Flutter app to monitor and control your devices
Advanced Features
Setup automation rules, energy monitoring, and billing calculations