Intermittent Connection Loss

Hi,

I am fairly new to Blynk and am working on a mini home automation project (sprinkler system). I have written my program on a Wemos D1 Mini and I have created my HMI on Blynk on my Android phone.

Everything seems to work perfectly fine, except that intermittently (very often), the connection of the Wemos to the Blynk server gets lost and takes a long time to reconnect, only to get dropped again later.

I am not writing my code in the Loop; my code runs in a Timer function every 500ms, so I don’t think it it overcrowding the server (?).

I have pasted all my code here. Would someone be able to tell me what stupid mistake I am making? Sorry for the long code…

Note: The Relay library is one that I created. I am not including the code here for brevity and because I don’t think it is relevant. If you need to see it let me know and I will post it.

Thanks!!

// *******************************************************************
//                           Defines & Includes
// *******************************************************************
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial

#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>

//needed for library
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h>          //https://github.com/tzapu/WiFiManager
#include <ESP8266Ping.h>
#include <Relay.h>



// *******************************************************************
//                            Variable Declaration
// *******************************************************************
// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = ****;

Relay ValveRelay1, ValveRelay2, ValveRelay3;

BlynkTimer TC1_Process;
int scheduler = 0;
const int TC1_Time = 500;

int hmi_LED = 0;
int V1Int, V2Int, V3Int, V4Int, V5Int, V6Int, V7Int, V8Int, V21Int, V22Int, V23Int;
//float V11Real, V12Real, V13Real, V14Real;
float remaining1, remaining2, remaining3;

int dxAutoSequence, diTRIGGER, dxRESET, dxSKIP, dxSTOPALLVALVES, ixTIMERLIMIT_min, ixTIMERLIMIT_ms;

int hmi_TIME1, hmi_TIME2, hmi_TIME3, hmi_STATE1, hmi_STATE2, hmi_STATE3;
int hmi_CloseVLV1, hmi_CloseVLV2, hmi_CloseVLV3;
int hmi_OpenVLV1, hmi_OpenVLV2, hmi_OpenVLV3;

int I33VLV1, I33VLV2, I33VLV3;



//float aiTIMERSETTING;

// *******************************************************************
//                             PERIODIC ROUTINE
// *******************************************************************

void TC1(){ // 500ms
  // -----------------------------------------------------------------
  // ---------- INPUTS -----------------------------------------------
  // -----------------------------------------------------------------

  I33VLV1 = digitalRead(D0);
  I33VLV2 = digitalRead(D5);
  I33VLV3 = digitalRead(D6);
  
  diTRIGGER = V8Int;
  dxSTOPALLVALVES = V6Int;


  hmi_OpenVLV1 = V1Int;
  hmi_OpenVLV2 = V2Int;
  hmi_OpenVLV3 = V3Int;
  hmi_CloseVLV1 = V21Int;
  hmi_CloseVLV2 = V22Int;
  hmi_CloseVLV3 = V23Int;


  ixTIMERLIMIT_min = V7Int;
  ixTIMERLIMIT_ms = 1000*60*ixTIMERLIMIT_min;


  // -----------------------------------------------------------------
  // ---------- CORE -------------------------------------------------
  // -----------------------------------------------------------------

  dxAutoSequence = (diTRIGGER || dxAutoSequence) && !ValveRelay3.FallingEdge && !dxSTOPALLVALVES;
  ValveRelay1.Run();
  ValveRelay2.Run();
  ValveRelay3.Run();
  
  ValveRelay1.TimedActivation(hmi_OpenVLV1 || diTRIGGER, hmi_CloseVLV1 || dxSTOPALLVALVES, ixTIMERLIMIT_ms);
  hmi_TIME1 = DivIntProt(100 * ValveRelay1.CurrentTimerValue, ixTIMERLIMIT_ms);
  Serial.println(D0);
  Serial.println(hmi_OpenVLV1);
  Serial.println(hmi_CloseVLV1);
  Serial.println(ixTIMERLIMIT_ms);
  Serial.println(ValveRelay1.State);
  Serial.println(I33VLV1);
  Serial.println(ValveRelay1.CurrentTimerValue);
  Serial.println("-");
  Serial.println(millis());
  Serial.println("-");

  ValveRelay2.TimedActivation(hmi_OpenVLV2 || (dxAutoSequence && (ValveRelay1.FallingEdge)), hmi_CloseVLV2 || dxSTOPALLVALVES, ixTIMERLIMIT_ms);
  hmi_TIME2 = DivIntProt(100 * ValveRelay2.CurrentTimerValue, ixTIMERLIMIT_ms);

  ValveRelay3.TimedActivation(hmi_OpenVLV3 || (dxAutoSequence && (ValveRelay2.FallingEdge)), hmi_CloseVLV3 || dxSTOPALLVALVES, ixTIMERLIMIT_ms);
  hmi_TIME3 = DivIntProt(100 * ValveRelay3.CurrentTimerValue, ixTIMERLIMIT_ms);    
  
  
  remaining1 = ValveRelay1.RemainingTime/60000.0;
  remaining2 = ValveRelay2.RemainingTime/60000.0;
  remaining3 = ValveRelay3.RemainingTime/60000.0;
  
  hmi_LED = 255 - hmi_LED;
  hmi_STATE1 = (I33VLV1 == LOW) ? 0 : 255;
  hmi_STATE2 = (I33VLV2 == LOW) ? 0 : 255;
  hmi_STATE3 = (I33VLV3 == LOW) ? 0 : 255;
  
  // -----------------------------------------------------------------
  // ---------- OUTPUTS ----------------------------------------------
  // -----------------------------------------------------------------
  Blynk.virtualWrite(V5, hmi_LED);
  
  
  Blynk.virtualWrite(V31, hmi_TIME1);
  Blynk.virtualWrite(V32, hmi_TIME2);
  Blynk.virtualWrite(V33, hmi_TIME3);

  
  Blynk.virtualWrite(V41, remaining1);
  Blynk.virtualWrite(V42, remaining2);
  Blynk.virtualWrite(V43, remaining3);

  Blynk.virtualWrite(V51, hmi_STATE1);
  Blynk.virtualWrite(V52, hmi_STATE2);
  Blynk.virtualWrite(V53, hmi_STATE3);

  digitalWrite(D1, HIGH);

  ValveRelay1.UpdateOutput();
  ValveRelay2.UpdateOutput();
  ValveRelay3.UpdateOutput();
 
}



// *******************************************************************
//                                  SETUP
// *******************************************************************
void setup()
{
  // Debug console
  Serial.begin(115200);


  ValveRelay1.SetPin(D0);
  ValveRelay2.SetPin(D5);
  ValveRelay3.SetPin(D6);
  ValveRelay1.UpdateRate = TC1_Time;
  ValveRelay2.UpdateRate = TC1_Time;
  ValveRelay3.UpdateRate = TC1_Time;
  ValveRelay1.AutoOutput = 0;
  ValveRelay2.AutoOutput = 0;
  ValveRelay3.AutoOutput = 0;



  // Pin initialization
  pinMode(D1, OUTPUT);     // Status LED
  pinMode(D0, OUTPUT);     // Valve 1
  pinMode(D5, OUTPUT);     // Valve 2
  pinMode(D6, OUTPUT);     // Valve 3
  
  digitalWrite(D1, HIGH);  // Status LED
  digitalWrite(D0, LOW);   // Valve 1
  digitalWrite(D5, LOW);   // Valve 2
  digitalWrite(D6, LOW);   // Valve 3



  

  dxSTOPALLVALVES = 0;

  // Periodic Routine Setup
  TC1_Process.setInterval(TC1_Time, TC1);
  
  // WiFi Setup and Connection
  WiFiManager wifiManager;
  wifiManager.autoConnect("AutoConnectAP");
  Serial.println("Connected!");
  WiFiManagerParameter custom_blynk_token("Blynk", "blynk token", auth, 33);
  wifiManager.addParameter(&custom_blynk_token);
  wifiManager.autoConnect("Blynk");
  Blynk.config(custom_blynk_token.getValue());
}



// *******************************************************************
//                           USER-DEFINED FUNCTIONS
// *******************************************************************
int DivIntProt(int in1, int in2)
{
  if (in2 == 0)
  {
    return 0;
  }
  else
  {
    return (in1 / in2);
  }
}



// *******************************************************************
//                                  LOOP
// *******************************************************************
void loop()
{
  Blynk.run();
  TC1_Process.run(); // Initiates BlynkTimer

}


// *******************************************************************
//                          BLYNK SYNC ALL
// *******************************************************************
bool isFirstConnect = true; // Keep this flag not to re-sync on every reconnection
BLYNK_CONNECTED() // This function will run every time Blynk initial connection is established
{
  if (isFirstConnect) {
    Blynk.syncAll();
    isFirstConnect = false;
  }
}

// *******************************************************************
//                                  BLYNK INPUTS
// *******************************************************************
BLYNK_WRITE(V1)
{ 
  int value = param.asInt(); // Get value as integer
  V1Int = value;
}
BLYNK_WRITE(V2)
{ 
  int value = param.asInt(); // Get value as integer
  V2Int = value;
}
BLYNK_WRITE(V3)
{ 
  int value = param.asInt(); // Get value as integer
  V3Int = value;
}
BLYNK_WRITE(V4)
{ 
  int value = param.asInt(); // Get value as integer
  V4Int = value;
}
BLYNK_WRITE(V5)
{ 
  int value = param.asInt(); // Get value as integer
  V5Int = value;
}
BLYNK_WRITE(V6)
{ 
  int value = param.asInt(); // Get value as integer
  V6Int = value;
}
BLYNK_WRITE(V7)
{ 
  int value = param.asInt(); // Get value as integer
  V7Int = value;
}
BLYNK_WRITE(V8)
{ 
  int value = param.asInt(); // Get value as integer
  V8Int = value;
}
BLYNK_WRITE(V21)
{ 
  int value = param.asInt(); // Get value as integer
  V21Int = value;
}
BLYNK_WRITE(V22)
{ 
  int value = param.asInt(); // Get value as integer
  V22Int = value;
}
BLYNK_WRITE(V23)
{ 
  int value = param.asInt(); // Get value as integer
  V23Int = value;
}



// *******************************************************************
//                          WIFI: configModeCallback
// *******************************************************************
// Gets called when WiFiManager enters configuration mode
void configModeCallback (WiFiManager *myWiFiManager) 
{
  Serial.println("Entered config mode");
  Serial.println(WiFi.softAPIP());
  Serial.println(myWiFiManager->getConfigPortalSSID());
}

You needed it your post and format your code correctly, so that it’s readable.

Pete.

Hi Pete

Thanks for pointing it out. I didn’t know how to format the code. I modified my original post. I hope this is better.

Thanks

That’s better!

You’re calling your TC1() function every half second, and it has quite a bit to do in that time.
I’d try two things (not necessarily at the same time):

  1. call the TC1() function less frequently, and see if that fixes your problem
  2. add some Blynk.run() lines into your TC1() function, at strategic points, so that the Blynk background functions aren’t starved of processor time while TC1() is being executed.

Pete.

In addition to Pete’s suggestions I’d try to add

#define BLYNK_DEBUG

before

#define BLYNK_PRINT Serial

to see what happens before the connetion gets lost.

Hi Pete, IBK,

I tried doing what you guys suggested and here is what I got:

  1. First, I removed all my Serial.println commands that I was using to debug my logic, in case this was taking too much resources.
  2. When I uploaded (without changing anything else), it seemed to be fixed. However, after a few hours, connection started to drop again
  3. I activated the Blynk Debug as suggested by IBK, and got the following stream:

[380168] <[14|1D|1E|00|06]vw[00]5[00]0
[380180] <[14|1D|1F|00|07]vw[00]31[00]0
[380191] <[14|1D] [00|07]vw[00]32[00]0
[380202] <[14|1D]![00|07]vw[00]33[00]0
[380214] <[14|1D]"[00|0D]vw[00]41[00]60.0000
[380225] <[14|1D]#[00|0D]vw[00]42[00]60.0000
[380236] <[14|1D]$[00|0D]vw[00]43[00]60.0000
[380247] <[14|1D]%[00|07]vw[00]51[00]0
[380258] <[14|1D]&[00|07]vw[00]52[00]0
[380269] <[14|1D]'[00|07]vw[00]53[00]0
[380633] <[06|1D]([00|00]
[380668] >[00|1D]([00|C8]

  1. Now it is working fine, I am waiting a few hours to see if connection starts to drop again, so I try Pete’s suggestion.

How do I interpret this debug stream? Please note that most of the times, the last two lines of the stream:

[380633] <[06|1D]([00|00]
[380668] >[00|1D]([00|C8]

are not there.

Thanks

This is the heartbeat, board telling Blynk that it’s alive and kicking.

Generally vw will be virtual write [00] pin number

Oh yes. Makes sense now. Thanks IDB!

Just an update: it seems things are running smoothly now. I am not sure what did it really. I removed all my serial.println instructions but it still dropped the connevtion after a while. But when I activated the Blynk debug for some reason it has been running smooth ever since…