PZEM-004T energy monitor on an Arduino Uno
A PZEM-004T v3.0 AC energy meter on Modbus: the Uno prints the voltage, current, power, kWh, frequency and power factor. Drag the mains sliders on the meter. The whole build, an Arduino Uno and 1 more part, runs here in your browser on the firmware below; open it in the editor to change the wiring or the code and run it again.
Teaching? Assign it to your class in one click.
Intermediate Runs in your browser. Free, and no account needed.
The parts retail for about $34. On Mokxi they're free.
The code
The firmware exactly as the editor opens it. Change a line there and press Run: it compiles in the browser.
// PZEM-004T energy monitor.
//
// The PZEM-004T v3.0 talks Modbus-RTU at 9600 baud. Its TX goes into pin 2
// and its RX comes from pin 3, through SoftwareSerial, and the PZEM004Tv30
// library does the Modbus: every reading below is one register of the meter.
//
// The meter's mains side is set on the part's sliders here. On the bench it
// is wired to live mains, which can kill: only a qualified person should
// connect one.
#include <PZEM004Tv30.h>
#include <SoftwareSerial.h>
SoftwareSerial pzemSerial(2, 3); // RX (the meter's TX), TX (the meter's RX)
PZEM004Tv30 pzem(pzemSerial);
void setup() {
Serial.begin(115200);
Serial.println("PZEM-004T energy monitor");
// The library skips any read in the first 200 ms after reset (it returns
// 0), so give it that long before the first one.
delay(250);
Serial.print("Meter address: 0x");
Serial.println(pzem.readAddress(), HEX);
}
void loop() {
float voltage = pzem.voltage();
float current = pzem.current();
float power = pzem.power();
float energy = pzem.energy();
float frequency = pzem.frequency();
float pf = pzem.pf();
if (isnan(voltage) || isnan(current) || isnan(power) || isnan(energy) || isnan(frequency) || isnan(pf)) {
Serial.println("Error reading the meter: is it on the mains?");
} else {
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("PF: "); Serial.println(pf);
}
Serial.println();
delay(2000);
}
Parts list
2 parts, plus the jumper wires. They retail for about $34; on Mokxi they're free.
How it is wired
4 connections, pin by pin, read from the circuit itself. Each line is one set of pins joined together, by a jumper wire or a breadboard strip.
- Ground: Arduino Uno R3 pin GND; AC energy meter, PZEM-004T v3.0 pin GND
- Arduino Uno R3 pin 3; AC energy meter, PZEM-004T v3.0 pin RX
- Arduino Uno R3 pin 2; AC energy meter, PZEM-004T v3.0 pin TX
- Arduino Uno R3 pin 5V; AC energy meter, PZEM-004T v3.0 pin 5V
Change it and keep it
Open it in the editor, change the circuit or the code, and keep your version in a free account.