Code isn't working without connected Blynk

@wanek do you get any further info if you add the following 2 lines as the first lines of the sketch?

#define BLYNK_DEBUG
#define BLYNK_PRINT Serial

Blynk.run() is designed this way that if it loses connectivity it will automatically try to reconnect you can have a look in source files. You would have to modify Blynk library or use what you have posted as last code which is fine btw.

no, just about the same output:

    entering Blynk.config()
    [0] Blynk v0.3.3
    entering Blynk.connect()

keeps hanging at Blynk.connect(), regardless that the network cable is plugged or not. this is my sketch now:

    #define BLYNK_DEBUG
    #define BLYNK_PRINT Serial

    #include <UIPEthernet.h>
    #include <BlynkSimpleUIPEthernet.h>

char auth[] = "xxxxxxxxxxxxxxxxxxxxxxxxx";
float timeout = (millis() / 1000);

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

  Serial.println("entering Blynk.config()");
  Blynk.config(auth, "blynk-cloud.com", 8442);

  Serial.println("entering Blynk.connect()");
  while (Blynk.connect() == false) {
    Serial.println("in while: Blink.connect() == false");
    if (((millis() / 1000) - timeout) > 10) {
      break;
    }
  }

  Serial.println("setup complete");
}

void loop()
{
  if (Blynk.connected()) {
    Blynk.run();
  }
}

there is no need to use float variable for timeout, its wrong, just use unsigned long, also mills() returns unsigned long so result of mills()/1000 is unsigned long, to get float you would have to cast both numbers to float. Secondly this is pointless:

while (Blynk.connect() == false) {
    Serial.println("in while: Blink.connect() == false");
    if (((millis() / 1000) - timeout) > 10) {
      break;
    }
  }

This is function in Blynk library responsible for connecting:

bool connect(uint32_t timeout = BLYNK_TIMEOUT_MS*3) {
	conn.disconnect();
	state = CONNECTING;
	uint32_t started = millis();
	while ((state != CONNECTED) &&
	       (millis() - started < timeout))
	{
		run();
	}
	return state == CONNECTED;
}

You can clearly see there is timeout already there… just use it as Blynk.connect(timeout)

And btw your code is not hanging up on Blynk.connect() it just executes the check once or maybe not at all because you wrongly declared timeout float. you should just declare it as global variable float timeout; then later in setup assign (mills() / 1000)

@conkerkh you are quite right timeout shouldn’t be float.

Perhaps you can expand on what you mean by “just declare it as global variable float timeout;”

@Costas

I messed up last bit, what I meant is declare as unsigned long variable without initializing it:

unsigned long timeout;

rather than:

unsigned long timeout = mills() / 1000;

This variable most likely wont initialize properly as timers are not yet running (it’s initialized before setup happens?), this is actually good question but for sake of predictable results it should be done in setup(). If timers aren’t initialized it will be 0 anyway, kinda pointless right? Also in this case timeout doesn’t have to be global as it is used only in setup()

Yes timeout only needs to be declared in setup() not globally.

unsigned long timeout; is wrong though because you want the running time when setup reaches this point not zero. In some cases it can take MANY seconds to work through all the items in setup() e.g. with WiFiManager etc.

So it does need to be:

` unsigned long timeout = millis() / 1000;

If it is declared as global it should be unsigned long timeout; as there is no point in initializing there a global variable with mills(), you assign mills()/1000 later in setup just before while loop. However if the variable is used as local in setup then you initialize and declare variable inline just before while loop like so: unsigned long timeout = mills() / 1000; (same as your last line), you probably misunderstood me as for the first part.

Anyway the whole thing with while loop is not needed as you can simply use Blynk.connect(3333); which will do the same.

@conkerkh do you actually use Blynk.connect(timeout); in your sketches?

With Blynk.connect(1); i.e 3 milliseconds I get:

[4868] Blynk v0.3.4
[5001] Connecting to blynk-cloud.com:8442
[5351] Ready (ping: 1ms).

This suggests it took 351 milliseconds to connect so why didn’t it skip through the timeout after 3ms?

Tried several connections and even with almost 5 seconds to connect it still doesn’t skip the timeout.

[5865] Blynk v0.3.4
[5865] Connecting to blynk-cloud.com:8442
[11225] Connecting to blynk-cloud.com:8442
[11545] Ready (ping: 0ms).

hi!
thanks for clearing things up. i was asked to follow exact code examples, this is why i used ‘as is’.

unfortunately for the next days i will not have access to the arduino + ethernet modul. but later i will test your suggestion too, and announce if it works or not.

It’s a while condition not a timer interrupt so in this case you wont see timeout after 3ms but it will occur when run() finishes execution and at the same time while loop checked that it is executing for more than 3ms.

1 Like

Hi @wanek

I’m wondering if you ever resolved your connection issues as discussed in this thread? I am looking for a solution for the same problem. I would like to use Blynk.connect() instead of Blynk.begin() so I can run the code even when internet connection is down.

I am experiencing the same problems as you have described.

hello!

the short answer is yes. but not was as simple as i thought…
i also have to mention, that i’m not really good at oop, so probably, there are more elegant ways to solve this problem.

i still do not understand why everybody thinks, that a sketch should work only with network connection. yes, it is very nice to use the blynk app, but sometimes the arduino should work even without internet… so, here is what i did (only the relevant code):

/*

 There is a bug in blynk library (v0.3.4), which hangs the Blynk.begin(auth) function (keeps restarting the board every minute), if there is no network access during startup. To bypass this problem, edit this file in:
  libraries\Blynk\Adapters\BlynkEthernet.h, at line 58:

  comment out the: BLYNK_FATAL("DHCP Failed!"); line,

  and insert these lines:
  BLYNK_LOG("DHCP failed. check your network connection!");
  BLYNK_LOG("bypassing blynk...");
  return;

*/

// global variables
bool blynkAllowed = true;
bool firstConnect = true;

void setup()
{
  //Serial.begin(9600);
  
  Blynk.begin(auth);       // configuring ethernet. timeout: 60 seconds

  if (millis() < 50000) {  // if Blynk.begin(auth) finished under 50 seconds == connected to network
    beep(500, 0);
    //Serial.println("connected to local network!");

    tryConnecting();                          // try to connect to blynk server
    tryConnecting();                          // i put this twice, because very rarely it fails the first connection

    timer.setInterval(1000, updateBlynk);     // set how often send data to the blynk server
    timer.setInterval(60000, tryConnecting);  // if lost connection, try to connect time by time

    //Serial.println("reconnect attempts to blynk server allowed in main loop");
  }
  else {                   // if Blynk.begin(auth) took more than 50 seconds == no network connection
    blynkAllowed = false;
    beep(2000, 0);

    //Serial.println("no network access. no reconnect attempts will be allowed in main loop");
  }
}

void loop()
{
  checkBlynk();
  timer.run();  // initiates SimpleTimer
}

void checkBlynk()
{
  if (blynkAllowed) {
    if (firstConnect) tryConnecting();
    if (Blynk.connected()) Blynk.run();
  }
}

void tryConnecting()
{
  if (!Blynk.connected()) {
    Blynk.connect();  // try to connect for 15 seconds, every time, as set  in: timer.setInterval(60000, tryConnecting) in void setup
                      // but let the main loop run

    if (Blynk.connected()) {
      if (firstConnect) {
        // do some none relevant stuff here, and
        firstConnect = false;
      }
      
      //Serial.println("connected to blynk server!");
      beep(500, 0);
    }
  }
}

i hope the code + comments are self explanatory. check it out, and let me know if this works for you. since when i wrote this code, there are newer library versions, but afaik this specific situation was not resolved.

*edit: of course, do not forget, to close the arduino ide before editing the lib file, and open the ide only after you saved the file.

1 Like

Hi @wanek,

Thankyou very much for sharing your solution. I will try and implement what you have done and let you know if it works for me. Well done for working it out.

Nick Murray

@wanek I have implemented the code you suggested and made the changes in the Blynk library file. It works well for me. Thanks again for the solution.

i’m glad that could help.

I am facing same problem.I am using Nodemcu ESP8266 12e.
This my original code

#define BLYNK_PRINT Serial // Comment this out to disable prints and save 
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <SimpleTimer.h>
#include <TimeLib.h>

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

// Set your LED and physical button pins here
const int ledPin = 16;
const int btnPin = 5;

SimpleTimer timer;
void checkPhysicalButton();

int ledState = LOW;
int btnState = HIGH;
void sendUptime() {
  Blynk.virtualWrite(V20, millis() / 60000);
  long rssi = WiFi.RSSI();
  Blynk.virtualWrite(V15, rssi);
}
void setup()
{
Serial.begin(115200);
  pinMode(ledPin, OUTPUT);
  pinMode(btnPin, INPUT_PULLUP);
  digitalWrite(ledPin, ledState);
  timer.setInterval(100L, checkPhysicalButton);
  Blynk.begin(auth, "xxxxxxx", "xxxxxxx");
while (Blynk.connect() == false) {
    // Wait until connected
  }

timer.setInterval(60000L, sendUptime);
  // Setup a function to be called every 100 ms
  
}

bool isFirstConnect = true;

// This function will run every time Blynk connection is established
BLYNK_CONNECTED() {
  if (isFirstConnect) {  
    Blynk.syncAll();
    isFirstConnect = false;
  }
}


// When App button is pushed - switch the state
BLYNK_WRITE(V2) {
  ledState = param.asInt();
  digitalWrite(ledPin, ledState);
}

void checkPhysicalButton()
{
  if (digitalRead(btnPin) == LOW) {
    // btnState is used to avoid sequential toggles
    if (btnState != LOW) {

      // Toggle LED state
      ledState = !ledState;
      digitalWrite(ledPin, ledState);

      // Update Button Widget
      Blynk.virtualWrite(V2, ledState);
    }
    btnState = LOW;
  } else {
    btnState = HIGH;
  }
}

void loop()
{ timer.run();
  Blynk.run(); // Run Blynk
  // Run SimpleTimer
}

I have tried your code but got many errors. can explain how to implement this your my code???
I am using Nodemcu ESP 8266 12e.

What errors did you get?

The above code works fine when it connected to internet .
But doesn’t works when wiffi router is off.
I have connected physical buttons they should works when internet is off / wiffi router is off.
Plz guys help me.

@saurabh47 study this post in detail Check connection status in loop and reconect