PZEM-004T v3.0 and NodeMCU / Wemos Mini running on Blynk - How To procedure

+ =


The purpose of this project is to have PZEM-004T v3.0 connect to NodeMCU or Wesmo Mini D1 to display data on the Blynk app. (using local Blynk server)

This project is cheap to make and fun to build.
PZEM cost $4.33 (AliExpress)
Wemos D1 cost $2.3 (Ebay)

First: make a wiring connection for PZEM-004 v3.0 and ESP8266: (either NodeMCU and Wesmo; I personally preferred Wesmos as it’s small and compact)

  1. ESP8266 5V ==> PZEM 5V
  2. ESP8266 G ==> PZEM GND
  3. ESP8266 Rx ==> PZEM D6
  4. ESP8266 Tx ==> PZEM D5

Second: make a AC Voltage wiring connection: (Warning: you are dealing with high voltage that can kill you, so be extra careful with this as I have no responsibility for this)
See product manual for AC voltage wiring connection

Third: Download Blynk App to your phone, create new project and generate an Authorization code

Fourth: Program the ESP8266

  1. Create a new project; download and paste the below code to your Arduino project: (make sure to update your WiFI SSID, WiFi password; Blynk app authorization key)
#include <ArduinoOTA.h>
#include <BlynkSimpleEsp8266.h>
#include <SimpleTimer.h>
#include <ModbusMaster.h>
#include <ESP8266WiFi.h>
#include "settingsPZEM.h"

#include <SoftwareSerial.h>  //  ( NODEMCU ESP8266 )
SoftwareSerial pzem(D5,D6);  // (RX,TX) connect to TX,RX of PZEM for NodeMCU
//SoftwareSerial pzem(D7,D8);  // (RX,TX) connect to TX,RX of PZEM
#include <ModbusMaster.h>
ModbusMaster node;
SimpleTimer timer;

//WiFi data
char ssid[] = "Put your WiFi SSID here";                    //WiFi Credential
char pass[] = "Put your WiFi password here";              //WiFi Password
char server[] = "Put your Blynk local server IP address here";         //Blynk local server IP address
int port = 8080;                        //Blynk local port
#define USE_LOCAL_SERVER                //Use local Blynk Server - comment-out if use Blynk hosted cloud service
#define AUTH    "put your Blynk App Authorization code here"    //PZEM-004v3 Auth code for Blynk Local Server

int timerTask1;
double U_PR, I_PR,  P_PR,  PPR, PR_F, PR_PF, PR_alarm;
uint8_t result;  uint16_t data[6];

void setup(){
  Serial.begin(115200); Serial.println("Start serial"); pzem.begin(9600); Serial.println("Start PZEM serial");
node.begin(1, pzem);  Serial.println("Start PZEM"); // 1 = ID MODBUS

#if defined(USE_LOCAL_SERVER)
  WiFi.begin(ssid, pass);
  Blynk.config(AUTH, server, port);
  Blynk.begin(AUTH, ssid, pass);
  while (Blynk.connect() == false) {}

//  timerTask1 = timer.setInterval(1000, updateBlynk);


void updateBlynk() {
  Blynk.virtualWrite(vPIN_VOLTAGE,               U_PR);
  Blynk.virtualWrite(vPIN_CURRENT_USAGE,         I_PR);
  Blynk.virtualWrite(vPIN_ACTIVE_POWER,          P_PR);
  Blynk.virtualWrite(vPIN_ACTIVE_ENERGY,         PPR);
  Blynk.virtualWrite(vPIN_FREQUENCY,             PR_F);
  Blynk.virtualWrite(vPIN_POWER_FACTOR,          PR_PF);
  Blynk.virtualWrite(vPIN_OVER_POWER_ALARM,      PR_alarm);

void loop(){;

result = node.readInputRegisters(0x0000, 10);
  if (result == node.ku8MBSuccess)  {
U_PR      = (node.getResponseBuffer(0x00)/10.0f);
I_PR      = (node.getResponseBuffer(0x01)/1000.000f);
P_PR      = (node.getResponseBuffer(0x03)/10.0f);
PPR       = (node.getResponseBuffer(0x05)/1000.0f);
PR_F      = (node.getResponseBuffer(0x07)/10.0f);
PR_PF     = (node.getResponseBuffer(0x08)/100.0f);
PR_alarm  = (node.getResponseBuffer(0x09));  

    Serial.print("U_PR:     "); Serial.println(U_PR);   // V
    Serial.print("I_PR:     "); Serial.println(I_PR,3);   //  A
    Serial.print("P_PR:     "); Serial.println(P_PR);   //  W 
    Serial.print("PPR:      "); Serial.println(PPR,3);   // kWh
    Serial.print("PR_F:     "); Serial.println(PR_F);    // Hz
    Serial.print("PR_PF:    "); Serial.println(PR_PF);  
    Serial.print("PR_alarm: "); Serial.println(PR_alarm,0);

  1. Setting.h: Download the code below to your project and save it as “settingsPZEM.h” (make sure both project_name.ino and settingsPZEM.h are in the same folder location)
//#include <wifi_credentials.h>
// Remove below 2 lines when use Blynk hosted server, 
//#define USE_LOCAL_SERVER       
//#define SERVER                          IPAddress(192,168,1,20)
  Over The Air Hostname  
#define OTA_HOSTNAME                    "PZEM-004v3"
   Virtual Pins - Base
#define vPIN_VOLTAGE		            V0
#define vPIN_CURRENT_USAGE          V1
#define vPIN_ACTIVE_POWER           V2
#define vPIN_ACTIVE_ENERGY          V3
#define vPIN_FREQUENCY              V4
#define vPIN_POWER_FACTOR           V5
#define vPIN_OVER_POWER_ALARM       V6

   Debug. Change to 0 when you are finished debugging.
const int debug             =           1; 
  1. Upload project: From Arduino, save the project and upload it to PZEM004 (make sure the Arduino set to the correct COM port with correct board as shown below)

  2. Blynk App: Go to Blynk app on your phone and layout the blynk project with virtual pin number according to the settings.h above.

  3. Run and Enjoy:


Could this damage esp8266 pin. 5V vs 3V3?

In theory yes, you should use a level shifter, but in practice ESP8266/NodeMCUs are 5v tolerant on the logic level pins.
However, what you shouldn’t do is to try applying 5v to the pin labelled 3.3v


1 Like

7 posts were split to a new topic: Want to use PZEM controller to detect current flow direction

A post was split to a new topic: Energy question