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.