DIY Smart Power Meter With CSV Data Logging (PZEM-004T)
by Benjamin_Tanudjaja in Circuits > Sensors
340 Views, 3 Favorites, 0 Comments
DIY Smart Power Meter With CSV Data Logging (PZEM-004T)
When I was working on my university research paper about energy saving, I needed a reliable way to collect real power consumption data over time. Most of the analysis required continuous logging so I could process the results later in tools like Excel.
I started looking for a power meter that could log data directly into a CSV file. While there are plenty of commercial devices available, they are often very expensive and not very flexible for custom research needs. I also tried to find a DIY version online, but surprisingly, I couldn’t find a simple and complete solution that fit my requirements.
So instead of giving up, I decided to build my own smart power meter with PZEM-004T. The goal was to create a low-cost, customizable device that can measure electrical parameters and log them into a CSV file for easy analysis.
In this Instructable, I’ll show you how you can build your own smart power meter, log data efficiently, and use it for projects like energy monitoring, research, or improving energy efficiency at home.
Supplies
Components:
- Microcontroller (ESP32-C3 Supermini)
- Current sensor (PZEM-004T 10A)
- DC power supply (WX-DC12003)
- Real time clock (RTC DS1307)
- TFT Display (2.4" SPI TFT Touchscreen ILI9488)
- Jumper wires
- Breadboard / PCB
Tools:
- Soldering iron
- Multimeter
Software:
- Arduino IDE / PlatformIO
- Required libraries
How It Works
In this project, instead of building a power measurement circuit from scratch, I used the PZEM-004T 10A module, which makes things much easier and more accurate. This module can directly measure voltage, current, power, and energy, and communicates with a microcontroller digitally.
On top of that, I added a 2.4" TFT touchscreen display with an SD card slot, which allows the system to both visualize data in real time and log it into CSV files for later analysis.
Power Measurement with PZEM-004T
The PZEM-004T handles all the complex electrical measurements internally.
- It measures:
- Voltage (V)
- Current (A)
- Power (W)
- Energy (kWh)
- It communicates with the microcontroller using UART (serial communication)
- This eliminates the need for manual calibration and complex signal processing
The microcontroller simply reads ready-to-use values from the module.
TFT Touchscreen Display Interface
The 2.4" TFT touchscreen acts as the main user interface of the system. It also includes an SD card slot, which is used for data logging.
The interface is divided into 5 pages:
- Page 1 – Real-Time DataDisplays live readings:
- Voltage
- Current
- Power
- Energy
- Page 2 – Daily Graph Shows power usage throughout the day
- Page 3 – Weekly Graph Displays energy trends over the week
- Page 4 – Monthly Graph usage over a month
- Page 5 – Yearly Graph Long-term energy consumption visualization
Users can switch between pages using the touchscreen.
CSV Data Logging (Built-in SD Card)
All measured data is saved into a CSV file using the SD card slot on the display.
The format of the CSV is:
This makes it easy to:
- Open in Excel / Google Sheets
- Generate graphs
- Use in research (like my energy-saving paper)
System Workflow
The system continuously runs in a loop:
- Read data from PZEM-004T
- Update real-time display (Page 1)
- Save data to CSV file
- Update graph data (Pages 2–5)
- Wait for user input (touchscreen navigation)
- Repeat
Understanding the PZEM-004T (10A Vs 100A)
The PZEM-004T is a popular AC energy monitoring module that simplifies power measurement by giving you ready-to-use digital data (voltage, current, power, and energy) via UART communication.
However, there are two common versions of this module:
👉 10A version and 👉 100A version
Important: Both the 10A and 100A version is available in different physical board module.
And choosing the right one is very important for both accuracy and wiring. Both version offer the same accuracy meassurement: voltage, current, power, frequency of 0.5%, but with the 100A version, you'll get 10x worse accuracy than the 10A version.
Key Difference: How Current Is Measured
PZEM-004T 10A (Direct Measurement)
- Measures current directly through the module
- The load current flows through the board itself
- Measures current with built in shunt resistor
PZEM-004T 100A (With Current Transformer Clamp)
- Uses an external current transformer (CT clamp)
- The wire passes through the clamp for current reading. But, it also needs Lin and Nin to read voltage
- Measures current indirectly via magnetic field
There are also 2 types of clamp
When using the PZEM-004T 100A version, the current is measured using a Current Transformer (CT clamp). There are two common types of CT clamps: Open CT (split-core) and Closed CT (solid-core).
Read the measurement result
The command format of the master reads the measurement result is(total of 8 bytes):
Slave Address + 0x04 + Register Address High Byte + Register Address Low Byte + Number of Registers High Byte + Number of Registers Low Byte + CRC Check High Byte + CRC Check Low Byte.
The command format of the reply from the slave is divided into two kinds: Correct Reply:
Slave Address + 0x04 + Number of Bytes + Register 1 Data High Byte + Register 1 Data Low Byte + ... + CRC Check High Byte + CRC Check Low Byte
Error Reply:
Slave address + 0x84 + Abnormal code + CRC check high byte + CRC check low byte Abnormal code analyzed as following (the same below)
- 0x01,Illegal function
- 0x02,Illegal address
- 0x03,Illegal data
- 0x04,Slave error
The register of the measurement results is arranged as the table shown above
For example, the master sends the following command (CRC check code is replaced by 0xHH and 0xLL, the same below)
0x01 + 0x04 + 0x00 + 0x00 + 0x00 + 0x0A + 0xHH + 0xLL
Indicates that the master needs to read 10 registers with slave address 0x01 and the start address of the register is 0x0000
The correct reply from the slave is as following:
0x01 + 0x04 + 0x14 + 0x08 + 0x98 + 0x03 + 0xE8+0x00 + 0x00 +0x08 + 0x98+ 0x00 + 0x00 + 0x00 + 0x00 + 0x00 + 0x00 + 0x01 + 0xF4 + 0x00 + 0x64 + 0x00 + 0x00 + 0xHH + 0xLL
The above data shows
- Voltage is 0x0898, converted to decimal is 2200, display 220.0V
- Current is 0x000003E8, converted to decimal is 1000, display 1.000A
- Power is 0x00000898, converted to decimal is 2200, display 220.0W
- Energy is 0x00000000, converted to decimal is 0, display 0Wh
- Frequency is 0x01F4, converted to decimal is 500, display 50.0Hz
- Power factor is 0x0064, converted to decimal is 100, display 1.00
- Alarm status is 0x0000, indicates that the current power is lower than the alarm power threshold
Circuit Diagram
SPI — TFT, Touchscreen, SD Card
The TFT display, touchscreen, and SD card share the same SPI bus (MOSI, MISO, SCK).Each device is controlled using a separate CS (Chip Select) pin.
Only one device is active at a time based on its CS pin.
I²C — RTC
The RTC module uses I²C, which only needs:
- SDA (data)
- SCL (clock)
Used to provide timestamps for CSV logging.
UART — PZEM-004T
The PZEM-004T uses UART (serial):
- TX → RX
- RX → TX
Important: Arduino UNO have only 1 UART, so you can't open serial monitor while using the PZEM. Other microcontroller may have more than 1 UART (like ESP32-C3 in this case)
In the PCB that I've designed, you need to jumper 2 connections, the GND and the SCK, because I really tried to make it only with 1 layer.
Hardware Setup
1: Modify the PZEM UART Connector
The PZEM-004T comes with an XH connector that is not PCB-friendly.
- Remove the default connector
- Replace it with pin headers
- Connect a wire to PZEM Lin and Nin
- This allows the module to be directly soldered or plugged into the PCB
2: Solder All Components
Once the PCB is ready:
- Solder all components one by one:
- Headers
- Connectors
- Modules
3: Jumper Unconnected Traces
There are 2 unconnected trace, the GND and the SCK.
- Use jumper wires to connect missing traces
- Keep them short and neat
- Double-check connections with a multimeter
4: Mount the TFT Using Stacked Headers
To save space and allow proper layering:
- Use two stacked female headers for the TFT display
- This raises the display above the PCB
- Allows other components to sit underneath
Installing Libraries & Setup
This project uses a few libraries to handle each module:
- PZEM-004T-v30 → Reads voltage, current, power, and energy via UART
https://github.com/mandulaj/PZEM-004T-v30.git
- RTClib → Gets time from the RTC via I²C (used for timestamps)
https://github.com/adafruit/RTClib.git
- Adafruit GFX → Basic graphics (text, shapes, graphs)
https://github.com/adafruit/Adafruit-GFX-Library.git
- Adafruit ILI9341 → Controls the TFT display via SPI
https://github.com/adafruit/Adafruit_ILI9341.git
- XPT2046_Touchscreen → Reads touch input via SPI
https://github.com/PaulStoffregen/XPT2046_Touchscreen.git
⚠️ Important:
Different TFT displays use different driver chips (ILI9341, ST7735, ST7789, etc.), so you must use the correct driver library for your specific display.
The Full code is uploaded to my Github:
https://github.com/benjamintanudjaja-alt/DIY-Smart-Power-Meter-With-CSV-Data-Logging-PZEM-004T-
Safety Notes