Re connection after wifi internet loss

I am in the process of migrating my ongoing project to 2.0. I am running 3 Wemos D1 mini clones having used wifi provisioning and Edgent. They are in the same template and uploads are working with Blynk.air. My issue is that they do not re connect after internet loss. Here is what it shows on the serial moniotor.

[58848] RUNNING => CONNECTING_NET
[58848] Connecting to WiFi: NETGEAR83
[88852] CONNECTING_NET => ERROR

The bare bones Edgent does re connect automatically. I guess my next step would be to strip down my sketch and see if I can isolate what causes the issue but I figured I’d post to see if there are some simple things I could try first. The Edgent sketch is a little above my ability level as far as trying to tweak the reconnect function. Any help or input would be greatly appreciated.

// Fill-in information from your Blynk Template here
#define BLYNK_TEMPLATE_ID "xxxxxxx"
#define BLYNK_DEVICE_NAME "Plant Monitoring"

#define BLYNK_FIRMWARE_VERSION        "0.1.0"

#define BLYNK_PRINT Serial
//#define BLYNK_DEBUG

#define APP_DEBUG

// Uncomment your board, or configure a custom board in Settings.h
//#define USE_SPARKFUN_BLYNK_BOARD
//#define USE_NODE_MCU_BOARD
//#define USE_WITTY_CLOUD_BOARD
#define USE_WEMOS_D1_MINI

#include "BlynkEdgent.h"
#include <WidgetRTC.h>

bool LongHold1=false;
bool LongHold2=false;
bool ButtonPressed1=false;
bool ButtonPressed2=false;
int ButtonTimer1;
int ButtonTimer2;

int pumpPin[5];
int moistureThreshP[5];
int pumpRunTime[5];
int rawRead[5];
int sensorReadMap[5];
int sensorPowerPin[5];
int virtualGraphPin[5];
int virtualRawReadDataPin[5];

int j;
int i;
int k;

String  my_h;
String  my_m;
String  my_s;
String  my_D;
String  my_M;
String  my_Y;
String Weekday;
String Time;
String date1;

BlynkTimer myTimer;
WidgetRTC rtc;
WidgetTerminal terminal(V12);
WidgetLED greenLed1(V52);WidgetLED redLed1(V53);
WidgetLED greenLed2(V57);WidgetLED redLed2(V56);

void setup()
{
  Serial.begin(9600);
  delay(100);

  BlynkEdgent.begin();

  myTimer.setTimeout(3600001L,[](){});       //sacrificial timer for timer bug  
  myTimer.setInterval(10003L, GetTime);     // display clock every 10 seconds
  myTimer.setInterval((1000L*60L*5L)+17L,sensorRead);      //timer for regular reading of moisture level to show on level displays
  myTimer.setInterval((1000L*60L*30L)+49L,checkMoisture);    //timer to check moisture for watering 

  pumpPin[1]=D1;                                                  //pump pins
  pumpPin[2]=D2;
  pumpPin[3]=D3;
  pumpPin[4]=D3;

  sensorPowerPin[1]=D5;                                            //sensor power pins
  sensorPowerPin[2]=D6;
  sensorPowerPin[3]=D7;
  sensorPowerPin[4]=D8;

  virtualGraphPin[1]=V0;                                         //virtual pins for moisture level graph in app
  virtualGraphPin[2]=V1;
  virtualGraphPin[3]=V2;
  virtualGraphPin[4]=V3;

  virtualRawReadDataPin[1] = V8;
  virtualRawReadDataPin[2] = V9;
  virtualRawReadDataPin[3] = V8;
  virtualRawReadDataPin[4] = V8;
  
  pinMode(A0,INPUT);
  pinMode(pumpPin[1],OUTPUT);
  pinMode(pumpPin[2],OUTPUT);
  pinMode(pumpPin[3],OUTPUT);
  pinMode(pumpPin[4],OUTPUT);
  pinMode(sensorPowerPin[1],OUTPUT);
  pinMode(sensorPowerPin[2],OUTPUT);
  pinMode(sensorPowerPin[3],OUTPUT);
  pinMode(sensorPowerPin[4],OUTPUT);  
}

void loop() {
  BlynkEdgent.run();

  myTimer.run();
}

void sensorRead(){
  digitalWrite(D5,LOW);
  digitalWrite(D6,LOW);
  delay(500);
  Blynk.run();  
 
  for (i=1; i<=2; i=i+1){
    digitalWrite(sensorPowerPin[i],HIGH);
    delay(500);
    rawRead[i]=analogRead(A0);
    if (i==1){sensorReadMap[i] = map(rawRead[i],415, 266, 1, 100);}
    if (i==2){sensorReadMap[i] = map(rawRead[i],415, 266, 1, 100);}
    if (i==3){sensorReadMap[i] = map(rawRead[i],769, 209, 1, 100);}
    if (i==4){sensorReadMap[i] = map(rawRead[i],769, 380, 1, 100);}

    Serial.print(i);Serial.print(" raw read = ");Serial.println(rawRead[i]);
    Serial.print("mapped read = ");Serial.println(sensorReadMap[i]); 
    digitalWrite(sensorPowerPin[i],LOW);
    delay(500);

    terminal.print(i); terminal.print(" raw read = "); terminal.println(rawRead[i]);
    terminal.print("mapped read = ");terminal.println(sensorReadMap[i]);
    terminal.flush();
    
    Blynk.run();
       
    Blynk.virtualWrite(virtualGraphPin[i],sensorReadMap[i]); 
    Blynk.virtualWrite(virtualRawReadDataPin[i],rawRead[i]);
  }
}

void checkMoisture(){
  Serial.println("                 CHECKING  MOISTURE !!!");
  terminal.println("  Watering Check: ");
  date1 = (my_M + " " + my_D + " " + my_Y);
  terminal.print(date1);
  terminal.print("  ");
  terminal.println(Time);  
  terminal.flush();
    
  for(j = 1; j<=2; j=j+1){
    Serial.print("moist. read of plant ");Serial.print(j);Serial.print(" = ");Serial.print(sensorReadMap[j]);Serial.print("   moist. thresh = ");Serial.println(moistureThreshP[j]);
    /*terminal.print("moisture plant ");terminal.print(j);terminal.print(" = ");terminal.print(sensorReadMap[j]);terminal.print(" threshold = ");terminal.println(moistureThreshP[j]);terminal.flush();*/
      if (sensorReadMap[j]<=moistureThreshP[j] && j==1){pumpOn1();} 
      if (sensorReadMap[j]<=moistureThreshP[j] && j==2){pumpOn2();}
      //if (sensorReadMap[j]<=moistureThreshP[j] && j==3){pumpOn3();}
      //if (sensorReadMap[j]<=moistureThreshP[j] && j==4){pumpOn4();}      
}
}

//Pump 1 ON/OFF  functions
void pumpOn1(){                                                                                    
  digitalWrite(pumpPin[1],HIGH);
  Blynk.virtualWrite(V2,2);     //Pump state toggle manual pump on notification                                                             
  Serial.print("Pump 1 on");Serial.print("  RunTime= ");Serial.println(pumpRunTime[1]);            
  terminal.print("P1 on for ");terminal.println(pumpRunTime[1]);terminal.flush();                   
  myTimer.setTimeout(pumpRunTime[1]*1000L,pumpOff1);                                                                                               
}                                                                                                  
void pumpOff1(){                                                                                   
  Serial.println("pump 1 off");                                                                    
  terminal.println("");terminal.flush();
  terminal.print("P1 off  ");terminal.flush();                                                   
  digitalWrite(pumpPin[1],LOW);
  Blynk.virtualWrite(V2,0);    //Pump state toggle for notification                                                                                                                                 
}                                                                                                

//Pump 2 ON/OFF functions
void pumpOn2(){                                                                                    
  digitalWrite(pumpPin[2],HIGH); 
  Blynk.virtualWrite(V3,2);      //Pump state toggle for notification                                                             
  Serial.print("Pump 2 on");Serial.print("  RunTime= ");Serial.println(pumpRunTime[2]);            
  terminal.print("P2 on for ");terminal.println(pumpRunTime[2]);terminal.flush();                    
  myTimer.setTimeout(pumpRunTime[2]*1000L,pumpOff2);                                                 
}                                                                                                  
void pumpOff2(){                                                                                                                                                                    
  Serial.println("pump 2 off");                                                                    
  terminal.print("P2 off  ");terminal.flush();                                                   
  digitalWrite(pumpPin[2],LOW); 
  Blynk.virtualWrite(V3,0);     //Pump state toggle for notification                                                               
}                                                                                                  

  /**************** LOCK UNLOCK 1**************/
BLYNK_WRITE(V50) {  // button to be held down to activate
    if (param.asInt() and  !LongHold1 ) {
    ButtonTimer1 = myTimer.setTimeout(1541, LongHoldDetect1); // press 2 sec
    ButtonPressed1 = true;    
    
// Button has been released
  } else {
    ButtonPressed1 = false;        // Reset press flag
     if (param.asInt()==1) {
      digitalWrite(D1,HIGH);
      Blynk.virtualWrite(V2,1);}  //Pump state toggle for notification 
       
     else {digitalWrite(D1,LOW);
           Blynk.virtualWrite(V2,0);}  //Pump state toggle for notification 
 
    // If the long hold function wasn't called, it's a short press.
    if (!LongHold1) {
      myTimer.deleteTimer(ButtonTimer1);   // Kill the long hold timer if it hasn't been activated.

      // Reset the long press flag
      LongHold1 = false;
      greenLed1.off();
      redLed1.on();
    }
  }
}

BLYNK_WRITE(V51) {  // Reset button
  if (param.asInt()) {
    if (LongHold1 = true) {
      ButtonPressed1 = false;
      LongHold1 =  false;
      greenLed1.off();
      redLed1.on();
        }
  }
}
  /**************** LOCK UNLOCK 2**************/
BLYNK_WRITE(V54) {  // button to be held down to activate
    if (param.asInt() and  !LongHold2 ) {
    ButtonTimer2 = myTimer.setTimeout(1537, LongHoldDetect2); // press 2 sec
    ButtonPressed2 = true;    
    
// Button has been released
  } else {
    ButtonPressed2 = false;        // Reset press flag
      if (param.asInt()==1) {
        digitalWrite(D2,HIGH);
        Blynk.virtualWrite(V3,1);}       //Pump state toggle for notification 
      else {
        digitalWrite(D2,LOW);
        Blynk.virtualWrite(V3,0);}  //Pump state toggle for notification 
 
    // If the long hold function wasn't called, it's a short press.
    if (!LongHold2) {
      myTimer.deleteTimer(ButtonTimer2);   // Kill the long hold timer if it hasn't been activated.

      // Reset the long press flag
      LongHold2 = false;
      greenLed2.off();
      redLed2.on();
    }
  }
}

BLYNK_WRITE(V55) {  // Reset button
  if (param.asInt()) {
    if (LongHold2 = true) {
      ButtonPressed2 = false;
      LongHold2 =  false;
      greenLed2.off();
      redLed2.on();
        }
  }
}

// Checks for long press condition on SETTINGS button
void LongHoldDetect1() {
  // If the button is still depressed, it's a long hold
  if (ButtonPressed1) {
    LongHold1 = true;
    greenLed1.on();
    redLed1.off();
     }
}
// Checks for long press condition on SETTINGS button
void LongHoldDetect2() {
  // If the button is still depressed, it's a long hold
  if (ButtonPressed2) {
    LongHold2 = true;
    greenLed2.on();
    redLed2.off();
     }
}

void GetTime() {
my_h = MyPrintDigits(hour());
my_m = MyPrintDigits(minute());
my_s = MyPrintDigits(second());
my_D = MyPrintDigits(day());
my_M = MyPrintDigits(month());
my_Y = MyPrintDigits(year());

  /////////////////////////////////////// Clock /////////////////////////////////////
  String Weekday = dayAsString(weekday());
  Blynk.virtualWrite(V20, Weekday + " " + my_M + " " + my_D + " " + my_Y);
  Time = my_h + ":" + my_m + ":" + my_s;
  Blynk.virtualWrite(V21, Time);
}

///////////////////////////////////// MyPrintDigits /////////////////////////////////////
String MyPrintDigits(int digits) {
  String new_digits = "";
  if (digits < 10) new_digits += "0";
  new_digits += String(digits);
  return new_digits;
}
///////////////////////////////////// Day of the week  /////////////////////////////////////
String dayAsString(int day) {
  switch (day) {
    case 1: return "Sunday";
    case 2: return "Monday";
    case 3: return "Tuesday";
    case 4: return "Wednesday";
    case 5: return "Thursday";
    case 6: return "Friday";
    case 7: return "Saturday";
  }
}
BLYNK_CONNECTED() {
  Blynk.sendInternal("rtc", "sync"); //request current local time for device
  Blynk.syncVirtual(V0);
  Blynk.syncVirtual(V1);
  Blynk.syncVirtual(V2);
  Blynk.syncVirtual(V3);
  Blynk.syncVirtual(V4);
  Blynk.syncVirtual(V5);
  Blynk.syncVirtual(V6);
  Blynk.syncVirtual(V7);
  Blynk.syncVirtual(V8);
  Blynk.syncVirtual(V9);
  Blynk.syncVirtual(V12);
  Blynk.syncVirtual(V20);
  Blynk.syncVirtual(V21);
  Blynk.syncVirtual(V22);
  Blynk.syncVirtual(V23);
  Blynk.syncVirtual(V50);
  Blynk.syncVirtual(V51);
  Blynk.syncVirtual(V52);
  Blynk.syncVirtual(V53);
  Blynk.syncVirtual(V54);
  Blynk.syncVirtual(V55);
  Blynk.syncVirtual(V56);
  Blynk.syncVirtual(V57); 
}
BLYNK_WRITE(V4) {moistureThreshP[1] = param.asInt();}             //gets moisture threshold level P1 from app
BLYNK_WRITE(V6) {moistureThreshP[2] = param.asInt();}                       
BLYNK_WRITE(V8) {moistureThreshP[3] = param.asInt();}                        
BLYNK_WRITE(V10) {moistureThreshP[4] = param.asInt();}                                                                

BLYNK_WRITE(V5) {pumpRunTime[1] = param.asInt();}                //gets pump runtime from app                
BLYNK_WRITE(V7) {pumpRunTime[2] = param.asInt();}
BLYNK_WRITE(V9) {pumpRunTime[3] = param.asInt();}
BLYNK_WRITE(V11) {pumpRunTime[4] = param.asInt();}

BLYNK_WRITE(V22) {param.asString();}                //gets plant names from app                
BLYNK_WRITE(V23) {param.asString();}

I notice this as well

As someone who has been following this forum for awhile especially since the launch of 2.0, I fail to understand why this post is getting no response at all good or bad. Devs or moderators could you give me some comment at least to help with future posts? Thanks

A post was split to a new topic: Connection issues with ESP32

The way the forum works (or at least should work) is that users with experience or some form of “educated insight” into a problem chip-in with their ideas. Of course, it doesn’t always work like that, some forum members will post things anyway, regardless of how useful, relevant or insightful they may be.

The problem is that Blynk IoT is new to all of us, and we are all approaching from different starting points, and with different goals in mind. I for one don’t use Edgent, as I don’t run any Blynk code on my devices. Instead I use MQTT and Arduino OTA on my devices, and use Node-Red as my interface with Blynk.

Blynk developers read the posts on this forum, but are mostly focussed on commercial clients and rolling-out new features. The best place to raise an issue of this type is really on the GitHub issues page, because these issues are then assigned to the most appropriate person and the progress is more easily tracked. However, if you are going to raise an issue there I’d suggest that you include all of the relevant information, including the library version that you are currently using.

Pete.

1 Like

First off, thank you for your response. Points taken and I was trying to word my last reply so as not to sound offensive. I have pretty much read every one of your responses for the last 2 months and can’t even imagine the time and effort you put in. (Your Timer tutorial was one of the best I’ve read)
I am fairly new to this (the last coding I’ve done pre-pandemic was in BASIC and Fortrtan in the mid to late 80’s ) so it’s been quite the learning curve and I usually prefer to just read and Google to figure stuff out. I just figured I’d give posting a go as it could be helpful in the future.
Anyway I am using Blynk library version 1.0.1. I will be looking to have my projects running in 2 locations and wanted the ability to update regularly so I figured Edgent was the way to go.
Thanks again

I noticed a Blynk.run() statement in your void sensorRead() loop. Is that right ?

I am actually not sure if they are appropriate with Edgent but this sketch runs well. They are left over from the original sketch to help deal with delays.
I have actually tried replacing that function with a timer routine to get rid of all delays but I have the same issue.

if you are going to have additional .run statements then they should be BlynkEdgent.run();

Pete.

Ok Pete, thanks for the clarification. I tried that simple update with no change. I am going to try a step by step rebuild from the working edgent until I find the issue. I’ll post results.

So I got kinda of lucky and figured out the issue relatively early in the rebuild process. If I comment out pinMode(pumpPin[3],OUTPUT) it reconnects consistently with no hang. I’m not sure if this make sense but I tested thoroughly and it is the case.

The funny or sad part is I that at the moment I am just testing so I’m not even using the D3 or D4 pins. I know you have to pay attention to the Wemos D1 mini pin use but this was working in legacy and it always booted fine.

D3 = GPIO0

Take a look at your Settings.h tab.

Pete.

Sorry Pete, I do not see that in my settings.h tab. Could I have something set up wrong? I am running Arduino 1.1.15, my board is selected as WEMOS(LOLIN)D1 mini(clone) and I have I’m showing Blynk version 1.0.1 installed.

Regardless, I do understand that D3 is GPIO0 on the WEMOS and just thought that could cause flash or boot issues as opposed to a reconnection issue.

Post your Settings.h

Pete.

#define BOARD_BUTTON_PIN            0                     // Pin where user button is attached
  #define BOARD_BUTTON_ACTIVE_LOW     true                  // true if button is "active-low"

  #define BOARD_LED_PIN               4                     // Set LED pin - if you have a single-color LED attached
  //#define BOARD_LED_PIN_R           15                    // Set R,G,B pins - if your LED is PWM RGB
  //#define BOARD_LED_PIN_G           12
  //#define BOARD_LED_PIN_B           13
  //#define BOARD_LED_PIN_WS2812      4                     // Set if your LED is WS2812 RGB
  #define BOARD_LED_INVERSE           false                 // true if LED is common anode, false if common cathode
  #define BOARD_LED_BRIGHTNESS        64                    // 0..255 brightness control

#endif


/*
 * Advanced options
 */

#define BUTTON_HOLD_TIME_INDICATION   3000
#define BUTTON_HOLD_TIME_ACTION       10000

#define BOARD_PWM_MAX                 1023

#define CONFIG_AP_URL                 "blynk.setup"
#define CONFIG_DEFAULT_SERVER         "blynk.cloud"
#define CONFIG_DEFAULT_PORT           443

#define WIFI_NET_CONNECT_TIMEOUT      30000
#define WIFI_CLOUD_CONNECT_TIMEOUT    60000
#define WIFI_AP_IP                    IPAddress(192, 168, 4, 1)
#define WIFI_AP_Subnet                IPAddress(255, 255, 255, 0)
//#define WIFI_CAPTIVE_PORTAL_ENABLE

//#define USE_TICKER
//#define USE_TIMER_ONE
//#define USE_TIMER_THREE
//#define USE_TIMER_FIVE
//#define USE_PTHREAD

#define BLYNK_NO_DEFAULT_BANNER

#if defined(APP_DEBUG)
  #define DEBUG_PRINT(...) BLYNK_LOG1(__VA_ARGS__)
#else
  #define DEBUG_PRINT(...)
#endif

That looks incomplete.

Pete.

I’m trying to figure out what you’re getting at without you spoon feeding me the answers.

Just to re-cap I now have 3 Wemos D1 minis running in my template running the above sketch with the pinMode(pumpPin[3],OUTPUT) commented out and the above settings.h tab. They seem stable, update via Blynk.air and now reconnect after router reboot.

That is the settings.h tab in my sketch that I am using. I’m sure you are probably right but my understanding is that you’re board pin outs are set by uncommenting the board you are using. This is done in my sketch so I’m not sure why it would be incomplete. Is there something I missed?

Your Settings.h should contain this code, unless you’ve deleted it or moved it somewhere else in the sketch…

#if defined(USE_NODE_MCU_BOARD) || defined(USE_WEMOS_D1_MINI)

  #define BOARD_BUTTON_PIN            0
  #define BOARD_BUTTON_ACTIVE_LOW     true

  #define BOARD_LED_PIN               2
  #define BOARD_LED_INVERSE           true
  #define BOARD_LED_BRIGHTNESS        255

If this is in your code then GPIO0 (D3) is already in use…

#define BOARD_BUTTON_PIN 0

If it’s not in your code then you’ve disabled some of the Edgent provisioning functionality.

Pete.

Sorry, you are right as usual it’s in there, not sure where I cut and pasted from. So I guess I was just lucky with nothing else in the code getting hung up earlier.
Thanks for your time and effort.

Been following this and but if i unplug power to my device and reconnect it still does not reconnect. Looking through the the files specifically the configStore.h i notice the use of EEPROM. I wonder, if one uses EEPROM within their sketch would this have an effect for the reconnection?