Blynk 2.0 connection/provisioning handler

You’re welcome.

@jhm802
Can you tell me what’s the problem exactly ?
Does it work ?

If you would like to use blynk without wifi provisioning you can do that, you don’t have to use blynk edgent.

@jhm802 has said that he wants to use provisioning, but for his customers be able to use the devices offline, without them being provisioned, if necessary.

Do you have add my suggestions about how he might achieve that?

I’m away at the moment, and don’t have any equipment that would allow me to investigate how that might be achieved.

Pete.

The sketch I sent him is working okay, I tried it with and without internet connection.

but will it work without being provisioned? That is, brand new device no wifi credentials ever loaded.

I didn’t try, but I guess not.

Just getting back to this.
John93 got me part way there.

  • I added a pullup resistor to IO12 and that caused the “A fatal error occurred: Timed out waiting for packet content” error so my bad on that.
  • I simplified his code so there is only one switch and one output.
  • This works when the device has not been provisioned. Edgent sits waiting for someone to do so but the switch and relay code works perfectly.
  • The problem comes when I turn off my router. I get the following 6 times and then the ESP32 resets
    “Connecting to blynk.cloud:443”
    “Secure connection failed”
  • So most of the way there. If I can get it to stop resetting and patiently wait for the wifi connection to come back and then resume without resetting…

I’ll keep digging but am hoping someone has used Blynk in a product that needs to keep running without resets when wifi is lost.

I turned off my router then I powered the device, it doesn’t reset, everything is okay here.

That’s encouraging, I must have something slightly different due to changing your code or my IDE/Library setup is different.
Blynk library 1.0.1
WiFi101 library 0.16.1
WiFi library 1.2.7 (not sure this is used?)
Arduino IDE 1.8.13
ESP32-WROOM-32D (Dev board)

  • I took your original code, added BLYNK_TEMPLATE_ID and BLYNK_DEVICE_NAME so it would compile.
  • I added “Serial.println(“John93 setup code”);” in your setup() routine so I could see it reset.
  • I uploaded it and toggled the switch a few times to show the relay changing (the program running).
  • I powered off my router and below is the serial output
  • It tries 6 times to reconnect and then reboots (“John93 setup code”);
  • It reboots over and over until I re-power the router, then it recovers.
    What’s your secret :smile:

11:22:50.367 → John93 setup code
11:22:50.459 → [138]
11:22:50.459 → ___ __ __
11:22:50.459 → / _ )/ /_ _____ / /__
11:22:50.459 → / _ / / // / _ / '/
11:22:50.506 → /
//_, /////_
11:22:50.506 → /
/ v1.0.1 on ESP32
11:22:50.506 →
11:22:53.366 → [3030] Using Dynamic IP: 192.168.0.25
11:22:53.366 → [3040] Connecting to blynk.cloud:443
11:22:54.629 → [4301] Certificate OK
11:22:54.866 → [4503] Ready (ping: 200ms).
11:23:19.727 → Switch-1 on
11:23:19.810 → Switch-1 off
11:23:19.855 → Switch-1 on
11:23:20.094 → Switch-1 off
11:23:20.138 → Switch-1 on
11:23:20.183 → Switch-1 off
11:24:05.600 → [75235] Using Dynamic IP: 192.168.0.101
11:24:05.600 → [75245] Connecting to blynk.cloud:443
11:24:23.858 → [93500] Secure connection failed
11:24:23.858 → [93510] Connecting to blynk.cloud:443
11:24:23.858 → [93524] Secure connection failed
11:24:28.870 → [98514] Connecting to blynk.cloud:443
11:24:29.077 → [98726] Secure connection failed
11:24:33.875 → [103516] Connecting to blynk.cloud:443
11:24:34.156 → [103791] Secure connection failed
11:24:45.626 → ets Jun 8 2016 00:22:57
11:24:45.626 →
11:24:45.626 → rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
11:24:45.626 → configsip: 0, SPIWP:0xee
11:24:45.626 → clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
11:24:45.626 → mode:DIO, clock div:1
11:24:45.671 → load:0x3fff0018,len:4
11:24:45.671 → load:0x3fff001c,len:1216
11:24:45.671 → ho 0 tail 12 room 4
11:24:45.671 → load:0x40078000,len:10944
11:24:45.671 → load:0x40080400,len:6388
11:24:45.671 → entry 0x400806b4
11:24:45.943 → John93 setup code
11:24:46.083 → [135]
11:24:46.083 → ___ __ __
11:24:46.083 → / _ )/ /
_____ / /
_
11:24:46.083 → / _ / / // / _ / '/
11:24:46.083 → /
//_, /////_
11:24:46.083 → /
__/ v1.0.1 on ESP32
11:24:46.083 →

11:24:49.008 → [3068] Using Dynamic IP: 192.168.0.101
11:24:49.008 → [3078] Connecting to blynk.cloud:443
11:24:49.054 → [3128] Secure connection failed

May I ask you why are you using wifi101 library ?

I went looking for where the includes might be coming from to collect revisions of as many libraries as I could and found it in WiFi101. So I was guessing which libraries so John93 could verify which revs he was operating under.

What I did discover from your example is that Edgent runs in a state machine (in ConfigMode.h) and calls app_loop() from most of the states, which is where the users code would be run from. I was trying to run it from the main loop() routine. So if you run your code in app_loop, which you did, it calls your code even if it has stuff to do.
There are two timeouts, WIFI_CLOUD_CONNECT_TIMEOUT and WIFI_NET_CONNECT_TIMEOUT, in Settings.h that are set for 30 seconds. If it cannot connect with wifi(NET) or Blynk(CLOUD), within these timeouts, it resets the cpu. I could increase these but it would just reset less often.

  • When something goes wrong, the state machine sets BlynkState to MODE_ERROR, which in turn causes enterError() to be called which resets the CPU

// Edgent state machine:
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;
}
}

The enter Error routine restarts the CPU:

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();
}

So maybe I can re-write this so instead of resetting the CPU, I just restarts the state machine. I was hoping somewhere was an example (template) for us folks that want to run code without the status of the provisioning, wifi or Blynk connection to reset our products.

OK, I tried something that seems to work so far.

  • I created a counter that counts seconds since reboot and Serial print it every second
  • I did a slight modification in the enterError() routine that sends it back to looking for WiFi instead of resetting the MCU.
    Modified enterError():

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;
}
}
Serial.println(“Going back to look for lost WiFi”);
BlynkState::set(MODE_CONNECTING_NET); // go back to trying wifi instead of resetting MCU
/*
DEBUG_PRINT(“Restarting after error.”);
delay(10);

restartMCU();
*/
}

Now it seems to ignore wifi being turned on and off. Probably still some holes but it now seems to be very tolerant of the wifi being disconnected and re-connected. Stay tuned.

2 Likes

What’s your board model ?

Expressif ESP32 -DevKitC V4 wit an ESP32-WROOM-32D module on it.

Thank you so much for posting this! I was facing the same issue with resets and this solved my issue. FYI, I created a task with freeRTOS that runs regardless of provisioning and the state of edgent. As soon as my esp32 board is powered on, the task starts running no matter what edgent is doing.

hello SK-ONE.
could you publish your code? i am also using freertos with blynk but i am having problems, and the documentation about it is not much.
Thank,
Pietro

I used this tutorial. ESP32 Dual Core with Arduino IDE | Random Nerd Tutorials
The only thing I noticed is that you have to pin the new task to core 1. If you pin it to core 0, it will interfere with Blynk.

Hola SK-ONE
Podrías publicar el código para que nos sirva de ejemplo por favor!

Are you free to investigate now?

The OP seemed to have made some progress by the time I returned home, so didn’t bother investigating further.

Pete.