Is there a good & bad version of MQTT for ESP devices?

Hi all,

I’m just getting used to running ESP8266 boards as remote climate monitors around the home but finding they seem to stop running at odd intervals.

The device does not drop off the WiFi but just seems to stop sending data via MQTT. A reboot fixes it but I was wondering if the sketch I’m running is a working one or not as I really don’t know much about these little devices yet.

This is the sketch…

/*
 *     Maker      : DIYSensors                
 *     Project    : Temp and Humidity WiFi - MQTT and OTA 
 *     Version    : 1.0
 *     Date       : 10-2024
 *     Programmer : Ap Matteman
 *     Modified by: Dave Kearley March 2026
 */    

#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
#include <PubSubClient.h>
#include <Adafruit_Sensor.h>
#include <DHT.h>
#include <DHT_U.h>
//#include "arduino_secrets.h"

int iWiFiTry = 0;          
int iMQTTTry = 0;
int signalstrength;
String sClient_id;

//DHT22 settings
#define DHTPIN 14     // Digital pin connected to the DHT sensor
#define DHTTYPE    DHT22     // DHT 22 (AM2302)
DHT_Unified dht(DHTPIN, DHTTYPE);

unsigned long lPmillis = 0;        // will store last time MQTT has published
const long lInterval = 60000; // 60000 ms => 60 Seconds for demo. You can change it to 5 minutes

//Set WiFi details here.....
const char* ssid = "xxxxxx";
const char* password = "xxxxxx";
const char* HostName = "xxxxxx";  // make this unique!

//Set MQTT Subscriptions here - MQTT topic will read as "HostName & _Temperature" or "HostName & Humidity"...
const char* TopicTemperature = "xxxxxx_Temperature";
const char* TopicHumidity = "xxxxxx_Humidity";
const char* TopicWiFi = "xxxxxxx_WiFi";

//Set MQTT broker connection here...
const char* mqtt_broker = "xxxxxxx";
const char* mqtt_user = "xxxxxx";
const char* mqtt_password = "xxxxxxx";

WiFiClient espClient;
PubSubClient MQTTclient(espClient); // MQTT Client

void setup() {
  Serial.begin(115200);
  while (!Serial) { ; }  // wait for serial port to connect. Needed for native USB port only    
  dht.begin();       
  Connect2WiFi();
  Connect2MQTT();
  pinMode(LED_BUILTIN,OUTPUT);
}

void Connect2WiFi() { 
  //Connect to WiFi
  // WiFi.mode(WIFI_STA);  //in case of an ESP32
  iWiFiTry = 0;
  WiFi.begin(ssid, password);
  WiFi.setHostname(HostName);
  Serial.print("Connecting to WiFi ");
  while (WiFi.status() != WL_CONNECTED && iWiFiTry < 11) { //Try to connect to WiFi for 11 times
    ++iWiFiTry;
    Serial.print(".");
    delay(500);
  }
  Serial.println("");
  Serial.print("Got IP: ");  Serial.println(WiFi.localIP());

  // ArduinoOTA.setPort(8266); // Port defaults to 8266
  
  ArduinoOTA.setHostname(HostName); 
  // ArduinoOTA.setPassword((const char *)OTAPassword); // You can set the password for OTA

  ArduinoOTA.onStart([]() { Serial.println("Start"); });
  ArduinoOTA.onEnd([]()   { Serial.println("\nEnd"); });
  ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
    Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
  });
  ArduinoOTA.onError([](ota_error_t error) {
    Serial.printf("Error[%u]: ", error);
    if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
    else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
    else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
    else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
    else if (error == OTA_END_ERROR) Serial.println("End Failed");
  });
  ArduinoOTA.begin();
  Serial.println("Ready");

  //Unique MQTT Device name
  sClient_id = "esp-client-" + String(WiFi.macAddress());
  Serial.print("ESP Client name: "); Serial.println(sClient_id);
}

void Connect2MQTT() {
  // Connect to the MQTT server
  iMQTTTry=0;
  if (WiFi.status() != WL_CONNECTED) { 
    Connect2WiFi; 
  }

  Serial.print("Connecting to MQTT ");
  MQTTclient.setServer(mqtt_broker, 1883);
  while (!MQTTclient.connect(sClient_id.c_str(), mqtt_user, mqtt_password) && iMQTTTry < 11) { //Try to connect to MQTT for 11 times
    ++iMQTTTry;
    Serial.print(".");
    delay(500);
  }
  Serial.println("");
}

void loop() {
  ArduinoOTA.handle();
  unsigned long lCmillis = millis();

  if (lCmillis - lPmillis >= lInterval) {
    lPmillis = lCmillis;
    if (!MQTTclient.connect(sClient_id.c_str(), mqtt_user, mqtt_password)) {
      Connect2MQTT();
    }

    //Flash the onboard LED
    digitalWrite(LED_BUILTIN,LOW);
    delay(500);
    digitalWrite(LED_BUILTIN, HIGH);

    // Get WiFi signal strength and print its value.
    signalstrength = WiFi.RSSI();
    if (isnan(signalstrength)) {
      Serial.println("Error reading signal strength!");
      MQTTclient.publish(TopicWiFi, String(-180).c_str());
    }
    else {
      Serial.print("Signal Strength: "); Serial.print(signalstrength); Serial.println("dBm");
      MQTTclient.publish(TopicWiFi, String(signalstrength).c_str());
    }

    sensors_event_t event;
    dht.temperature().getEvent(&event);
    if (isnan(event.temperature)) {
      Serial.println("Error reading temperature!");
      MQTTclient.publish(TopicTemperature, String("-180").c_str());
    //  MQTTclient.publish("Office/Sensor/TemperatureF", String("-180").c_str());
    }
    else {
      Serial.print("Temperature: "); Serial.print(event.temperature); Serial.println("°C");
      MQTTclient.publish(TopicTemperature, String(event.temperature).c_str());
    //  MQTTclient.publish("Office/Sensor/TemperatureF", String((event.temperature * 1.8) + 22).c_str());
    }
    // Get humidity event and print its value.
    dht.humidity().getEvent(&event);
    if (isnan(event.relative_humidity)) {
      Serial.println("Error reading humidity!");
      MQTTclient.publish(TopicHumidity, String(-180).c_str());
    }
    else {
      Serial.print("Humidity: "); Serial.print(event.relative_humidity); Serial.println("%");
      MQTTclient.publish(TopicHumidity, String(event.relative_humidity).c_str());
    }
    Serial.println("----------------------------");

    // If you want to reboot your device when WiFi is not working
    if (iWiFiTry > 10){
      Serial.println("REBOOTING");
      Serial.println(" Reboot in 2 seconds");
      Serial.println(""); 
      delay(2000);
      ESP.restart(); 
    }
  }
  
}

I modified it to add the WIFi signal strength to MQTT but that was about it.

Any ideas?

It might be better to get help on a dedicated Arduino forum. Very little of what I see here directly relates to the broader Home Assistant project.

Any reason you’re not using ESPHome instead?

Personally, when I was still using MQTT with ESPHome, instead of the native HA API, I had no problems, but now I’m using the native API.

Have you checked whether your device actually still gives readings (the DHT itself)? Does your broker report rhe client as connected?

1 Like

Thanks, i’ll go for Arduino help but will check the MQTT status as well, and look into ESPHome

My 8266’s drop out as described. I’ve found if you let an 8266 connect in “N” mode, it tends to zombie like that, especially with Tasmota. If you tell it to run in only ‘G’ or ‘B’ mode, it does much better. Tasmota has a switch for that, so I’m sure there is an Arduino command to handle it.
It was annoying with my older routers disconnecting every couple of weeks or so, but when I got my WIFI 7 router, it’s daily.

2 Likes

Thanks, thats interesting.

I’m just looking into ESPHome after a recommendation…

To add to that, now that I think about it more: Keep them on 2.4GHz and it might need to use a separate SSID for your 5GHz network (if you have one). Depending on gear, you could disable roaming, set a static IP or make a DHCP reservation (and avoid DNS lookups).

1 Like

Just so you know mine have always been on a separate SSID, and the ‘N’ thing still affected me. (& static address)
Francis here keyed me in to this problem.

2 Likes

Network issues are pesky, for sure. In my case everything works even though it’s a single SSID, use DNS and have no reservations. The only thing I’ve done is to fix a couple of devices to a specific AP. I’ve even seen people fiddle with channel widths.

2 Likes

This one?

Last update a few years ago? Either very stable and doesn’t need any bug fixes, or abandoned.
MQTT sits on top of your network connection.
Both ESPHome and Tasmota have pre-packaged software to enable a ESP8266 to collect and report DHT22 readings. Both are robustly updated, offer OTA updates, and might be an alternative to your Arduino code.
The MQTT Explorer addon app can be useful for monitoring inbound MQTT traffic on HomeAssistant, as well as looking at the system and MQTT error logs.
MQTT is a robust and well proven standard data interchange format. You may find your issue is network related, rather than MQTT related. ESPHome has recently made a lot of changes to attempt to improve network reliability and you may wish to experiment with their implementation that doesn’t use MQTT, which can be a burden on a ESP8266 and is not required in thw following project as it injects the data direct into HomeAssistant without using MQTT.

1 Like

Thanks for that info, I have now switched over all the new sensors to ESPHome and not MQTT, I’ll see how it all plays…