Non blocking WiFi initializing on Edgent

Hello Blynk!
I am migrating to Edgent now for comercial purposes, I had copy a solution from Gunner that enable to run the code even if the wifi is out and reconnect when wifi is back and it worked very well so the machine can still make its duty if some energy shortage freeze the communication with the server, but now in Edgent is so different that I get lost, any clue to imitate the same effect of Gunner solution?
Thank you very much in advance!

In my old code:


void setup()
  WiFi.begin(ssid, pass);  // Non-blocking if no WiFi available
  Blynk.config(auth);
  Blynk.connect();

void loop()
  if (Blynk.connected()) { //IF NOT CONNECTED CONTINUE TO ITS DUTY
      digitalWrite(LED_BUILTIN, HIGH);
      Blynk.run();
      digitalWrite(LED_BUILTIN, LOW);
    }

    if (Blynk.connected() == false) { //OPTIONAL OR RECONNECT BY RESET BUTTON 
        Blynk.connect();
    }

A clue in Edgent code :


void enterError() {
  BlynkState::set(MODE_ERROR);
  
  unsigned long timeoutMs = millis() + 10000;
  while (timeoutMs > millis() || g_buttonPressed)
  {
    delay(10);
    app_loop();
    if (!BlynkState::is(MODE_ERROR)) {
      return;
    }
  }
  DEBUG_PRINT("Restarting after error.");
  delay(10);

  restartMCU();
}

Another clue in Edgent code:


  void run() {
    app_loop();
    switch (BlynkState::get()) {
    case MODE_WAIT_CONFIG:       
    case MODE_CONFIGURING:       enterConfigMode();    break;
    case MODE_CONNECTING_NET:    enterConnectNet();    break;
    case MODE_CONNECTING_CLOUD:  enterConnectCloud();  break;
    case MODE_RUNNING:           runBlynkWithChecks(); break;
    case MODE_OTA_UPGRADE:       enterOTA();           break;
    case MODE_SWITCH_TO_STA:     enterSwitchToSTA();   break;
    case MODE_RESET_CONFIG:      enterResetConfig();   break;
    default:                     enterError();         break;
    }
  }

Maybe is here where I need to start looking?

Hey there,

You can use the app_loop function in the Blynk.Edgent. it should be called periodically, even when BlynkEdgent.run() is blocking,
But, you shouldn’t call any blocking functions in app_loop.

Alternatively, you can try freertos.

1 Like

Hola, tengo el mismo problema. Abrí este foro “Blynk Edgent deja de correr el programa si se corta internet”
Juan93 comento la misma respuesta pero, ahun con eso no me queda claro como modificar el codigo edgent con app_loop para hacer correr el programa sin internet.

I am using Blynk (and BlynkEdgent) to operate and monitor Fermenters and Brite Tanks in a beer brewing application (a tough job but somebody has to do it). Fermenter temperature control and Brite Tank CO2 infusion has to operate even if WiFi or internet goes down (non-blocking is a requirement as in almost any industrial process).

Here is what works for me:

/////////////////////////////////////////////////////////////
// File fermenter.ino:

#define BLYNK_TEMPLATE_ID "xxxxxxxxxxxx"
#define BLYNK_DEVICE_NAME "xxxxxxx"

#define BLYNK_FIRMWARE_VERSION        "0.1.0"

#define BLYNK_PRINT Serial
//#define APP_DEBUG

#include "BlynkEdgent.h"

BlynkTimer timer;
 // other includes, global variables, defines, BLYNK_WRITE(Vx), myTimerEvent(),  etc

void setup(void) {
  BlynkEdgent.begin();
  // Setup a function to be called periodically
  timer.setInterval(2000L, myTimerEvent);
// other setup code required by your application
}

void main_loop() {
  // The code controlling fermenter / brite tank that should run regardless of connection status
}
void loop() {
  BlynkEdgent.run();
  timer.run();
}

//////////////////////////////////////////////////////////////////////
//File BlynkEdgent.h:

void main_loop(); // put function prototype at the top of file

// Edit function app_loop() at the bottom of file
void app_loop() {
    main_loop();        // Changed: call main_loop()
    edgentTimer.run();
    edgentConsole.run();
}

////////////////////////////////////////////////////////////////////////////////
// File ConfigMode.h:

void enterError() {
  BlynkState::set(MODE_ERROR);
  
  unsigned long timeoutMs = millis() + 10000;
  while (timeoutMs > millis() || g_buttonPressed)
  {
    delay(10);
    app_loop();
    if (!BlynkState::is(MODE_ERROR)) {
      return;
    }
  }

  DEBUG_PRINT("Reconnect to WiFi");
  BlynkState::set(MODE_CONNECTING_NET); // Changed: try to reconnect
/*
  DEBUG_PRINT("Restarting after error.");
  delay(10);

  restartMCU();
*/
}

I cannot guarantee that there are no negative side effects. Please use and test to make sure it works for you !!

You need to take care structuring your code like this, because the code that is in your main_loop is in effect in your void loop (because it’s called by app_loop, which is called by BlynkEdgent.run which is called from void loop).

It would be far better to call your main_loop with a non-blocking BlynkTimer.

We all know that you void loop needs to be kept clean, and your current arrangement is just hiding the fact that it’s not as clean as it should be.

Pete.

1 Like

Of course main_loop() should not contain any blocking code, e.g. delays. I forgot to mention that.
Regarding using BlynkTimer, app_loop() calls edgentTimer. Using BlynkTimer, it would still run the main_loop code, just less frequently.

It’s not just delays that can cause problems in the void loop.

Pete.

After much agony I found my solution the the Edgent blocking problem by using the 2nd core in ESP32 (core0). All functions called from there run in core0 even without putting every function -apart form a continuous loop task- into a task. For testing I used the TTGO T Display board I got Leds, buttons, UART (senseairS8 sensor) and the one wire interface for the DHT22 going (that is not super reliable at the best of times). Not tried I2C or interrupts. All this while running the graphic display plotting sensor readings and Blynk doing its work on vPins. In this way there is no funny business happening with timing when wifi goes down (“non-blocking” BlynkTimer is blocking for several seconds without wifi in my test). So my buttons, Leds, and sensors are instant responders, display does not flinch. I only just got it to work so much more testing to be done, but so far so good. It reconnects fine when wifi is back.
There are still some hiccups in Blynk. My mesh network goes through a router to the Net. If the router goes down the device on the Mesh network stays on Mesh wifi but not the cloud (no internet). When the router reconnects to the internet Blynk does not reconnect to the server as it did not detect the disconnect (maybe it does if I wait long enough?) So you have to do the connect to server yourself. Hope this gives some inspiration, maybe someone else has already used this 2nd core option but I have not seen it, super happy to hear about it. Cheers

Try to ping the router :thinking:

Definitely easy solvable. Just thought to mention it as in an industrial situation you wanna consider and test the unforeseen . Cheers

Hi @StefanNZ , can you share the code you made for having running Blynk in Core0?

I’m waiting for some ESP32 to test the same solution in order to avoid the hold introduced by the Blynk routines to my process.