Code isn't working without connected Blynk

ok. thank you. i will try it right now.

You also need to have a loop check for when your network comes back up so you can start using Blynk again.

i used the code in the example you gave, but now it hangs during the Blynk.connect() function WITH NETWORK CABLE PLUGGED.

if instead Blynk.begin(auth) i’m using the code you gave, maybe there are other things to manually configure? i did not find a detailed documentation how to configure manually, but here: http://docs.blynk.cc/#blynk-firmware-virtual-pins-control-blynk_connected it says:
“You can also set up shields (WiFi, Ethernet) manually, and then call:
Blynk.config(auth);” so, maybe i’m missing something before call Blynk.config(auth)…

however, i do not understand, how could the “while” cycle measure the timeout, if it never gets executed, because the program hangs at Blynk.connect()?

this is the relevant part from my sketch:

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

char auth[] = "xxxxxxxxxxxxxxxxxxxxxxxxx";

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

  Serial.println("entering Blynk.config(auth);");
  Blynk.config(auth);

  Serial.println("entering Blynk.connect();");
  Blynk.connect();

  Serial.println("set float");
  float timeout = (millis() / 1000);

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

  beep(50, 0);  // system ready
}

My sketch extract is based on WiFi and for devices that are already connected to the internet with WiFiManager.

You need to adapt for ethernet access and as I don’t use ethernet you would have to post your working ethernet sketch if you want us to advise what changes you need to make.

ok, here is my working sketch (only the relevant code):

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

char auth[] = "xxxxxxxxxxxxxxxxxxxxxxx";

void setup()
{
  Blynk.begin(auth);

/* if network cable not plugged, timeout is ~60 seconds, after that it reboots. i would like to bypass this (instead rebooting -> go to loop()), if there is no network connection.*/

  beep(50, 0);
}

void loop()
{
  Blynk.run();

  checkOpto();
  checkUps();
  checkMotion();
  checkButton();
  checkTimers();
}

@Costas , i’m not allowed to post more than 3 post in the same topic, so i try to edit this one.

so, i have tried the EXACT code you provided.
now it passes the Blynk.config(auth, “blynk-cloud.com”, 8442) function, but hangs in the Blynk.connect() , with the network cable plugged!
it does not enter in the “while” loop.

I have installed the relevant libraries and set the board to Mega ADK but without the actual hardware it is difficult to check.

What does this do for you:

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

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

void setup()
{
  Serial.begin(9600);
  Blynk.config(auth, "blynk-cloud.com", 8442);
  //Blynk.begin(auth);
  // You can also specify server.
  // For more options, see BoardsAndShields/Arduino_Ethernet_Manual example
  //Blynk.begin(auth, "blynk-cloud.com", 8442);
  //Blynk.begin(auth, IPAddress(192,168,1,100), 8888);

  Blynk.connect();
  while (Blynk.connect() == false) {
    if(((millis()/1000) - timeout) > 10){   // issue msg if not connected to Blynk in more than 10 seconds
      break; 
    }
  }
}

void loop()
{
  if(Blynk.connect() == true){
    Blynk.run();
  }
}

Looks like I’ve solved the problem using this code:

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

char auth[] = "auth";
const char* ssid = "ssid";
const char* password = "pass";

void setup()
{
  Serial.begin(9600);
  WiFi.begin(ssid, password);
  Blynk.config(auth);
  if (WiFi.status() == WL_CONNECTED) {
    Blynk.connect(5);
  }
}

void loop()
{
  if (WiFi.status() == WL_CONNECTED) {
    if (Blynk.connected() == true) {
      Blynk.run();
    }
    else {
      Blynk.connect(5);
      Blynk.run();
    }
  }
}

It connects longer than usual if anything is working, but connecting and syncing. If I deny ESP8266 connecting to AP, my code is working after 10 seconds approx. If I’ll allow — it reconnects and works again.
My code working from the start, if I reboot ESP8266, no more pauses on Blynk connecting.

The code needs polishing, though.

2 Likes

@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