BLYNK
HOME       📲 GETTING STARTED       📗 DOCS       ❓HELP CENTER       👉 SKETCH BUILDER

Merging two codes for PZEM004T and DHT 22

Please somebody guide me to merge these two codes for PZEM004T and DHT 22 to work on single ESP8266.
Code for PZEM

#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

WiFi.mode(WIFI_STA);
#if defined(USE_LOCAL_SERVER)
  WiFi.begin(ssid, pass);
  Blynk.config(AUTH, server, port);
#else
  Blynk.begin(AUTH, ssid, pass);
#endif
  while (Blynk.connect() == false) {}
  ArduinoOTA.setHostname(OTA_HOSTNAME);
  ArduinoOTA.begin();

//  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(){
Blynk.run();
//ArduinoOTA.handle();
//timer.run();

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);
Serial.println("====================================================");

updateBlynk();
  delay(1000);
}

Code for DHT22

#define BLYNK_PRINT Serial
 
 
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <DHT.h>
 
// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "Your-Auth-Token";
 
// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "Your-Wifi-Name";
char pass[] = "Your-Wifi-Password";
 
#define DHTPIN 0          // D3
 
// Uncomment whatever type you're using!
#define DHTTYPE DHT11     // DHT 11
//#define DHTTYPE DHT22   // DHT 22, AM2302, AM2321
//#define DHTTYPE DHT21   // DHT 21, AM2301
 
DHT dht(DHTPIN, DHTTYPE);
BlynkTimer timer;
 
// This function sends Arduino's up time every second to Virtual Pin (5).
// In the app, Widget's reading frequency should be set to PUSH. This means
// that you define how often to send data to Blynk App.
void sendSensor()
{
  float h = dht.readHumidity();
  float t = dht.readTemperature(); // or dht.readTemperature(true) for Fahrenheit
 
  if (isnan(h) || isnan(t)) {
    Serial.println("Failed to read from DHT sensor!");
    return;
  }
  // You can send any value at any time.
  // Please don't send more that 10 values per second.
  Blynk.virtualWrite(V5, t);
  Blynk.virtualWrite(V6, h);
}
 
void setup()
{
  // Debug console
  Serial.begin(9600);
 
  Blynk.begin(auth, ssid, pass);
  // You can also specify server:
  //Blynk.begin(auth, ssid, pass, "blynk-cloud.com", 8442);
  //Blynk.begin(auth, ssid, pass, IPAddress(192,168,1,100), 8442);
 
  dht.begin();
 
  // Setup a function to be called every second
  timer.setInterval(1000L, sendSensor);
}
 
void loop()
{
  Blynk.run();
  timer.run();
}

Why don’t you show the already working PZEM code you achieved last time to start with:

and

It’s better to save other people some precious time.

The main issues i faced was not because the code itself.
After i installed software serial library, downgraded the Arduino core to 2.4.2 and removed the level shifter,connected the Pzem with board directly with 5V to VV of ESP and ground to G ,RX & TX with D5 and D6 of ESP.
All the codes(the one you suggested as well) started to give results.
The codes I have implemented successfully are stated below.

#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

WiFi.mode(WIFI_STA);
#if defined(USE_LOCAL_SERVER)
  WiFi.begin(ssid, pass);
  Blynk.config(AUTH, server, port);
#else
  Blynk.begin(AUTH, ssid, pass);
#endif
  while (Blynk.connect() == false) {}
  ArduinoOTA.setHostname(OTA_HOSTNAME);
  ArduinoOTA.begin();

//  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(){
Blynk.run();
//ArduinoOTA.handle();
//timer.run();

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);
Serial.println("====================================================");

updateBlynk();
  delay(1000);
}

The one you suggested is as below

#define USE_BLYNK_WM      0       // https://github.com/khoih-prog/Blynk_WM

#include <ArduinoOTA.h>

#if USE_BLYNK_WM
#include <BlynkSimpleEsp8266_WM.h>
#else
#include <BlynkSimpleEsp8266.h>
#endif

//#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;

#if !USE_BLYNK_WM
//WiFi data
char ssid[] = "****";          //WiFi Credential
char pass[] = "****";          //WiFi Password
char server[] = "****";        //Blynk local server IP address
int port = 8080;               //Blynk local port

#define AUTH    "****"    //PZEM-004v3 Auth code for Blynk Local Server
#endif

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

#define UPDATE_INTERVAL_MS      5000

// Use 0 or 1 when you don't need to debug with many messages
#define DEBUG_LOOP              2

#define MODBUS_ID               1

void updateBlynk() 
{
  getPZEM();
 
  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);
}

uint8_t getPZEM()
{
  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));

    #if (DEBUG_LOOP > 0)
    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);
    Serial.println("====================================================");
    #endif   
  }
  #if (DEBUG_LOOP > 0)
  else
    Serial.println("PZEM: can't get data");
  #endif
  
  return result;
}

// Use this to avoid being blocked here if no WiFi
void connectWiFi(const char* ssid, const char* pass)
{
    #if (DEBUG_LOOP > 0)
    Serial.println("Connecting to " + String(ssid));
    #endif
    
    WiFi.mode(WIFI_STA);
    if (pass && strlen(pass)) 
    {
        WiFi.begin(ssid, pass);
    } else 
    {
        WiFi.begin(ssid);
    }
    int i = 0;
    while ((i++ < 30) && (WiFi.status() != WL_CONNECTED)) 
    {
        BlynkDelay(500);
    }

    #if (DEBUG_LOOP > 0)
    if (WiFi.status() == WL_CONNECTED)
      Serial.println("Connected to " + String(ssid));
    else
      Serial.println("Can't connect to " + String(ssid));
    #endif
}

void connectWiFiAndBlynk()
{
  if (WiFi.status() != WL_CONNECTED)
  {
    connectWiFi(ssid, pass);  
  }
  else
  {
    #if (DEBUG_LOOP > 0)
    Serial.println("Trying connecting to BlynkServer " + String(server));
    #endif
    Blynk.connect();

    if (Blynk.connected())
    {
      #if (DEBUG_LOOP > 0)
      Serial.println("Connected to BlynkServer " + String(server));
      #endif
    }     
  }
}

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

  #if USE_BLYNK_WM
    Blynk.begin();
  #else
    // Use this to avoid being blocked here if no WiFi
    //connectWiFi(ssid, pass);
    Blynk.config(AUTH, server, port);

    connectWiFiAndBlynk();
    //Blynk.connect();
  #endif  
    
  ArduinoOTA.setHostname(OTA_HOSTNAME);
  ArduinoOTA.begin();
  timerTask1 = timer.setInterval(UPDATE_INTERVAL_MS, updateBlynk);
}

void loop()
{
  if (Blynk.connected())
  {
    Blynk.run();
  }
  else
  {
    connectWiFiAndBlynk();
  }
  
  ArduinoOTA.handle();
  timer.run();  
}

After testing for continous 2 weeks, I believe the V03 of PZEM004T dont need any modification to run with ESP8266.

Sorry for misunderstanding. But IMHO, I still think that you have to fix your loop() and remove the unwanted delay().

The delay() function must be used only when it’s absolutely necessary, as it’s a waste of CPU power (unless we use it as a CPU cooler :slight_smile: ). It can create problem when we are least expected.
You can see the effect of it on the system, especially on software timers in:

Unless you’re using a preemptive multi-tasking OS, the delay() monopolizes the CPU power, yet doing nothing. It deprives all other tasks the neccessary execution to perform normally. You can try a longer delay() in the loop() and see its unwanted effect, such as Blynk disconnection, etc…

Anyway, hereafter is the suggested code to merge DHT into PZEM:

#define USE_BLYNK_WM      0       // https://github.com/khoih-prog/Blynk_WM

#include <ArduinoOTA.h>

#if USE_BLYNK_WM
#include <BlynkSimpleEsp8266_WM.h>
#else
#include <BlynkSimpleEsp8266.h>
#endif

//#include <SimpleTimer.h>
#include <ModbusMaster.h>
#include <ESP8266WiFi.h>
#include "settingsPZEM.h"

#include <DHT.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;

BlynkTimer timer;

#if !USE_BLYNK_WM
//WiFi data
char ssid[]   = "****";           //WiFi Credential
char pass[]   = "****";           //WiFi Password
char server[] = "****";           //Blynk local server IP address
int port      = 8080;             //Blynk local port

char auth[]   = "****";           //PZEM-004v3 Auth code for Blynk Local Server
#endif


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

#define UPDATE_INTERVAL_MS      5000

// Use 0 or 1 when you don't need to debug with many messages
#define DEBUG_LOOP              2

#define MODBUS_ID               1

#define DHTTYPE     DHT11     // DHT 11
//#define DHTTYPE     DHT22   // DHT 22, AM2302, AM2321
//#define DHTTYPE     DHT21   // DHT 21, AM2301

#define DHTPIN        D2        // Using pin D2 for DHTxx

DHT dht(DHTPIN, DHTTYPE);

// Change according to your Blynk App design 
#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

#define DHT_TEMP                  V7
#define DHT_HUMIDITY              V8 

float humidDHT;
float tempDHT;

// This function sends Arduino's up time every second to Virtual Pin (5).
// In the app, Widget's reading frequency should be set to PUSH. This means
// that you define how often to send data to Blynk App.
void readSensor()
{
  float h  = dht.readHumidity();
  float t  = dht.readTemperature(); // or dht.readTemperature(true) for Fahrenheit
 
  if (isnan(h) || isnan(t)) 
  {
    Serial.println("Failed to read from DHT sensor!");
    return;
  }

  humidDHT  = h;
  tempDHT   = t;
}

void updateBlynk() 
{
  getPZEM();

  readSensor();
 
  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);

  Blynk.virtualWrite(DHT_TEMP, tempDHT);
  Blynk.virtualWrite(DHT_HUMIDITY, humidDHT);
}

uint8_t getPZEM()
{
  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));

    #if (DEBUG_LOOP > 0)
    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);
    Serial.println("====================================================");
    #endif   
  }
  #if (DEBUG_LOOP > 0)
  else
    Serial.println("PZEM: can't get data");
  #endif
  
  return result;
}

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

  dht.begin();
  Serial.println("Started DHT");
  
  #if USE_BLYNK_WM
    Blynk.begin();
  #else
    WiFi.begin(ssid, pass);
    
    #if USE_LOCAL_SERVER
      Blynk.config(auth, server, BLYNK_HARDWARE_PORT);
    #else
      Blynk.config(auth);
    #endif
    
    Blynk.connect();
    if ( Blynk.connected())
      Serial.println("Connected to Blynk");   
  #endif
    
  ArduinoOTA.setHostname(OTA_HOSTNAME);
  ArduinoOTA.begin();
  
  timer.setInterval(UPDATE_INTERVAL_MS, updateBlynk);
}

void loop()
{
  Blynk.run();  
  timer.run();
  ArduinoOTA.handle();
}

Certainly, you can do it your way, and use this as an example how to merge.

Good luck again,

Bundle of thanks again, worked like a charm.