Wemos D1 mini (ESP8266) does not re-connect to WiFi

One of my Wemos’ does not want to reconnect after dropping Wifi (router issue). I would appreciate any insights as to why this is happening.

I myself think it is probably getting stuck in the reconnect() function,
i.e. void loop checks connection to MQTT, which would be offline if WiFi is down, calls reconnect() function, which just loops until a connection to MQTT server is established (which it won’t be until wifi is reconnected).

Is that correct?

Here is the full code:

//v002 MQTT Garage and garden weather monitor with LCD screen
//2 x SHT30's, 1 xLolin HP303B 


#include <LOLIN_HP303B.h>    
#include <Adafruit_GFX.h>    
#include <Adafruit_ST7735.h>
#include <WEMOS_SHT3X.h>   
#include <ESP8266WiFi.h>
#include <Wire.h>
#include <PubSubClient.h>
#include <SimpleTimer.h>

#include <ESP8266mDNS.h>  //for OTA updates
#include <WiFiUdp.h>     //for OTA updates
#include <ArduinoOTA.h>  //for OTA updates

#define TFT_RST -1 //for TFT I2C Connector Shield V1.0.0 and TFT 1.4 Shield V1.0.0
#define TFT_CS D4  //for TFT I2C Connector Shield V1.0.0 and TFT 1.4 Shield V1.0.0
#define TFT_DC D3  //for TFT I2C Connector Shield V1.0.0 and TFT 1.4 Shield V1.0.0


//Setup display name as tft
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);

// HP303B pressure and temperature sensor setup
LOLIN_HP303B HP303BPressureSensor;
int32_t temperature;
int32_t pressure;
int16_t oversampling = 7;
int16_t ret;
int pressure_offset = 19;  

//Setup SHT30 temp and humidity sensors
SHT3X garage(0x45);    
SHT3X garden(0x44); 
float temp_garden_offset = 0; 

//Setup Wifi & MQTT credentials
#define wifi_ssid "SSID"
#define wifi_password "PASSWORD"
//
#define mqtt_server "192.168.1.xx"
#define mqtt_user "USER"
#define mqtt_password "PASSWORD"
//
#define temperature_garage_topic "garage/sensor/temperature"
#define humidity_garage_topic "garage/sensor/humidity"
#define pressure_garage_topic "garage/sensor/pressure"
//
#define temperature_garden_topic "garden/sensor/temperature"
#define humidity_garden_topic "garden/sensor/humidity"
//
#define heartbeat_topic "garage/wemos/heartbeat"
#define freeram_topic "garage/wemos/freeram"

WiFiClient espClient;
PubSubClient client(espClient);

long rssi; //  setup variable for RSSI heartbeat value
char *client_id = "Wemos_no_4_MQTT_Garage_Garden_Weather";  

SimpleTimer timer; // simple timer for heartbeat



void setup()
{
  // Add support for OTA***************************************
  ArduinoOTA.onError([](ota_error_t error) {
    ESP.restart();
  });
  ArduinoOTA.setHostname(client_id);
  ArduinoOTA.begin();  /* setup the OTA server */
  // **********************************************************

  Serial.begin(115200);
  setup_wifi();  // calls wifi setup function
  client.setServer(mqtt_server, 1883);

  while (!Serial) {} // Wait

  //Setup timers
  timer.setInterval(5000L, heartbeat);  //timer for heartbeat RSSI
  delay (2500); // space out functions
  timer.setInterval(5000L, sendSensor); //timer for reading sensors


  //Initial setup TFT screen
  tft.initR(INITR_144GREENTAB); 
  tft.setTextWrap(false); 
  tft.setRotation(3);         
  tft.fillScreen(ST77XX_BLACK); 
  tft.setTextSize(2);           
  tft.setTextColor(ST77XX_WHITE);
  tft.setCursor(0, 0);
  tft.println("Garage");
  tft.setCursor(0, 64);
  tft.println("Garden");

  HP303BPressureSensor.begin(); //starts HP303B sensor
}


void setup_wifi() {
  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(wifi_ssid);

  WiFi.begin(wifi_ssid, wifi_password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}


void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    // If you do not want to use a username and password, change next line to
    // if (client.connect("ESP8266Client")) {
    if (client.connect(client_id, mqtt_user, mqtt_password)) {
      Serial.println("connected");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}


void heartbeat()  // function for heartbeat check
{
  Serial.print("RSSI:");
  Serial.println(WiFi.RSSI());
  client.publish(heartbeat_topic, String(WiFi.RSSI()).c_str(), true);
  client.publish(freeram_topic, String(ESP.getFreeHeap()).c_str(), true);
}



void sendSensor()
{
  //Setup variables garage
  float temp_garage = (garage.cTemp);
  int hum_garage = (garage.humidity);
  //Setup variables garden
  float temp_garden = (garden.cTemp);
  int hum_garden = (garden.humidity);

  if (garage.get() == 0)  //garage sensor is responding
  {
    //Write garage temp
    tft.setTextColor(ST7735_GREEN, ST7735_BLACK); 
    tft.setCursor(0, 16);
    tft.print("Temp:");
    tft.print(String(temp_garage, 1));
    tft.print("c");
    //
    Serial.print("Garage temperature:");
    Serial.println(String(temp_garage).c_str());
    client.publish(temperature_garage_topic, String(temp_garage , 1).c_str(), true);
    //
    //Write garage humidity
    tft.setTextColor(ST7735_CYAN, ST7735_BLACK);  
    tft.setCursor(0, 32);
    tft.print("Humid:");
    tft.print(int(hum_garage));  
    tft.print("%");
    //
    Serial.print("Garage humidity:");
    Serial.println(String(hum_garage).c_str());
    client.publish(humidity_garage_topic, String(hum_garage).c_str(), true);
  }
  else  //garage sensor is not responding
  {
    tft.setTextColor(ST7735_RED, ST7735_BLACK);  
    tft.setCursor(0, 16);
    tft.print("Error in");
  }


  //Read the garden SHT30 sensor
  //if (isnan(hum_garden) || isnan(temp_garden))
  //if (hum_garden == 0 || hum_garden > 100)

  if (garden.get() == 0)  //garden sensor is responding
  {
    //Write garden temp
    tft.setTextColor(ST7735_GREEN, ST7735_BLACK);  /
    tft.setCursor(0, 80);
    tft.print("Temp:");
    tft.print(String((temp_garden + temp_garden_offset), 1));  
    tft.print("c "); 
    //
    Serial.print("Garden temperature:");
    Serial.println(String(temp_garden).c_str());
    client.publish(temperature_garden_topic, String(temp_garden , 1).c_str(), true);
    //
    //Write garden humidity
    tft.setTextColor(ST7735_CYAN, ST7735_BLACK);  
    tft.setCursor(0, 96);
    tft.print("Humid:");
    tft.print(int(hum_garden));
    tft.print("%");
    //
    Serial.print("Garden humidity:");
    Serial.println(String(hum_garden).c_str());
    client.publish(humidity_garden_topic, String(hum_garden).c_str(), true);
  }
  else  //garden sensor is not responding
  {
    tft.setTextColor(ST7735_RED, ST7735_BLACK);  
    tft.setCursor(0, 80);
    tft.print("Error out");
  }


  //Read garage Wemos shield HP303B pressure sensor
  ret = HP303BPressureSensor.measurePressureOnce(pressure, oversampling);

  if (ret != 0)   //if sensor returns anything other than 0 (where 0=successfull read)
  {
    //Something went wrong.
    //Look at the library code for more information about return codes
    tft.setTextColor(ST7735_RED, ST7735_BLACK);   
    tft.setCursor(0, 112);
    tft.print("mBar Error");
  }
  else
  {
    //Write garage pressure values
    tft.setTextColor(ST7735_YELLOW, ST7735_BLACK); 
    tft.setCursor(0, 112);
    tft.print("mBar:");
    tft.print((pressure / 100) + pressure_offset); 
    tft.print("  ");  
    //
    Serial.print("Garage pressure:");
    Serial.println(String((pressure / 100) + pressure_offset).c_str());
    client.publish(pressure_garage_topic, String((pressure / 100) + pressure_offset).c_str(), true);
  }

}



void loop() {

  // Add support for OTA***************************************
  ArduinoOTA.handle();
  // **********************************************************

  timer.run(); //  initiates SimpleTimers

  if (!client.connected())
  {
    reconnect();
  }
  client.loop();
}

Previous message too long to add more :o

If my above thoughts are correct, would the fix be to call setup_wifi() if client not connected?

i.e.

void loop() {

  // Add support for OTA***************************************
  ArduinoOTA.handle();
  // **********************************************************

  timer.run(); //  initiates SimpleTimers

  if (!client.connected())
  {
    setup_wifi();  // reconnect to wifi first
    reconnect();  // then reconnect to the MQTT broker
  }
  client.loop();
}

the WiFi.setAutoReconnect option is persistent (remembered on flash)
https://arduino-esp8266.readthedocs.io/en/latest/esp8266wifi/station-class.html#setautoreconnect

Thank you I will take a look at that now :slight_smile:

@Juraj I have done some reading (that was a very useful link!) and it seems that the WiFi should auto reconnect by itself by default:

"By default, ESP will attempt to reconnect to Wi-Fi network whenever it is disconnected. There is no need to handle this by separate code"

I'm sure you were aware of that! So I am wondering if that can be the issue as I have not made any changes.

I've just tried rebooting my Access Point and it did reconnect fine, I'm wondering if there is some bug in my code which is causing it to lock up somewhere?

Would appreciate if someone could have a scan through and see if it jumps out :blush: