Hello,
I have been trying to use blynk as a monitoring system on a nodemcu with a simple timer based sensor read. I also wanted redundancy against power outage and network loss. But when i put this code together, the simple timer would fail to execute about 10% of the time. Deeper dive shows that it was because Blynk.connected() was failing pretty regularly. Exactly 300 seconds regularly in fact, where it would then reconnect and continue to execute my program. Further dive showed that if i reset my router, i could get blykn.connected() to pass for up to time X, where X was the length of my DHCP lease, until it started failing every 300 seconds again. Changing my lease from hours to days could put off the problem unless I reset or update the MCU. I started to think it was the wifi, but further testing showed that wifi was constant through all of this. None of my other wifi devices show internet issues, though i haven’t explicitly tested for it.
The code is the simple Check Blynk code that is posted in this forum (based of Costas work) to run and reconnect during network loss. Perhaps my network settings are wrong?
And this wouldn’t even be an issue, except blynk stops my timers from executing as it tries to reconnect, which can take 5-10 seconds every 5 minutes.
I’ve tried to attach an excel graph from the superchart logging my connected time. This timer resets every time blynk connect or WL_connect failed.
My next step is to add a regular ping command to see if it is all of the internet which is failing every few minutes or only the blynk server connection.
Any advice on how to make a strong, persistent connection to the blynk server without resetting my router every day?
Thanks for the help!
#define NAMEandVERSION "OfflineTask_Reconnect_V1.0"
//#define BLYNK_DEBUG // Optional, this enables more detailed prints
//
const int SDAPIN= D4;//pin 4 is SDA in software
const int SCLPIN= D5; //pin 5 is SCL in software
unsigned long TimeOfLastWater_Mem=0;
unsigned long TimeOfLastWater_BLYNK=0;
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
#include "uEEPROMLib.h" //reads the AT24C32 eeprom in the RTC
#define BLYNK_TIMEOUT_MS 500 // must be BEFORE BlynkSimpleEsp8266.h doesn't work !!!
#define BLYNK_HEARTBEAT 17 // must be BEFORE BlynkSimpleEsp8266.h works OK as 17s
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <DHT.h>
#include <NTPClient.h>
#include <WiFiUdp.h>
#include <Time.h>
#include <TimeLib.h>
#include <TimeAlarms.h>
// RealTimeClock Library for DS1307 and DS3231 // see this page for info on using eeprom https://lastminuteengineers.com/ds3231-rtc-arduino-tutorial/#onboard-24c32-eeprom
#include "RTClib.h"
RTC_DS3231 RTC_EXTERNAL;
//#include <WidgetRTC.h>
//WidgetRTC RTCWidget; // requires RTC widget in app
#include <Wire.h>
#include <OneWire.h>
#include <DallasTemperature.h>
// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "#######################";
// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "#############";
char pass[] = "############";
unsigned int port = 8080;
char server[] = "45.55.96.146"; // can use "blynk-cloud.com" or an IP address. ping blynk-cloud.com and paste result
// Set your Static IP address
IPAddress local_IP(192, 168, 1, 176); //static IP for nodemcu
// Set your Gateway IP address
IPAddress gateway(192, 168, 1, 254); //router address
IPAddress dns_ip ( 192, 168, 1, 182); // pihole address
IPAddress subnet(255, 255, 255, 0); //I dunno, just copied
byte arduino_mac[] = {0xBC,0xDD,0xC2,0x24,0xEB,0xDC};
#define BLYNK_PRINT Serial
// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs). Use the pin umber for the bus.
//OneWire oneWire(DS18BPIN);
WidgetLED led_light(V50);
WidgetLED led_pump(V51);
WidgetLED led_wifi(V53); //This light on app will be active if connection is live
BlynkTimer timer;
BlynkTimer watertimer;
BlynkTimer sensortimer;
int timer_pump_off; //this is a timer to turn off the pump. It is activated after pump turns on to make sure it turns off
int timer_sensor_read; //this timer is controllable from the app. It controls the sensor read frequency.
// Define NTP Client to get time. This runs once during setup in full code and then never again.
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP);
unsigned long networkconnecttime= 0; // store the time blynk was connected. Reset each time blynk.connected fails
unsigned long wificonnecttime= 0; // store the time wifi was connected. Reset each time wifi check fails
unsigned int myEthernetTimeout = 20000; // 5.0s Ethernet Connection Timeout (ECT)
unsigned long blynkInterval = 120; // 120.0s Check Server Frequency (CSF)
unsigned long startConnecting = millis();
bool isFirstConnect=1;
const int MAXRETRY=3;
int eepromLocation=0; //save the location of the eeprom record. should find this at start of each program at Setup.
bool networkon = 0;
bool online = 0;
///////////////////////////////////////////
//////////////////////////////////////
void CheckConnection(){ // check every 11s if connected to Blynk server
if(!Blynk.connected())
{
// online = 0;
yield();
if (WiFi.status() != WL_CONNECTED)
{
wificonnecttime=millis();
Serial.println("Not connected to Wifi! Connect...");
//Blynk.connectWiFi(ssid, pass); // used with Blynk.connect() in place of Blynk.begin(auth, ssid, pass, server, port);
WiFi.setSleepMode(WIFI_NONE_SLEEP);//WIFI_MODEM_SLEEP may work better
WiFi.config(local_IP, dns_ip, gateway, subnet);
//WiFi.config(local_ip, gateway_ip, subnet_mask);
WiFi.begin(ssid, pass);
delay(400); //give it some time to connect
if (WiFi.status() != WL_CONNECTED)
{
Serial.println("Cannot connect to WIFI!");
Serial.print("\tReconnection failed. Trying again later. ");
online = 0;
}
else
{
Serial.println("Connected to wifi!");
}
}
if ( WiFi.status() == WL_CONNECTED && !Blynk.connected() )
{
networkconnecttime=millis();
Serial.println("Not connected to Blynk Server! Connecting...");
Blynk.connect(); // // It has 3 attempts of the defined BLYNK_TIMEOUT_MS to connect to the server, otherwise it goes to the next line
if(!Blynk.connected()){
Serial.println("Connection failed!");
Serial.print("\tReconnection failed. Trying again later. ");
online = 0;
}
else
{
online = 1;
}
}
}
else{
Serial.println("Connected to Blynk server!");
//online = 1;
Blynk.virtualWrite(V22, millis() / 1000 /60);
Blynk.virtualWrite(V23, (millis()-networkconnecttime) / 1000); //find out how much time has passed since the last internet outtage
Blynk.virtualWrite(V24, (millis()-wificonnecttime) / 1000); //find out how much time has passed since the last internet outtage
}
}
////////////////////////////////////////////////////
// Setup //
///////////////////////////////////////////////////
void setup()
{
// Debug console
#ifndef ESP8266 //part of rtc library?
while (!Serial); // for Leonardo/Micro/Zero
#endif
Serial.println("Welcome to Setup!");
Serial.begin(115200);
Wire.begin(SDAPIN, SCLPIN); //Wire.begin(SDA,SCL) allows us to change the pins the clock uses
RTC_EXTERNAL.begin(); // Synchronize with widget (server) time on connection
// setSyncProvider(syncProvider); // the function to get the time from the RTC
if(timeStatus() != timeSet)
Serial.println("Unable to sync with the RTC");
else
Serial.println("RTC has set the system time");
Blynk.begin(auth, ssid, pass);
// You can also specify server:
//Blynk.begin(auth, ssid, pass, "blynk-cloud.com", 80);
//Blynk.begin(auth, ssid, pass, IPAddress(192,168,1,100), 8080);
timer.setInterval(15000L, CheckConnection); // check connection to server per blynkInterval
Serial.println("Setup Complete. \n");
}
////////////////////////////////////////////////
//LOOP//
////////////////////////////////////////////////////
void loop()
{
timer.run();
// only attempt Blynk-related functions when connected to Blynk
if (Blynk.connected())
{
Blynk.run();
}
}
This should be a graph showing how blynk.connect time cycles every 5 min during continuous wifi connection.