Close Menu
  • Articles
    • Learn Electronics
    • Product Review
    • Tech Articles
  • Electronics Circuits
    • 555 Timer Projects
    • Op-Amp Circuits
    • Power Electronics
  • Microcontrollers
    • Arduino Projects
    • STM32 Projects
    • AMB82-Mini IoT AI Camera
    • BLE Projects
  • IoT Projects
    • ESP8266 Projects
    • ESP32 Projects
    • ESP32 MicroPython
    • ESP32-CAM Projects
    • LoRa/LoRaWAN Projects
  • Raspberry Pi
    • Raspberry Pi Projects
    • Raspberry Pi Pico Projects
    • Raspberry Pi Pico W Projects
  • Electronics Calculator
Facebook X (Twitter) Instagram
  • About Us
  • Disclaimer
  • Privacy Policy
  • Contact Us
  • Advertise With Us
Facebook X (Twitter) Instagram Pinterest YouTube LinkedIn
How To Electronics
  • Articles
    • Learn Electronics
    • Product Review
    • Tech Articles
  • Electronics Circuits
    • 555 Timer Projects
    • Op-Amp Circuits
    • Power Electronics
  • Microcontrollers
    • Arduino Projects
    • STM32 Projects
    • AMB82-Mini IoT AI Camera
    • BLE Projects
  • IoT Projects
    • ESP8266 Projects
    • ESP32 Projects
    • ESP32 MicroPython
    • ESP32-CAM Projects
    • LoRa/LoRaWAN Projects
  • Raspberry Pi
    • Raspberry Pi Projects
    • Raspberry Pi Pico Projects
    • Raspberry Pi Pico W Projects
  • Electronics Calculator
How To Electronics
Home » DIY AC Energy Meter using PZEM-004T & Arduino
Arduino Projects

DIY AC Energy Meter using PZEM-004T & Arduino

Mamtaz AlamBy Mamtaz AlamUpdated:March 6, 20259 Mins Read
Share Facebook Twitter LinkedIn Telegram Reddit WhatsApp
PZEM-004T Arduino Energy Meter
Share
Facebook Twitter LinkedIn Pinterest Email Reddit Telegram WhatsApp

Overview

In this project, we will interface PZEM-004T (a compact AC power monitoring module) with Arduino to build a single phase AC Energy Meter. PZEM-004T Current and Voltage reader is a module that can measure current, voltage, active power (W), energy (kWh), frequency, and power factor. The module uses Modbus-RTU, a standard protocol for industrial communication. Microcontrollers such as Arduino can read PZEM-004T data via serial interfaces.

Earlier, we build the following energy meter projects:

  • GSM-Based Prepaid Energy Meter
  • IoT DC Energy Meter using INA226 & ESP32
  • IoT AC Energy Meter with ESP32 & Blynk
  • Energy Meter using ESP32 & HMI Display

While the projects mentioned above are excellent for learning energy monitoring concepts and well-suited for hobbyist applications, their accuracy is limited due to the use of basic components like the ZMPT101B voltage sensor and SCT-013 current sensor. These modules are not precision instruments, and their measurements may exhibit noticeable deviations.

Hence we need a precise Energy Meter that can measure all parameters correctly. The PZEM-004T is used for the same applications. In this energy meter project, we will establish a serial communication between PZEM-004T & Arduino, and read the data such as Voltage, Current, Power, Energy, Power Factor & Frequency. All these data can be displayed on 16×2 LCD Display. Further you can make the IoT version of this project using the PZEM-004T and ESP32 microcontroller.


Bill of Materials

We need the following components to build this energy meter project. You can purchase all the components from the given links.

S.N.Components NameQuantityPurchase Link
1Arduino Nano Board1Amazon | AliExpress
2PZEM-004T AC Meter Module1Amazon | AliExpress
316x2 LCD Display1Amazon | AliExpress
4Connecting Wires10Amazon | AliExpress
5Breadboard1Amazon | AliExpress
Fig: Components & Tools Required




PZEM-004T Multifunction AC Digital Meter

The PZEM-004T is a compact, single-phase AC power monitoring module designed to measure electrical parameters such as voltage (80–260V), current (up to 100A via external CT), active power, energy consumption (kWh), frequency, and power factor.

PZEM-004T V3.0
Fig: PZEM-004T V3.0

It communicates via Modbus-RTU protocol over TTL serial (), making it easy to interface with microcontrollers like Arduino or ESP32. With built-in galvanic isolation and a non-invasive current transformer, it prioritizes safety. It is widely used in IoT applications, smart metering, and home automation projects.

PZEM-004T V3.0 Feature

  • Voltage: 80–260V, 0.1V resolution, 0.5% accuracy
  • Current: 0–10A (10A model), 0–100A (100A model), 0.001A resolution, 0.5% accuracy
  • Active Power: 0–2.3kW (10A model), 0–23kW (100A model), 0.1W resolution, 0.5% accuracy
  • Power Factor: 0.00–1.00, 0.01 resolution, 1% accuracy
  • Frequency: 45–65Hz, 0.1Hz resolution, 0.5% accuracy
  • Active Energy: 0–9999.99kWh, 1Wh resolution, 0.5% accuracy, resettable via software
  • Over Power Alarm: Settable threshold, triggers alarm on exceedance
  • Communication: RS485 (UART to RS485), 9600 baud, 8N1

Open CT & Close CT

Both Close CT and Open CT are 100A current transformers (Class 1.5 accuracy) compatible with the PZEM-004T module.

Fig: PZEM-004T Open CT & Close CT

The Closed Current Transformer (CT) version of the PZEM-004T comes with a built-in, non-detachable CT, ensuring accurate and stable measurements. It is ideal for fixed installations where the sensor remains permanently connected to the measured circuit.

The Open Current Transformer (CT) version features a detachable clamp-type CT, allowing easy installation without disconnecting wires. This is useful for retrofitting or temporary monitoring applications where quick and flexible deployment is required.



Pinout of PZEM-004T V3.0

The PZEM-004T is an energy monitoring module that communicates via UART (RS485) and has the following pin configuration:

Pinout of PZEM-004T V3.0

1. Power & Measurement Pins:

  • L (Live) & N (Neutral): Connect to AC mains for voltage measurement and module power.
  • CT+ & CT-: Connect to the current transformer (CT) for current measurement.

2. Communication Pins (TTL Serial or RS485):

  • 5V: Power supply for the module (external 5V required).
  • GND: Ground reference for communication.
  • TX (Transmit): Sends data to the microcontroller.
  • RX (Receive): Receives data from the microcontroller.

Module TTL Interface Note: This module’s TTL interface is passive and requires an external 5V power supply. All four pins (5V, RX, TX, GND) must be connected for proper communication. Operating temperature range: -20°C to +60°C.

Communication Protocol of PZEM-004T V3.0

1. Physical Layer Protocol

  • Uses UART to RS485 communication interface
  • Baud rate: 9600, 8 data bits, 1 stop bit, no parity

2. Application Layer Protocol

  • Uses Modbus-RTU protocol
  • Supported function codes:
    • 0x03 (Read Holding Register)
    • 0x04 (Read Input Register)
    • 0x06 (Write Single Register)
    • 0x41 (Calibration – internal use only, requires password 0x3721)
    • 0x42 (Reset Energy)



3. Addressing

  • Slave address range: 0x01 – 0xF7
  • 0x00: Broadcast address (slave does not reply)
  • 0xF8: General address (for single-slave environments and calibration)

4. Reading Measurement Results

  • Master command format (8 bytes):
    Slave Address + 0x04 + Register Address (High + Low) + No. of Registers (High + Low) + CRC (High + Low)
  • Correct Reply:
    Slave Address + 0x04 + No. of Bytes + Register Data + CRC
  • Error Reply:
    Slave Address + 0x84 + Error Code + CRC
    • 0x01: Illegal function
    • 0x02: Illegal address
    • 0x03: Illegal data
    • 0x04: Slave error

5. Register Mapping

Register Address Description Resolution
0x0000 Voltage 0.1V
0x0001-0x0002 Current (Low & High) 0.001A
0x0003-0x0004 Power (Low & High) 0.1W
0x0005-0x0006 Energy (Low & High) 1Wh
0x0007 Frequency 0.1Hz
0x0008 Power factor 0.01
0x0009 Alarm status (0xFFFF = Alarm, 0x0000 = No Alarm)

For example, to read 10 registers from slave address 0x01, the master sends:
0x01 + 0x04 + 0x00 + 0x00 + 0x00 + 0x0A + CRC

Indicator Lights of PZEM-004T V3.0

The module has multiple LEDs to indicate power, pulse, and communication status:

Indicator Lights of PZEM-004T V3.0
Fig: Indicator Lights of PZEM-004T V3.0
  • Power Indicator Light: Shows that the module is powered and operational.
  • Pulse Indicator Light: It blinks based on active energy measurement. The higher blinking rate indicates higher power consumption.
  • TX Communication Light: Blinks when the module transmits data via RS485.
  • RX Communication Light: Blinks when the module receives data from the master device (e.g., Arduino, ESP32).

Refer to PZEM-004T Datasheet for more information.




Interfacing PZEM-004T Energy Meter Module with Arduino

Now let us interface the PZEM-004T Energy Meter Module with Arduino. The interfacing process is easy and requires some hardware connection and Arduino C++ Code.

Circuit Diagram & Connection

The following is the connection diagram which looks very simple.

Interfacing PZEM-004T Energy Meter Module with Arduino
Fig: Interfacing PZEM-004T Energy Meter Module with Arduino

Connect the PZEM-004T’s 5V and GND to Arduino’s 5V and GND for power. Link TX (PZEM) → RX (Arduino pin 10) and RX (PZEM) → TX (Arduino pin 11) for serial communication.

PZEM-004T Arduino Connection
Fig: PZEM-004T Arduino Connection

Connect the circuit on breadboard as per circuit diagram above.

Wire the live (L) and neutral (N) of your AC supply (120V/220V) to the PZEM’s AC input terminals (labeled “L” and “N”).

Fig: Current Transformer Connection

For Open CT (split-core): Clamp the CT around the live wire of the AC circuit you want to monitor (do NOT clamp neutral).
For Close CT (solid-core): Disconnect the circuit, thread the live wire through the CT’s core, and reconnect.

Caution: Isolate AC input (120/220V) wiring from Arduino circuits for safety.



Source Code/Program

Lets write an Arduino C++ Code to establish a Serial Communication between Arduino & PZEM-004T Energy Meter Module.

Before moving to the coding part, first install the PZEM-004T Arduino Library. The library is well written and does the Energy monitoring task using the ModBUS interface.

This Arduino code reads power parameters from a PZEM-004T V3.0 energy meter using SoftwareSerial on pins 11 (TX) and 12 (RX). It retrieves and displays voltage, current, power, energy, frequency, and power factor on the Serial Monitor. If any value is invalid, it prints an error message. Readings update every 2 seconds.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#include <PZEM004Tv30.h>      //https://github.com/mandulaj/PZEM-004T-v30
#include <SoftwareSerial.h>
 
// Define software serial pins for PZEM communication
#define RX_PIN 12 // Connect to PZEM Tx
#define TX_PIN 11 // Connect to PZEM Rx
 
// Create a software serial object
SoftwareSerial pzemSWSerial(RX_PIN, TX_PIN);
 
// Create a PZEM004Tv30 object
PZEM004Tv30 pzem(pzemSWSerial);
 
void setup() {
  // Initialize Serial Monitor
  Serial.begin(115200);
  Serial.println("PZEM-004T V3.0 Power Meter Reading");
}
 
void loop() {
  // Read and print the module's custom address
  Serial.print("Custom Address: 0x");
  Serial.println(pzem.readAddress(), HEX);
 
  // Read values from the PZEM sensor
  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 the data is valid before printing
  if (isnan(voltage)) {
    Serial.println("Error reading voltage");
  } else if (isnan(current)) {
    Serial.println("Error reading current");
  } else if (isnan(power)) {
    Serial.println("Error reading power");
  } else if (isnan(energy)) {
    Serial.println("Error reading energy");
  } else if (isnan(frequency)) {
    Serial.println("Error reading frequency");
  } else if (isnan(pf)) {
    Serial.println("Error reading power factor");
  } else {
    // Print measured values to the Serial Monitor
    Serial.print("Voltage: ");      Serial.print(voltage);      Serial.println(" V");
    Serial.print("Current: ");      Serial.print(current);      Serial.println(" A");
    Serial.print("Power: ");        Serial.print(power);        Serial.println(" W");
    Serial.print("Energy: ");       Serial.print(energy, 3);   Serial.println(" kWh");
    Serial.print("Frequency: ");    Serial.print(frequency, 1); Serial.println(" Hz");
    Serial.print("Power Factor: "); Serial.println(pf);
  }
 
  Serial.println(); // Add a blank line for readability
  delay(2000); // Wait before next reading
}

Copy the above code and paste it into your Arduino IDE editor window.



Testing & Results

From the Tools Menu, Select the Arduino Nano/UNO Board depending upon your board. Select the COM port and click on upload button to upload the code.

Once the code uploading is done the device is ready for testing. Power on the load now so that the load turns ON.

Fig: Testing PZEM-004T & Arduino

Open the Serial Monitor to observe the data.

The Serial monitor will show the following results when no load is connected.

Fig: Test Results without Load

The Serial Monitor will show the following results when any load is connected.

Fig: Test Results with Load

As you see in the image above, the PZEM-004T Module with Arduino is able to read the value of Voltage, Current, Power, Energy, Power Factor & Frequency.




PZEM-004T Energy Meter with Arduino & LCD Display

Now lets add an additional LCD Screen to the above circuit to display the energy meter parameters on LCD Screen. The hardware connection and coding requires an upgrade again.

Circuit Diagram & Connection

Here is the connection diagram for the LCD part.

PZEM-004T with Arduino & LCD
Fig: PZEM-004T with Arduino & LCD

Connect the VCC & GND pin of the LCD Display to Arduino 5V & GND pin respectively. Similarly, connect the SDA & SCL pin of the LCD Display to A4 & A5 of Arduino.

Fig: PZEM-004T Arduino LCD Assembly

Once the hardware connection is done, we can move ahead to the coding part.

Source Code/Program

The following Arduino C++ code has additional lines for displaying the PZEM-004T Energy Meter parameters on LCD Screen. You need to add I2C LCD Library for the code compilation.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#include <PZEM004Tv30.h>      //https://github.com/mandulaj/PZEM-004T-v30
#include <SoftwareSerial.h>
#include <LiquidCrystal_I2C.h>
 
// Initialize the I²C LCD at address 0x27 with 16 columns and 2 rows.
LiquidCrystal_I2C lcd(0x27, 16, 2);
 
// Define software serial pins for PZEM communication
#define RX_PIN 12 // Connect to PZEM Tx
#define TX_PIN 11 // Connect to PZEM Rx
 
// Create a software serial object
SoftwareSerial pzemSWSerial(RX_PIN, TX_PIN);
 
// Create a PZEM004Tv30 object
PZEM004Tv30 pzem(pzemSWSerial);
 
void setup()
{
  lcd.init();
  lcd.backlight();
  lcd.clear();
  // Initialize Serial Monitor
  Serial.begin(115200);
  Serial.println("PZEM-004T V3.0 Power Meter Reading");
}
 
void loop()
{
  // Read and print the module's custom address
  Serial.print("Custom Address: 0x");
  Serial.println(pzem.readAddress(), HEX);
 
  // Read values from the PZEM sensor
  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 the data is valid before printing
  if (isnan(voltage)) {
    Serial.println("Error reading voltage");
  } else if (isnan(current)) {
    Serial.println("Error reading current");
  } else if (isnan(power)) {
    Serial.println("Error reading power");
  } else if (isnan(energy)) {
    Serial.println("Error reading energy");
  } else if (isnan(frequency)) {
    Serial.println("Error reading frequency");
  } else if (isnan(pf)) {
    Serial.println("Error reading power factor");
  } else {
    // Print measured values to the Serial Monitor
    Serial.print("Voltage: ");      Serial.print(voltage);      Serial.println(" V");
    Serial.print("Current: ");      Serial.print(current);      Serial.println(" A");
    Serial.print("Power: ");        Serial.print(power);        Serial.println(" W");
    Serial.print("Energy: ");       Serial.print(energy, 3);   Serial.println(" kWh");
    Serial.print("Frequency: ");    Serial.print(frequency, 1); Serial.println(" Hz");
    Serial.print("Power Factor: "); Serial.println(pf);
    Serial.println();
 
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Voltage: ");
    lcd.print(voltage);
    lcd.print("V");
    lcd.setCursor(0, 1);
    lcd.print("Current:");
    lcd.print(current);
    lcd.print("A");
    delay(2000);
 
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Power:");
    lcd.print(power);
    lcd.print("W");
    lcd.setCursor(0, 1);
    lcd.print("Energy:");
    lcd.print(energy, 3);
    lcd.print("kWh");
    delay(2000);
 
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Frequency:");
    lcd.print(frequency, 1);
    lcd.print("Hz");
    lcd.setCursor(0, 1);
    lcd.print("PF:");
    lcd.print(pf);
    delay(2000);
  }
}

Copy the above code and paste it on your Arduino IDE editor window.



Testing & Results

Upload the above code to the Arduino board and the device will be ready for testing.

Once code uploading is done and the load is powered ON, the LCD Display will start displaying the Energy Meter parameters.

AC Energy Meter using PZEM-004T & Arduino
Fig: AC Energy Meter using PZEM-004T & Arduino

Initially the LCD Screen displays voltage and current for 2 seconds.

Fig: Voltage & Current Display

After 2 seconds, the LCD shows the value of Power and Energy Consumption.

Fig: Power and Energy Display

Finally, again after 2 seconds, it shows the value of frequency and power factor.

Fig: Frequency and Power Factor Display

In this way, you can build an AC Energy Meter using PZEM-004T & Arduino board and display the energy meter parameters on LCD Screen.

Share. Facebook Twitter Pinterest LinkedIn Tumblr Email Reddit Telegram WhatsApp
Previous ArticleWater Level Alert using Float Sensor & 555 Timer
Next Article IoT AC Energy Meter with PZEM-004T & ESP32 WebServer

Related Posts

DC Energy Meter using Arduino

Build a DC Energy Meter using Arduino – 32V/5A

Updated:August 26, 20252K
Interfacing ADXL375 Accelerometer with Arduino

Interfacing ADXL375 Accelerometer with Arduino (±200g)

Updated:June 28, 2025
Interfacing BMI160 Accelerometer & Gyroscope with Arduino

Interfacing BMI160 Accelerometer & Gyroscope with Arduino

Updated:February 2, 20259K
Password Based Door Lock Security System Using Arduino & Keypad

Password Based Door Lock Security System Using Arduino & Keypad

Updated:February 2, 20252436K
Earthquake Detector Alarm with with Accelerometer & Arduino

Earthquake Detector Alarm with Accelerometer & Arduino

Updated:February 2, 2025661K
74HC595 Shift Register with Arduino

Shift Register 74HC595 with Arduino – Examples & Code

Updated:February 2, 202516K
Add A Comment

CommentsCancel reply

Latest Posts

ESP32 Fingerprint Attendance System with Live Web Dashboard

June 14, 2026
IoT Based PM & Air Quality Monitoring System using ESP32

IoT Based PM & Air Quality Monitoring System using ESP32

June 14, 2026
DIY ESP32 MLX90640 IR Thermal Camera with Live Web Display

DIY ESP32 MLX90640 IR Thermal Camera with Live Web Display

May 10, 2026
IoT Activity Tracker with ESP32 & Accelerometer Gyroscope

IoT Activity Tracker with ESP32 & Accelerometer/Gyroscope

May 2, 2026
A Guide to Sourcing Obsolete ICs for Vintage Projects

Beyond AliExpress: A Guide to Sourcing Obsolete ICs for Vintage Projects

April 21, 2026

ESP32 IoT Vehicle Motion Analyzer with MPU6050 & LIS3MDL

April 27, 2026
Building a Smart Sensor Node with a BLE Microcontroller

Building a Smart Sensor Node with a BLE Microcontroller

February 26, 2026
High-Accuracy Pitch, Roll, Yaw with ESP32 & BNO08x IMU

High-Accuracy Pitch, Roll, Yaw with ESP32 & BNO08x IMU

April 27, 2026
Top Posts & Pages
  • IoT Based PM & Air Quality Monitoring System using ESP32
    IoT Based PM & Air Quality Monitoring System using ESP32
  • How to use LDR Sensor Module with Arduino
    How to use LDR Sensor Module with Arduino
  • 12V DC to 220V AC Inverter Circuit & PCB
    12V DC to 220V AC Inverter Circuit & PCB
  • Buck Converter: Basics, Working, Design & Application
    Buck Converter: Basics, Working, Design & Application
  • IoT AC Energy Meter with PZEM-004T & ESP32 WebServer
    IoT AC Energy Meter with PZEM-004T & ESP32 WebServer
  • How to use Modbus RTU with ESP32 to read Sensor Data
    How to use Modbus RTU with ESP32 to read Sensor Data
  • Silicon Controlled Rectifier (SCR): Construction, Working & Applications
    Silicon Controlled Rectifier (SCR): Construction, Working & Applications
  • ECG Graph Monitoring with AD8232 ECG Sensor & Arduino
    ECG Graph Monitoring with AD8232 ECG Sensor & Arduino
Categories
  • Arduino Projects (197)
  • Articles (60)
    • Learn Electronics (19)
    • Product Review (15)
    • Tech Articles (28)
  • Electronics Circuits (46)
    • 555 Timer Projects (21)
    • Op-Amp Circuits (7)
    • Power Electronics (13)
  • IoT Projects (205)
    • ESP32 MicroPython (7)
    • ESP32 Projects (82)
    • ESP32-CAM Projects (15)
    • ESP8266 Projects (76)
    • LoRa/LoRaWAN Projects (22)
  • Microcontrollers (38)
    • AMB82-Mini IoT AI Camera (4)
    • BLE Projects (18)
    • STM32 Projects (19)
  • Raspberry Pi (93)
    • Raspberry Pi Pico Projects (57)
    • Raspberry Pi Pico W Projects (12)
    • Raspberry Pi Projects (24)
Follow Us
  • Facebook
  • Twitter
  • Pinterest
  • Instagram
  • YouTube
About Us

“‘How to Electronics’ is a vibrant community for electronics enthusiasts and professionals. We deliver latest insights in areas such as Embedded Systems, Power Electronics, AI, IoT, and Robotics. Our goal is to stimulate innovation and provide practical solutions for students, organizations, and industries. Join us to transform learning into a joyful journey of discovery and innovation.

Copyright © How To Electronics. All rights reserved.
  • About Us
  • Disclaimer
  • Privacy Policy
  • Contact Us
  • Advertise With Us

Type above and press Enter to search. Press Esc to cancel.

Ad Blocker Enabled!
Ad Blocker Enabled!
Looks like you're using an ad blocker. Please allow ads on our site. We rely on advertising to help fund our site.