Blynk.Air with ESP & Sleep Mode (not with Edgent example)

Ok,
I merged this Topic from my quest in Blynk.Air problems - #36 by Y3G
Problem is that I cannot get the Blynk.Air to update my code OTA.
Note that the Edgent Example over OTA works.
But in my Code I am not using the BlynkEdgent.begin()/run(), and rather the Blynk.run().
I was looking into some examples here : https://platformio.org/lib/show/415/Blynk

…but I am not the brightest C-coder…and appreciate any help, especially to understand the DEBUG messages…

HW Info:
ESP8266-12F

The Serial Output:

12:30:17.778 → [2585]
12:30:17.778 → ___ __ __
12:30:17.778 → / _ )/ /_ _____ / /__
12:30:17.778 → / _ / / // / _ / '/
12:30:17.778 → /
//_, /////_
12:30:17.778 → /
__/ v1.0.1 on NodeMCU
12:30:17.778 →
12:30:17.778 → 9 —> is the BlynkState.h enum=“init”
12:30:17.778 → [2599] Connecting to blynk.cloud:80
12:30:18.014 → [2844] <[1D|00|01|00] —my TOKEN------
12:30:18.292 → [3104] >[00|00|01|00|C8]
12:30:18.292 → [3104] Ready (ping: 259ms).
12:30:18.292 → [3104] Free RAM: 49192
12:30:18.372 → [3171] <[11|00|02|00]xver[00]1.0.1[00]h-beat[00]45[00]buff-in[00]1024[00]dev[00]NodeMCU[00]fw-type[00]TMPLRwKDdSO8[00]fw[00]0.1.1[00]build[00]Sep 21 2021 12:09:43[00]tmpl[00]TMPLRwKDdSO8[00]
12:30:18.372 → 9 —> is the BlynkState.h enum=“init”
12:30:18.412 → [3244] <[10|00|03|00|04]vr[00]0
12:30:18.452 → YS:Succeed to return from Blynk.Connect()
12:30:18.452 → 9 —> is the BlynkState.h enum=“init”
12:30:18.452 → YS:On Setup(), TRUE from Blynk.connected()
12:30:18.452 → Boot number: 1
12:30:18.452 → Wake Time = 0.07 seconds
12:30:18.492 → [3311] <[14|00|04|00|06]vw[00]5[00]3
12:30:18.572 → [3378] <[14|00|05|00|0E]vw[00]4[00]0.0180664
12:30:18.572 → [3378] <@[00|06|00|0F]battery__medium
12:30:18.572 → A0 read → 0.02
12:30:18.612 → [3415] >[11|1E]a[00]d
12:30:18.612 → [3415] >ota[00]http://sgp1.blynk.cloud/static/fw_7453373513620572568.bin?token=iSrBWFPW_sZs_F5t_5iG3F2qBm9GSLPX
12:30:18.612 → [3429] >[00|00|02|00|C8]
12:30:18.652 → [3445] <[14|00|07|00|0C]vw[00]2[00]-91.000
12:30:18.652 → RSSI:-91.00
12:30:19.399 → -185.00ºC
12:30:19.399 → Begin SRF
12:30:20.377 → end Iterations: [5198] >[14|00|03|00|06]
12:30:20.377 → [5198] >vw[00]0[00]0
12:30:20.377 → Set digital pin D2 LOW
12:30:20.377 → [5198] >[00|00|06|00|13]
12:30:20.898 → 9 —> is the BlynkState.h enum=“init”
12:30:31.380 → Wake Time = 0.07 seconds
12:30:31.380 → [16199] <[14|00|08|00|06]vw[00]5[00]3
12:30:31.465 → [16271] <[14|00|09|00|0E]vw[00]4[00]0.0180664
12:30:31.465 → [16271] <@[00|0A|00|0F]battery__medium
12:30:31.465 → A0 read → 0.02
12:30:31.539 → [16339] <[14|00|0B|00|0C]vw[00]2[00]-91.000
12:30:31.539 → RSSI:-91.00
12:30:32.259 → -185.00ºC
12:30:32.299 → Begin SRF
12:30:33.289 → end Iterations: [18092] >[00|00|0A|00|13]
12:30:33.769 → 9 —> is the BlynkState.h enum=“init”
12:30:44.296 → Wake Time = 0.07 seconds
12:30:44.296 → [29093] <[14|00|0C|00|06]vw[00]5[00]3
12:30:44.336 → [29162] <[14|00|0D|00|0E]vw[00]4[00]0.0180664
12:30:44.336 → [29162] <@[00|0E|00|0F]battery__medium
12:30:44.376 → A0 read → 0.02
12:30:44.416 → [29229] <[14|00|0F|00|0C]vw[00]2[00]-93.000
12:30:44.416 → RSSI:-93.00
12:30:45.172 → -185.00ºC
12:30:45.172 → Begin SRF
12:30:46.186 → end Iterations: [30982] >[00|00|0E|00|13]
12:30:46.677 → 9 —> is the BlynkState.h enum=“init”

#define BLYNK_TEMPLATE_ID "TMPLRwKDdSO8"
#define BLYNK_DEVICE_NAME "ESP8266"
#define BLYNK_FIRMWARE_VERSION      "0.1.1"
#define APP_DEBUG
#define BLYNK_DEBUG

#include <BlynkSimpleEsp8266.h>
#include <BlynkState.h>
#include <OneWire.h>           // for Temp Diode
#include <DallasTemperature.h>  // for Temp Diode
// -----------------------------Global Variables ---------------------------------
#define TRIGGER 13 // NodeMCU Pin D7=io13 for SFR
#define ECHO    14 // NodeMCU Pin D5=io14  for SFR
//#define TEMP    12 // NodeMCU Pin D6  for TempSensor
const int TEMP = 12; 
const int SWITCH = 5; // IO5=D20 for the LPM ENable 
int iTemp;


OneWire oneWire(TEMP); // TEMP=Temperature=io 12 Setup a oneWire instance to communicate with any OneWire devices
DallasTemperature sensors(&oneWire); // Pass our oneWire reference to Dallas Temperature sensor 

char auth[] = "My TOKEN";
char ssid[] ="My SSID";
char passw[] ="My Password";
float wake_time = (float)millis()/float(1000); // Find out how long since the ESP rebooted
int bootCount = 0;
int wifi_connect_count = 0;  
float sleep_time_minutes =0.5;


BLYNK_CONNECTED() //sets the LED button to OFF at beginning
{
 iTemp=BlynkState::get();
 Serial.println(iTemp);
 Blynk.syncVirtual(V0);  // will cause BLYNK_WRITE(V0) to be executed
}

/*
//--------------- BLYNK.AIR OTA---------------------------------------------------------------

BLYNK_WRITE(InternalPinOTA) {
String overTheAirURL;
extern BlynkTimer edgentTimer;
overTheAirURL = param.asString();

 //overTheAirURL.replace("http://", "https://");

 edgentTimer.setTimeout(2000L, [](){
   // Start OTA
   Blynk.logEvent("sys_ota", "OTA started");

   // Disconnect, not to interfere with OTA process
   Blynk.disconnect();

   BlynkState::set(MODE_OTA_UPGRADE);
 });
}


*/
////-------------------------------------------------  LED Switch On/Off on GPIO 4/D2--------------------------------------------------------
BLYNK_WRITE(V0) // Executes when the value of virtual pin 0 changes
{
 if(param.asInt() == 1)
 {
   // execute this code if the switch widget is now ON
   digitalWrite(4,HIGH);  // Set digital pin IO4=D19 HIGH
   Serial.println("Set digital pin D2 HIGH");
 }
 else
 {
   // execute this code if the switch widget is now OFF
   digitalWrite(4,LOW);  // Set digital pin 2 LOW
   Serial.println("Set digital pin D2 LOW");    
 }
}


void setup()
{
 pinMode(TRIGGER, OUTPUT);
 pinMode(ECHO, INPUT);
 pinMode(TEMP, INPUT); //Temp Sensor 
 pinMode(4,OUTPUT);  // Led Output switch
 pinMode(SWITCH,OUTPUT);  // LPM Output switch
 Serial.begin(115200);
 digitalWrite(SWITCH,HIGH);  // Set digital pin IO5=D20 HIGH
 delay(1000);
 sensors.begin();   // Start the DS18B20 sensor 
    
 WiFi_Connect(ssid,passw,50); // Attempt to connect to Wi-Fi

 if (WiFi.status() == WL_CONNECTED)               // If we managed to connect to Wi-Fi then try to connect to Blynk, else go to sleep
 {
   Serial.println("YS:If we managed to connect to Wi-Fi then try to connect to Blynk, else go to sleep");
   Blynk.config(auth);  // Initialise the Blynk connection settings rest is taken from the TEMPLATE ID
   //Blynk.config(auth, blynk_server, blynk_port);
   iTemp=BlynkState::get();
   Serial.println(iTemp);
   Blynk.connect();                               // Attempt to connect to Blynk
   Serial.println("YS:Succeed to return from Blynk.Connect()");
   iTemp=BlynkState::get();
   Serial.println(iTemp);
 }
 else
 {
   Serial.println ("Wi-Fi connection failed - going to sleep");
   sleep_time_minutes = sleep_time_minutes * 2; // If you enable this line of code the it will make the device go to sleep for twice as long before trying again. Changing to 0.5 would make it try again sooner than normal
   Deep_Sleep_Now(sleep_time_minutes);
 }
if (Blynk.connected()) //= is Boolean TRUE, If we manages to connect to Blynk then carry-on as normal, else go to sleep
 {  
   Serial.println ("YS:On Setup(), TRUE from  Blynk.connected()");
 }
 else
 {  
   sleep_time_minutes = sleep_time_minutes * 2; // If you enable this line of code the it will make the device go to sleep for twice as long before trying again. Changing to 0.5 would make it try again sooner than normal
   Serial.println("FALSE from Blynk.connected(), failed - going to sleep");
   Deep_Sleep_Now(sleep_time_minutes);
 }
 ++bootCount;
 Serial.println("Boot number: " + String(bootCount)); 
// the above is instead the Blynk.begin(auth,ssid ,passw );
}


void loop()
{
 Serial.print("Wake Time = ");
 Serial.print(wake_time);
 Serial.println(" seconds");
 Blynk.virtualWrite(V5,wifi_connect_count);

   
 BatteryLevel();
 SignalStrenght();
 TempValue();
 SensorValue();
   
 Blynk.run(); // Needed to ensure that the Wake Time value is always uploaded to Blynk before going to sleep
 delay(500);
 digitalWrite(SWITCH,LOW);  // Set digital pin IO5=D20 low turn off the supply
 iTemp=BlynkState::get();
 Serial.println(iTemp);
 //Serial.println(BlynkState::StateStr[iTemp]); doesnt work
 delay(500);
 delay(10000);
 //Deep_Sleep_Now(5); // Value in Min
 
}
```cpp

I’d recommend that you start with the full Edgent sketch and leave all of the tabs in place.
Don’t switch to Blynk.run, and explore what happens to the State variable when you trigger an OTA update using Blynk.Air

Then add-in your deep sleep code, and an if statement that block sleep if the State variable indicates that an OTA is in progress.

Pete.

Hi Pete,
Need some elaborations here,

  • when you say “you start with the full Edgent sketch” , do you mean the example?
  • I assume the “tabs in place” are those that coming with the example…
  • what do you mean “don’t switch to Blynk.run”, I am to leave the BlynkEdgent.run in place?
  • Will I have to add in that example the Blynk::get() in order to get the state index?

Thanks
Y3G

Yes. The example without all of the hacking around that you’ve done.

Yes. All of the tabs (.h files) are there for a reason. Leave them in place.

Yes, leave Edgent.run in place if you are using the Edgent sketch.

I don’t know. That’s why I said in your other topic that you should experiment and see if State is available to you, and if it’s not then add your own variable to the OTA tab, which you can check before initiating deep sleep.

Pete.

Hi Pete,
I tried using the example.
I assume I wont be able to get over the Edgent class at all, if I don’t want to mess around with the working code snippets.
The BlynkState::get() shows just the current State as the Edgent.run provoked, it will never show the “OTAFlag”, for that I will have to figure out the OTA.h functions.
What if I use my code and insted the Blynk.run, I will use the BlynkEdgent.run? (though it uses the timers…)
Thanks for all hints


// Fill-in information from your Blynk Template here
#define BLYNK_TEMPLATE_ID "TMPLRH05nwxD"
#define BLYNK_DEVICE_NAME "OTA"
#define BLYNK_FIRMWARE_VERSION        "0.1.1"
#define BLYNK_PRINT Serial
#define APP_DEBUG
#include "BlynkEdgent.h"
#define led 16
int st, iTemp;
String sTemp;

void ledBlink()
{
  if (st == 0)
    {
      digitalWrite(led, HIGH);
      st=1;
      Serial.println("On");
    }
  else
    {
      digitalWrite(led, LOW);
      st=0;
      Serial.println("Off");
    }
   delay(2000);
}



void setup()
{
  Serial.begin(115200);
  delay(100);
  pinMode(led,OUTPUT);
  BlynkEdgent.begin();
 
}


void loop() 
{
  iTemp=BlynkState::get();
  Serial.println(iTemp);
  
  Serial.println("----------------- STarting BlynkEdgent.run----------------------------------------");
  BlynkEdgent.run();
  Serial.println("*************************Exiting BlynkEdgent.run**********************************");
  ledBlink();
   
}

The Seral Output looks like this
13:16:30.932 → [5145] Using Dynamic IP: 192.168.1.154
13:16:30.932 → [5146] CONNECTING_NET => CONNECTING_CLOUD
13:16:30.932 → Exiting BlynkEdgent.run*********
13:16:30.932 → On
13:16:31.349 → 3
13:16:31.349 → ----------------- STarting BlynkEdgent.run----------------------------------------
13:16:47.089 → [21304] Current time: Sat Sep 25 10:16:47 2021
13:16:47.089 → [21304] Connecting to blynk.cloud:443
13:16:49.503 → [23751] Ready (ping: 185ms).
13:16:49.819 → [24059] CONNECTING_CLOUD => RUNNING
13:16:49.819 → Exiting BlynkEdgent.run*********
13:16:49.819 → Off
13:16:49.898 → 4
13:16:49.898 → ----------------- STarting BlynkEdgent.run----------------------------------------
13:16:49.898 → Exiting BlynkEdgent.run*********
13:16:49.938 → On
13:16:50.391 → 4

.
.
.

13:18:05.230 → ----------------- STarting BlynkEdgent.run----------------------------------------
13:18:05.277 → Exiting BlynkEdgent.run*********
13:18:05.277 → On
13:18:05.732 → 4
13:18:05.772 → ----------------- STarting BlynkEdgent.run----------------------------------------
13:18:05.972 → [100221] Disconnected
13:18:06.012 → [100221] RUNNING => OTA_UPGRADE
13:18:06.012 → [100221] Disconnected
13:18:06.012 → [100221] OTA: http://sgp1.blynk.cloud/static/fw_10080139567892926627.bin?token=6SBmU-oQg1wSmFrEZl0c4kgI55kPx6q
13:18:06.012 → [100226] Connecting to sgp1.blynk.cloud:80
13:18:06.540 → [100753] Expected MD5: 162bb07aaa2d767a8f1c9ae13b1b419a
13:18:06.540 → [100754] Flashing…
13:18:11.664 →
10%
20%
30%
40%
50%
60%
70%
80%
90%
100%
13:19:01.714 → [155941] === Update successfully completed. Rebooting.
13:19:01.834 →
13:19:01.834 → ets Jan 8 2013,rst cause:2, boot mode:(3,6)
13:19:01.834 →
13:19:01.834 → load 0x4010f000, len 3664, room 16
13:19:01.834 → tail 0
13:19:01.834 → chksum 0xee
13:19:01.834 → csum 0xee
13:19:01.834 → v39c79d9b
13:19:01.834 → @cp:0
13:19:06.804 → cmp:0
13:19:07.113 → ld
13:19:07.525 →
13:19:07.525 → >[5690]
13:19:07.525 → ___ __ __
13:19:07.525 → / _ )/ /
_____ / /__
13:19:07.525 → / _ / / // / _ / '/
13:19:07.525 → /
//_, /////_
13:19:07.525 → /
__/ v1.0.1 on NodeMCU
13:19:07.525 →
13:19:07.525 → [5692] --------------------------
13:19:07.525 → [5695] Product: OTA
13:19:07.525 → [5697] Firmware: 0.1.1 (build Sep 25 2021 12:30:21)
13:19:07.525 → [5701] Token: …uVX2
13:19:07.525 → [5704] Device: NodeMCU @ 80MHz
13:19:07.525 → [5707] MAC: B4:E6:2D:44:E0:61
13:19:07.525 → [5710] Flash: 4096K
13:19:07.567 → [5712] ESP core: 2.7.2
13:19:07.567 → [5714] ESP SDK: 2.2.2-dev(38a443e)
13:19:07.567 → [5717] Boot Ver: 6
13:19:07.567 → [5719] Boot Mode:1
13:19:07.567 → [5721] FW info: 462608/1634304, MD5:162bb07aaa2d767a8f1c9ae13b1b419a
13:19:07.769 → [5924] Free mem: 31552
13:19:07.769 → [5924] --------------------------
13:19:07.769 → [5924] INIT => CONNECTING_NET
13:19:07.769 → 2
13:19:07.769 → ----------------- STarting BlynkEdgent.run----------------------------------------
13:19:07.769 → [5937] Connecting to WiFi: shavitim
13:19:19.196 → [17384] Using Dynamic IP: 192.168.1.154
13:19:19.196 → [17384] CONNECTING_NET => CONNECTING_CLOUD
13:19:19.236 → Exiting BlynkEdgent.run*********
13:19:19.236 → On
13:19:19.317 → 3
13:19:19.317 → ----------------- STarting BlynkEdgent.run----------------------------------------
13:19:35.430 → [33623] Current time: Sat Sep 25 10:19:35 2021
13:19:35.470 → [33623] Connecting to blynk.cloud:443
13:19:37.677 → [35872] Ready (ping: 32ms).
13:19:37.967 → [36153] CONNECTING_CLOUD => RUNNING
13:19:37.967 → Exiting BlynkEdgent.run*********
13:19:38.007 → Off
13:19:38.054 → 4
13:19:38.054 → ----------------- STarting BlynkEdgent.run----------------------------------------

Well, those numbers make sense…

enum State {
  MODE_WAIT_CONFIG,      0
  MODE_CONFIGURING,      1
  MODE_CONNECTING_NET,   2
  MODE_CONNECTING_CLOUD, 3
  MODE_RUNNING,          4
  MODE_OTA_UPGRADE,      5
  MODE_SWITCH_TO_STA,    6
  MODE_RESET_CONFIG,     7
  MODE_ERROR,            8

So you don’t want to start deep sleep if the value is 5

Pete.

yes, the number make sense, but to provoke it I need to run BlynkEdgent.run instead the Blynk.run and probably need to set up the Blynk.begin…Shortcuts will cause confusion…
OR
How do I ask if the OTA.AIR virtual Pin/Flag has been set in the cloud?

Of course. I’ve been telling you this in your old topic and in this one. What makes you think that Blynk.run is needed for deep sleep?

Pete.

Hi Pete,
I am a bit confused,
I did it because of this post: Beehive connected - #17 by christophebl


…maybe it is an older approach before they wrote the EDGENT class…
Will do another trials.
Thanks

Yes, that was a Legacy sketch.
You can still use Blynk.run with Blynk IoT, if you don’t want to have the Edgent provisioning and OTA functionality, but if you’re using the Edgent sketch then it needs to be Blynk.Edgent.run

Pete.

Hi Pete,
I tried with the BlynkEdgent example. After it worked solely with the OTA, I wanted to add a SleepMode…
but weird things happened…
As soon as it woke up from sleep mode it dropped a “gibbrish” on the serial output without carriage return, as it is stuck somewhere. Only when I disconnected the GPIO16–RST connection it moved on to the normal BLYNK procedure.
I think I am going to rollback…

cpp
// Fill-in information from your Blynk Template here
#define BLYNK_TEMPLATE_ID "TMPLRH05nwxD"
#define BLYNK_DEVICE_NAME "OTA"
#define BLYNK_FIRMWARE_VERSION        "0.1.0"
#define BLYNK_PRINT Serial
#define APP_DEBUG
#include "BlynkEdgent.h"
#define USE_NODE_MCU_BOARD
#define led 16


#include <OneWire.h>           // for Temp Diode
#include <DallasTemperature.h>  // for Temp Diode
// -----------------------------Global Variables ---------------------------------
#define TRIGGER 13 // NodeMCU Pin D7=io13 for SFR
#define ECHO    14 // NodeMCU Pin D5=io14  for SFR
//#define TEMP    12 // NodeMCU Pin D6  for TempSensor
const int TEMP = 12; 
const int SWITCH = 5; // IO5=D20 for the LPM ENable 

int st, iTemp;
String sTemp;

OneWire oneWire(TEMP); // TEMP=Temperature=io 12 Setup a oneWire instance to communicate with any OneWire devices
DallasTemperature sensors(&oneWire); // Pass our oneWire reference to Dallas Temperature sensor 









void setup()
{
  Serial.begin(115200);
  delay(100);
  pinMode(led,OUTPUT);
  sensors.begin();   // Start the DS18B20 sensor 
  BlynkEdgent.begin();
 
}


void loop() 
{
  
  Serial.print ("1. Getting Status ");
  iTemp=BlynkState::get();
  Serial.println(iTemp);
  
  Serial.println("2.---------------- STarting BlynkEdgent.run----------------------------------------");
  BlynkEdgent.run();
  Serial.println("3.************************Exiting BlynkEdgent.run**********************************");
  ledBlink();
  BatteryLevel();
  Serial.println("4.---------------- STarting Blynk.run----------------------------------------");
  Blynk.run();
   Serial.println("5.************************Exiting Blynk.run**********************************");
  delay(5000);
  ESP.deepSleep(0.5*60e6);  // Deep Sleep time is specified in micros
   
}

Change your baud rate to 74880 and you’ll see what messages you’re getting from the board itself.

GPIO16 is the wake up pin but you appear to be using i5 as an LED too?

Pete.

SOLVED!
Found a workaround that worked.
I used the AsyncElegantOTA library (demo can be found here:ESP8266 OTA (Over-the-Air) Updates - AsyncElegantOTA Arduino | Random Nerd Tutorials )
In combination with the Button, when pressed , it does not go to the SleepMode and initiates the OTA update.

cpp
void Elegant_OTA{
  BLYNK_WRITE(V0) // Executes when the value of virtual pin 0 changes
  {
    if(param.asInt() == 1)
    {
      // execute this code if the switch widget is now ON
    
      Serial.println("Button ON from BLYNK_WRITE(V0)");
      for (int i=1;i<60;i++)
      {
        AsyncElegantOTA.loop();
        delay(1000); 
        Serial.print("*");
      }
      
    }
    else
    {
      // execute this code if the switch widget is now OFF
      
      Serial.println("Button OFF from BLYNK_WRITE(V0)");  
    }
  }
}

Advantage: Works in combination with Blynk App/Dashboard and my code!
Disadvantage:

  • You will have to know the ipAdress of the ESP;
  • You will have to open another html file to upload your *bin file, so it does not work with Blynk.Air

If you have another working solution feel free to comment.