Wemos D1 Minis losing Wifi

My Wemos D1 Mini and Mini-lite-based controllers are losing Wifi connectivity after a few hours. Sometimes, they come back online quickly, sometimes it takes hours or even a reset. Are these boards known to be flaky as RSSI drops off? (I know there are knockoffs but at least two of them seemed legit).

Any best practices to a quick recovery with the Blynk library? Any way to debug? I would monitor them on serial with Blynk and Serial library debugging turned on, and they would just flap without much useful information (except maybe that the BlynkSimpleEsp8266_SSL was hitting a self-signed cert.

Here’s an example of a couple of them dropping off in an RSSI/availability chart:

Looks like I’m not the only one that’s hit this (Blynk and MQTT with Garage Door Controller being just one example).

1 Like

I use quite a few D1 Minis (all knock-offs as far as I can tell) and don’t have any major issues.

The one time I did have a problem it turned-out to be caused by a dodgy wireless access point that eventually killed all of my network.

Here’s a good example of a re-connection routine:

If signal strength is an issue then you could go for a D1 Mini Pro with an external antenna. Make sure you turn the zero ohm SMD resistor around to activate the external connection though.

Pete.

1 Like

I’m pretty sure the serial debug would give you some directions. I have been using those for ages and have no problems like you described.

Does the same thing happens without using SSL?

You can always reset your board if WiFi is not connected as a last resource.

That is a good point… I think that due the encryption overhead, SSL is better suited to devices with more horsepower, like the ESP32 and RPi (as a client)

I don’t want to run my own server and I won’t be using a non-SSL cloud service, so alas, that’s not really an option.

I think the software WDT should do the trick, though – if it goes out to lunch for too long, it should just go through a quick restart cycle and be back in business. I’ll try that next. I guess moving to ESP32s with off-board antennas would be the next move, but I’d love to not solder brand new circuits (they’re not on breadboards).

Maybe just adding the re-connection routine as suggested by @PeteKnight (and written by @Gunner), and boosting your WiFi signal (move router, better antenna on router, WiFi signal booster, etc,) would solve the problem. I run a few D1 Minis as well and don’t have any connection issues, My WiFi signal strength tends to hover around -50dbm.

You can also get your signal strength through code, and display it on BLYNK.

Blynk.virtualWrite(V10, WiFi.RSSI()); //signal strength on V10

Who knows maybe the issue is not with your ESP, but with your router or Internet Service Provider. As when I do have issues with my ESP dropping connection, I tend to see the drop on all my connected devices (smart TV, tablets, etc.).

@Toro_Blanco as shown in the chart, the worst RSSI is >-70. Only the ESPs blip and there’s never a network-wide event (so I don’t think it’s the internet connection). I also tried another router.

I’m thinking this a non-network layer root cause. The chances of an ESP losing connection are best right after it either receives a BLYNK_WRITE event or a digital input/output is toggled (e.g., when it’s most important to retain connectivity).

I don’t know if this is a good solution, but it appears to work for me. I run a timer (approx 10 sec) which checks that Blynk is connected and if it isn’t, it starts the Blynk.connect() (and increments a counter to tell me that it has had to reconnect). In the past 24 hrs, Blynk.connect() has been called three times.

I do the same thing for Wifi connection, by calling another timed function to reconnect the wifi if it is not connected (also with an incremental counter to alert me for occurrences).

My only current problem is that when my router is turned off and restarted, none of my ESP32 devices reconnect to the access point. Haven’t figured that out yet.

Looks like it’s beyond just losing connectivity – I added an LED flashing timer and that stops flashing when it goes offline. I added a soft WDT, so we’ll see if at least catches the event and restarts. My code is so basic that I doubt it’s anywhere in mine, so I’m suspecting a library.

The most suspect is executing ArduinoOTA.handle(); before Blynk.run();. Any best practices on ordering between the two? I could have sworn that OTA doesn’t work in the opposite order.

#include <Arduino.h>
#include <ArduinoOTA.h>
#include <BlynkSimpleEsp8266_SSL.h>
#include <ESP8266WiFi.h>

char auth[] = "foo"; // Entrance
const char *hostname = "esp-entrance";

#include "../../common/common.cpp"

#define BUZZER_PIN 4       // D2
#define REED_SWITCH_PIN 14 // D5
#define BUZZER_TIME 3000L
#define V_DOOR V1
#define V_BUTTON_BUZZER V3

void unlock_entrance() {
    Serial.println("Unlocking entrance");

    digitalWrite(BUZZER_PIN, HIGH);
}

void lock_entrance() {
    Serial.println("Locking entrance");

    digitalWrite(BUZZER_PIN, LOW);
}

void init_pins() {
    pinMode(LED_BUILTIN, OUTPUT);
    digitalWrite(LED_BUILTIN, LOW);

    pinMode(BUZZER_PIN, OUTPUT);
    lock_entrance(); // If stuck, this will turn off the entrance buzzer upon restart

    pinMode(REED_SWITCH_PIN, INPUT_PULLUP);
}

void warn_door_open() {
    int is_door_closed = digitalRead(REED_SWITCH_PIN);

    if (!is_door_closed) {
        Serial.println("THE ENTRANCE GATE HAS BEEN LEFT OPEN!");
        Blynk.notify("⚠️ THE ENTRANCE GATE HAS BEEN LEFT OPEN!");

        blynk_timer.setTimeout(60 * 60 * 1000, warn_door_open); // check again every hour until it's closed
    }
}

void send_reed_switch_state() {
    int is_door_closed = digitalRead(REED_SWITCH_PIN);
    Serial.println("Is entrance closed: " + String(is_door_closed));

    Blynk.virtualWrite(V_DOOR, is_door_closed);

    if (!is_door_closed) {
        blynk_timer.setTimeout(60 * 1000, warn_door_open); // check back in a minute
    }
}

BLYNK_WRITE(V_BUTTON_BUZZER) {
    int pushed = param.asInt();
    if (pushed) {
        Serial.println("Buzzer button pushed");

        unlock_entrance();

        blynk_timer.setTimeout(BUZZER_TIME, []() { // Lambda Reconnection Timer Function
            lock_entrance();
        });
    }
}

BLYNK_APP_CONNECTED() {
    Serial.println("Blynk App Connected.");

    send_reed_switch_state(); // in case of a stuck state
}

BLYNK_CONNECTED() {
    Serial.println("Connected to Blynk Server");

    send_reed_switch_state(); // in case of a stuck state
}

BLYNK_DISCONNECTED() {
    Serial.println("Disconnected from Blynk Server.");
}

void setup() {
    init_pins();

    init_common();

    send_reed_switch_state();
    attachInterrupt(digitalPinToInterrupt(REED_SWITCH_PIN), send_reed_switch_state, CHANGE);

    init_ota();

    Serial.println("Initialized");
}

void loop() {
    ArduinoOTA.handle();

    Blynk.run();

    blynk_timer.run();
}

common.cpp:

#define V_RSSI V10
#define V_UPTIME V11

#define STATS_INTERVAL 1000L
#define WDT_INTERVAL 10000L

char ssid[] = "foo";
char pass[] = "bar";

BlynkTimer blynk_timer;

void init_ota() {
    Serial.println("Initializing OTA...");

    ArduinoOTA.setHostname(hostname);

    ArduinoOTA.begin();
}

void send_stats() {
    int rssi = WiFi.RSSI();
    Serial.println("RSSI: " + String(rssi));
    Blynk.virtualWrite(V_RSSI, rssi);

    int uptime = millis() / 1000 / 60 / 60; // in hours
    Blynk.virtualWrite(V_UPTIME, uptime);

    digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); // blink onboard LED

    ESP.wdtFeed();
}

void init_common() {
    Serial.println("Initializing network code...");

    wdt_enable(WDTO_8S); // Restart ESP after going to the Bahamas for 8 seconds

    Serial.begin(115200);
    Serial.setDebugOutput(true);

    WiFi.begin(ssid, pass);
    Blynk.config(auth);
    Blynk.connect();

    pinMode(LED_BUILTIN, OUTPUT);
    digitalWrite(LED_BUILTIN, HIGH);

    blynk_timer.setInterval(STATS_INTERVAL, send_stats);
}
1 Like

No library issues that I have noticed on any of my constantly running projects… but then I do NOT use SSL due to the overhead issue on a lowly ESP8266

I have this running in my void loop() on a Wemos D1 powered Solar Charge Monitor… runs 24/7… only resetting when I am swapping the battery or something.

  timer.run();
  ArduinoOTA.handle();  // For OTA
  if (Blynk.connected()) {  // If connected run as normal
    Blynk.run();
  } else if (ReCnctFlag == 0) {  // If NOT connected and not already trying to reconnect, set timer to try to reconnect in 30 seconds
    ReCnctFlag = 1;  // Set reconnection Flag
    timer.setTimeout(30000L, []() {  // Lambda Reconnection Timer Function
      ReCnctFlag = 0;  // Reset reconnection Flag
      Blynk.connect();  // Try to reconnect to the server
    });  // END Timer Function
  }

As shown above, I run this script with OTA 1st, Blynk.run 2nd… but I have others (including a few Sonoff Basics) that work the other way… no notable issues either way that I can recall, and the Sonoffs are always running, even without any reconnection checks.

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

How frequently is the D1 Mini going offline?

I have an SSL connection and the D1 reboots after a day or two. For me I think it might be a memory leak in the ESP8266 core libraries for SSL. On reboot I have free RAM of 16500 but this slowly drops to 13500 over a day or so.

My D1 simply reboots and everything continues just fine. I believe the core developers have been migrating to BearSSL from axTLS but I’m not sure what the latest status is. I am certainly still using axTLS.

See the end of this GitHub thread regarding axTLS memory usage etc. BearSSL::WiFiClientSecure not working the same way axTLS did · Issue #4738 · esp8266/Arduino · GitHub

As others have pointed out SSL + Blynk + ESP8266 is working close to the limits. Or it is with axTLS but I believe memory usage is much better with BearSSL.

2 Likes

Coming back to this thread, the problem continues on 4 ESP8266s sharing common code. It’s more prominent on one that is doing a little more work than the others.

I’ve gotten desperate and refactored to not use SSL. Same thing happens. I played with a bunch of watchdog code, but it just fires the watchdog.

I even refactored and uploaded to an ESP32. The ESP32 does better, but it still goes offline regularly. I’m starting to think it’s hardware – either noisy mains power or something with the output circuit. D5 (GPIO2) on the D1 Mini is driving a solid state relay directly, so there’s not much to the circuit. It could also be an obscure library bug but I would see it here in the forums if it was new.

I’ll post code once I scrub it of keys.

To close the loop on this, the fix was ditching the ESP8266s and replacing with ESP32s.

I tried many hours of different directions: TLS/no TLS, optimizing heap space to avoid String operations, lots od diag messages, but nothing helped. The ESP32s almost never lose connectivity to the service and, if they do, they reconnect quickly.

Alas, this one will remain a mystery.

ESP8266 doesn’t have the same horsepower for SSL as the ESP32… thus lower stability when running such.

But we can mark this as solved I guess :slight_smile:

Hey @Gunner, as mentioned, I tried non-TLS with the ESP8266, so that wasn’t the issue.