BLYNK
BLYNK.IO       📲 GETTING STARTED       📗 DOCS       ❓HELP CENTER       👉 SKETCH BUILDER

ESP8266-01 with arduino Mega disconnect when router restart

Everything is possible. But this setup is complex and I’m not the right person to ask :slight_smile:.

I didn’t think so… but I know, you know, the right one :stuck_out_tongue_winking_eye: Can you stick a bug in their ear for us poor souls that like to merge ESP/Arduino.

Guys,
Please don’t fight :disappointed::disappointed::disappointed:, l just need to know how to get benefit from these words “Failed to connect WiFi” will show up on serial moniter screen and use them when they will show up to reset the Arduino.

Thanks

?? No fighting is happening ??

As for your issue… that is exactly what we are discussing… right now I don’t think there is anything else you can really do about that error, except to manually restart the Mega, AFTER the router.

I was joking :wink::wink::wink:. What about using like serial.find or serial.read to indicate something will be show up on serial port?

Like
If ( serial.find(“Failed to connect WiFi”))
{ //do reset code
}

The problem is that your sketch is NOT running, until connected, when using Blynk.begin() Which is why all standalone ESP’s should be using the Blynk.config() method… which cannot be done (with ESP as shield) as it throws a compile error with #include <BlynkSimpleShieldEsp8266.h>.

Short of a 2nd MCU monitoring your debug serial, and thus tripping an external reset… well, I don’t see any other way of doing it on one MCU when the sketch is halted.

if (wifi->joinAP(ssid, pass)) {
            String my_ip = wifi->getLocalIP();
            BLYNK_LOG1(my_ip);
        } else {
            BLYNK_LOG1(BLYNK_F("Failed to connect WiFi"));
            return false;
        }
        BLYNK_LOG1(BLYNK_F("Connected to WiFi"));
        return true;
    }

this is from BlynkSimpleShieldEsp8266.h

this is the source of Failed to connect WiFi.

That is the source of the error message… not the root of the issue.

Keep digging into it :+1:. Maybe you can come up with a solution??

I got it :blush::blush::blush::blush::blush::blush::grinning:.
To let any ESP8266 work automatically if any wifi issues will happen we have to update the BlynkSimpleShieldEsp8266.h library as following:
1- add #include <avr/wdt.h> library inside the BlynkSimpleShieldEsp8266.h library.
2- add wdt_enable(WDTO_1S); and wdt_reset(); to connectWiFi lines as shown down:

 bool connectWiFi(const char* ssid, const char* pass)
    {
        ::delay(500);
        BLYNK_LOG2(BLYNK_F("Connecting to "), ssid);
        /*if (!wifi->restart()) {
            BLYNK_LOG1(BLYNK_F("Failed to restart"));
            return false;
        }*/
        if (!wifi->kick()) {
             BLYNK_LOG1(BLYNK_F("ESP is not responding"));
			wdt_enable(WDTO_1S);
                        wdt_reset();
             //TODO: BLYNK_LOG_TROUBLE(BLYNK_F("esp8266-not-responding"));
             return false;
        }
        if (!wifi->setEcho(0)) {
            BLYNK_LOG1(BLYNK_F("Failed to disable Echo"));
            return false;
        }
        String ver = wifi->ESP8266::getVersion();
        BLYNK_LOG1(ver);
        if (!wifi->enableMUX()) {
            BLYNK_LOG1(BLYNK_F("Failed to enable MUX"));
        }
        if (!wifi->setOprToStation()) {
            BLYNK_LOG1(BLYNK_F("Failed to set STA mode"));
            return false;
        }
        if (wifi->joinAP(ssid, pass)) {
            String my_ip = wifi->getLocalIP();
            BLYNK_LOG1(my_ip);
        } else {
            BLYNK_LOG1(BLYNK_F("Failed to connect WiFi"));
			wdt_enable(WDTO_1S);
			wdt_reset();
            return false;
        }
1 Like

Interesting approach…I will have to test that.

But why add the wdt_reset(); if the purpose is to activate the WDT when that message is called.

Both of them work together the time for reset and active the reset.

But wdt_reset();doesn’t “activate” anything, it resets the timeout… is only needed if for some reason you DON’T want the reboot to happen after the 1 second you have allotted… in fact all that it does is reset the WDT a millisecond after it is activated :stuck_out_tongue: then since it is never called again… 1 second later… reboot!

Yes, you are right now we can add only wdt_enable(WDTO_1S); to connectWiFi lines it will work very good.

My solution it will deal with three problems by reset them and all of them they will happen togather:

1- when your wifi shield was working normally and your router reset himself or internet issue, this problem it be fix be add this code to your sketch

Void checkBlynk(){  
 if(!Blynk.connected()){
    Serial.println("Not connected to Blynk server"); 
    wdt_enable(WDTO_1S);
  }
}

2- after first reset will happen and your router will not be ready, so your serial monitor will stop with this words “Failed to connect WiFi” , so now you need to keep the reset function up to your router be ready to connect so I fixed this by update the BlynkSimpleShieldEsp8266.h library through add #include <avr/wdt.h> library inside the BlynkSimpleShieldEsp8266.h library. and add wdt_enable(WDTO_1S); to these lines as shown:

 bool connectWiFi(const char* ssid, const char* pass)
    {
        ::delay(500);
        BLYNK_LOG2(BLYNK_F("Connecting to "), ssid);
        /*if (!wifi->restart()) {
            BLYNK_LOG1(BLYNK_F("Failed to restart"));
            return false;
        }*/
        if (!wifi->kick()) {
             BLYNK_LOG1(BLYNK_F("ESP is not responding"));
			 wdt_enable(WDTO_1S);
             //TODO: BLYNK_LOG_TROUBLE(BLYNK_F("esp8266-not-responding"));
             return false;
        }
        if (!wifi->setEcho(0)) {
            BLYNK_LOG1(BLYNK_F("Failed to disable Echo"));
            return false;
        }
        String ver = wifi->ESP8266::getVersion();
        BLYNK_LOG1(ver);
        if (!wifi->enableMUX()) {
            BLYNK_LOG1(BLYNK_F("Failed to enable MUX"));
        }
        if (!wifi->setOprToStation()) {
            BLYNK_LOG1(BLYNK_F("Failed to set STA mode"));
            return false;
        }
        if (wifi->joinAP(ssid, pass)) {
            String my_ip = wifi->getLocalIP();
            BLYNK_LOG1(my_ip);
        } else {
            BLYNK_LOG1(BLYNK_F("Failed to connect WiFi"));
			wdt_enable(WDTO_1S);
            return false;

3- sometime you will get this message “ESP is not responding” and this will stop your device from connecting or reset him self, so I add wdt_enable(WDTO_1S); to this line

 if (!wifi->kick()) {
             BLYNK_LOG1(BLYNK_F("ESP is not responding"));
			 wdt_enable(WDTO_1S);

to reset your device also if it will stop with “ESP is not responding”.

Finally I want to thanks Gunner because he is encourage me to fix this problem .

2 Likes

@yaamr can we ask you to enter this useful hack in the “Projects” section. I’m not a fan of the shield system but I know there are a lot that do use them and have been struggling with the issue you have fixed.

I don’t consider the Projects section to be strictly tied to the literal meaning of the word, rather something that many Blynkers might find useful.

Yes, no problem but how can I enter these projects and add it???

Just put together a relatively concise “how-to” and post a new topic with a Projects made with Blynk category.

Ok, I will.

1 Like

hello all
i tried to implement what you said above for the lossing wifi connectivity in my system (Mega + ESP8266 wifi shield) but i get compiling error in the bool connectWiFi
can you please check my code and tell me where i did something wrong as am not too much into coding , a noobie

it is mainly happened after i add the bool connectWiFi(const char* ssid, const char* pass) function before the void setup (copy and paste what u said above here), if removed it , then it works but in the serial monitor if it loses connection, i receive Failed to connect WiFi and thats it.

here is the error

base operand of’->’ has non-pointer type ESP8266’

#define BLYNK_PRINT Serial // Enables Serial Monitor
#define BLYNK_PRINT Serial
#define BLYNK_DEBUG Serial

#include <ESP8266_Lib.h>
#include <BlynkSimpleShieldEsp8266.h>
#include <WatchDog.h>
#include <avr/wdt.h>
#ifndef BlynkSimpleShieldEsp8266_h
#define BlynkSimpleShieldEsp8266_h

#ifdef ESP8266
#error This code is not intended to run on the ESP8266 platform! Please check your Tools->Board setting.
#endif

#ifndef BLYNK_INFO_CONNECTION
#define BLYNK_INFO_CONNECTION  "ESP8266"
#endif

#ifndef BLYNK_ESP8266_MUX
#define BLYNK_ESP8266_MUX  1
#endif

#define BLYNK_SEND_ATOMIC
#define BLYNK_SEND_CHUNK 40

#include <BlynkApiArduino.h>
#include <Blynk/BlynkProtocol.h>
#include <utility/BlynkFifo.h>
#include <ESP8266_Lib.h>
#include <avr/wdt.h>

if (!wifi->kick()) {
       BLYNK_LOG1(BLYNK_F("ESP is not responding"));
       wdt_enable(WDTO_1S); 
            

class BlynkTransportShieldEsp8266
{
    static void onData(uint8_t mux_id, uint32_t len, void* ptr) {
        ((BlynkTransportShieldEsp8266*)ptr)->onData(mux_id, len);
    }

    void onData(uint8_t mux_id, uint32_t len) {
        if (mux_id != BLYNK_ESP8266_MUX) {
            return;
        }
        //BLYNK_LOG2("Got ", len);
        while (len) {
            if (client->getUart()->available()) {
                uint8_t b = client->getUart()->read();
                if(!buffer.push(b)) {
                    BLYNK_LOG1(BLYNK_F("Buffer overflow"));
                }
                len--;
            }
        }
    }

public:
    BlynkTransportShieldEsp8266()
        : client(NULL)
        , status(false)
        , domain(NULL)
        , port(0)
    {}

    void setEsp8266(ESP8266* esp8266) {
        client = esp8266;
        client->setOnData(onData, this);
    }

    void begin(const char* d,  uint16_t p) {
        domain = d;
        port = p;
    }

    bool connect() {
        if (!domain || !port)
            return false;
        status = client->createTCP(BLYNK_ESP8266_MUX, domain, port);
        return status;
    }

    void disconnect() {
        status = false;
        buffer.clear();
        client->releaseTCP(BLYNK_ESP8266_MUX);
    }

    size_t read(void* buf, size_t len) {
        uint32_t start = millis();
        //BLYNK_LOG4("Waiting: ", len, " Occuied: ", buffer.getOccupied());
        while ((buffer.getOccupied() < len) && (millis() - start < 1500)) {
            client->run();
        }
        return buffer.read((uint8_t*)buf, len);
    }
    size_t write(const void* buf, size_t len) {
        if (client->send(BLYNK_ESP8266_MUX, (const uint8_t*)buf, len)) {
            return len;
        }
        return 0;
    }

    bool connected() { return status; }

    int available() {
        client->run();
        //BLYNK_LOG2("Still: ", buffer.getOccupied());
        return buffer.getOccupied();
    }

private:
    ESP8266* client;
    bool status;
    BlynkFifo<uint8_t,256> buffer;
    const char* domain;
    uint16_t    port;
};

class BlynkWifi
    : public BlynkProtocol<BlynkTransportShieldEsp8266>
{
    typedef BlynkProtocol<BlynkTransportShieldEsp8266> Base;
public:
    BlynkWifi(BlynkTransportShieldEsp8266& transp)
        : Base(transp)
        , wifi(NULL)
    {}

    bool connectWiFi(const char* ssid, const char* pass)
    {
        ::delay(500);
        BLYNK_LOG2(BLYNK_F("Connecting to "), ssid);
        /*if (!wifi->restart()) {
            BLYNK_LOG1(BLYNK_F("Failed to restart"));
            return false;
        }*/
        if (!wifi->kick()) {
             BLYNK_LOG1(BLYNK_F("ESP is not responding"));
       wdt_enable(WDTO_1S);
             //TODO: BLYNK_LOG_TROUBLE(BLYNK_F("esp8266-not-responding"));
             return false;
        }
        if (!wifi->setEcho(0)) {
            BLYNK_LOG1(BLYNK_F("Failed to disable Echo"));
            return false;
        }
        String ver = wifi->ESP8266::getVersion();
        BLYNK_LOG1(ver);
        if (!wifi->enableMUX()) {
            BLYNK_LOG1(BLYNK_F("Failed to enable MUX"));
        }
        if (!wifi->setOprToStation()) {
            BLYNK_LOG1(BLYNK_F("Failed to set STA mode"));
            return false;
        }
        if (wifi->joinAP(ssid, pass)) {
            String my_ip = wifi->getLocalIP();
            BLYNK_LOG1(my_ip);
        } else {
            BLYNK_LOG1(BLYNK_F("Failed to connect WiFi"));
      wdt_enable(WDTO_1S);
            return false;
        }
        BLYNK_LOG1(BLYNK_F("Connected to WiFi"));
        return true;
    }

    void config(ESP8266&    esp8266,
                const char* auth,
                const char* domain = BLYNK_DEFAULT_DOMAIN,
                uint16_t    port   = BLYNK_DEFAULT_PORT)
    {
        Base::begin(auth);
        wifi = &esp8266;
        this->conn.setEsp8266(wifi);
        this->conn.begin(domain, port);
    }

    void begin(const char* auth,
               ESP8266&    esp8266,
               const char* ssid,
               const char* pass,
               const char* domain = BLYNK_DEFAULT_DOMAIN,
               uint16_t    port   = BLYNK_DEFAULT_PORT)
    {
        config(esp8266, auth, domain, port);
        connectWiFi(ssid, pass);
        while(this->connect() != true) {}
    }

private:
    ESP8266* wifi;
};

static BlynkTransportShieldEsp8266 _blynkTransport;
BlynkWifi Blynk(_blynkTransport);

#include <BlynkWidgets.h>

#endif

char auth[] = "******";
char ssid[] = "Ayman33";
char pass[] = "braveheart333";

#define EspSerial Serial1
#define ESP8266_BAUD 115200
ESP8266 wifi(&EspSerial);


BlynkTimer timer;


void myTimerEvent()
{
  Blynk.virtualWrite(V5, millis() / 1000);
}

void checkBlynk(){  
 if(!Blynk.connected()){
    Serial.println("Not connected to Blynk server"); 
    wdt_enable(WDTO_1S);
    
  }
} 
bool connectWiFi(const char* ssid, const char* pass)
    {
        ::delay(500);
        BLYNK_LOG2(BLYNK_F("Connecting to "), ssid);
        /*if (!wifi->restart()) {
            BLYNK_LOG1(BLYNK_F("Failed to restart"));
            return false;
        }*/
        if (!wifi->kick()) {
             BLYNK_LOG1(BLYNK_F("ESP is not responding"));
       wdt_enable(WDTO_1S);
             //TODO: BLYNK_LOG_TROUBLE(BLYNK_F("esp8266-not-responding"));
             return false;
        }
        if (!wifi->setEcho(0)) {
            BLYNK_LOG1(BLYNK_F("Failed to disable Echo"));
            return false;
        }
        String ver = wifi->ESP8266::getVersion();
        BLYNK_LOG1(ver);
        if (!wifi->enableMUX()) {
            BLYNK_LOG1(BLYNK_F("Failed to enable MUX"));
        }
        if (!wifi->setOprToStation()) {
            BLYNK_LOG1(BLYNK_F("Failed to set STA mode"));
            return false;
        }
        if (wifi->joinAP(ssid, pass)) {
            String my_ip = wifi->getLocalIP();
            BLYNK_LOG1(my_ip);
        } else {
            BLYNK_LOG1(BLYNK_F("Failed to connect WiFi"));
      wdt_enable(WDTO_1S);
            return false;
}
 }           
void setup()
{
  
  Serial.begin(9600);
  delay(10);
  
  EspSerial.begin(ESP8266_BAUD);
  delay(10);

  Blynk.begin(auth, wifi, ssid, pass);

  timer.setInterval(1000L, myTimerEvent);
  timer.setInterval(6000L, checkBlynk);
}

void loop()
{
  
  Blynk.run();
  timer.run();
}

The code you’ve seen in post #22 of this topic is not an Arduino sketch, it’s one of the Blynk libraries, which @yaamr was suggesting could be modified as he described. If you go back and re-read the post this will become apparent.

I’d strongly recommend not modifying the Blynk libraries unless you really know what you’re doing (which you don’t) otherwise you are likely to simply create more problems for yourself and make it impossible to implement more appropriate solutions.

Pete.