Blynk 2.0 connection/provisioning handler

Can anyone point me to a good tutorial or example or community discussion of how to handle wifi and provisioning in a non-blocking way. The project needs to run whether or not the customer has bothered to provision it and whether or not there is wifi available. Connecting to the Blynk server is optional. I have been modifying the Edgent example but I keep ending up with the ESP32 resetting or blocking code which will not let the product code run. If I could get to the point where I can get an LED to blink with poor or no existent wifi and credentials, I think I could use Blynk in the product. Thanks!!

Hey there,

You can try this :
https://mega.nz/file/YQdDTAQA#OBWgZU-dA8EvO7J_M1anDudmwnBImAHmfvaQC3Ik7z8

This is a sketch to control 2ch relay using the app and switches when there’s internet connection and switches only when you’re offline

1 Like

Thanks. It still hangs if it’s not provisioned. I was hoping the Blynk timer would run if there was no connections or provision but they also seem to be blocked. I may have a separate processor handle the real time stuff and just use Blynk for the comms.
Thanks again, much appreciated.

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.