Merging two codes for PZEM004T and DHT 22

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,