Blynk.run without internet freezes off line program

this is the final sketch:

///////////////////////////////////////////////////////////////////////////   
#define BLYNK_PRINT Serial                                               //            
//#define BLYNK_DEBUG                                                    //
#include <BlynkSimpleEsp8266.h> //por el uso de BlynkTimer               //   
#include <ESP8266WiFi.h>                                                 //   
#include <ESP8266mDNS.h>                                                 //   
#include <WiFiUdp.h>                                                     //   
#include <ArduinoOTA.h>                                                  //   
//web server                                                             //   
#include <ESP8266WebServer.h>                                            //   
ESP8266WebServer server(80);                                             //   
                                                                         //   
///////////////////////////USUARIO Y CLAVE OTA/////////////              // 
const char *ssid_AP = "acceso_local_sin_internet";       //              //
const char *password_AP = "internet";                    //              //     
const char* ssid = "linksys";                            //              //
const char* password = "";                               //              //
///////////////////////// FIN USUARIO Y CLAVE OTA//////////              //
//AcĆ” se declaran las variables a monitorear localmente por el web server//

bool LED1status = LOW;
bool LED2status = LOW;
bool findecarreracerrado;
bool findecarreraabierto;
bool estaabriendo;
bool estacerrando;
bool abierto;
bool cerrado;
bool botoncierra;
bool botonabre;
bool variablepare;

////////////////////////////Blynk///////////////////////////////////////////////////////////
char auth[] = "9StmFKRVBTvsSixY3xIJTZx01i3sPvWi"; //otro mio
//char auth[] = "e1861a5b6775474aa770d5df240a5868"; //mio
//char auth[] = "ninguno"; //ivan.arnaez.ia@gmail.com
   BLYNK_WRITE(V0){ bool a = param.asInt();if (a==1){variablepare=1;}  } 
   BLYNK_WRITE(V1){ bool b = param.asInt();if (b==1){botonabre=1;}     }  
   BLYNK_WRITE(V2){ bool c = param.asInt();if (c==1){botoncierra=1;}   }                
   WidgetLED led1 (V5); //abriendo
   WidgetLED led2 (V6); //cerrando 
  BlynkTimer timer;
void leds(){ //V5 y V6
   bool a1 = digitalRead(D7);
  if (a1==1) {led1.on();}
  else {led1.off();}
   bool a2 = digitalRead(D8);
  if (a2==1) {led2.on();}
  else {led2.off();}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////fin Blynk

//////////////////////////////funciones de attachInterrupt/////
void ICACHE_RAM_ATTR  fin_de_carrera(){                      //
                                                             //
   digitalWrite(D7, LOW);                                    //
   digitalWrite(D8, LOW);                                    //
   variablepare=1;                                           //
   Serial.println("fin de carrera");                         //
}                                                            //                                             
/////////////////////////////////////////////////////////////// 

/////////////////////////////////////////////////////////////////////////////SETUP/////

void setup() {
  Serial.begin  (115200);
  delay(100);
  
///////////////////////////////////////// WIFI IP FIJA ////////////////////////////////  
  WiFi.mode(WIFI_AP_STA);                                                            //
  WiFi.softAP(ssid_AP, password_AP);                                                 //
IPAddress local_IP(192, 168, 1, 37);                                                 //
IPAddress gateway(192, 168, 1, 254);                                                 //
IPAddress subnet(255, 255, 255, 0);                                                  //
IPAddress primaryDNS(8, 8, 8, 8);   //optional                                       //
IPAddress secondaryDNS(8, 8, 4, 4); //optional                                       //
if (!WiFi.config(local_IP, gateway, subnet, primaryDNS, secondaryDNS)) {             //
    Serial.println("STA Failed to configure"); }                                     //
  WiFi.begin(ssid, password);                                                        //
  int c;                                                                             // 
  if (WiFi.status() != WL_CONNECTED && c<10) {delay(500);Serial.print (".");c=c++; } //
  Serial.print("IP address: ");Serial.println(WiFi.localIP());                       //
  WiFi.setAutoReconnect(true);                                                       //
///////////////////////////////////////////////////////////////////////////////////////
  
////////////////////////////////////Blynk setup///////////////////////
                                                                    //
Blynk.config(auth);                                                 //
if (WiFi.status() == WL_CONNECTED) {Serial.println("conectado");    //
    Blynk.connect(5);Serial.println ("Blynk connect");}             //
                                                                    //
timer.setInterval(2000L, leds);                                    //
timer.setInterval(100L, lup);                                      //
                                                                    //
                                                                    //
//////////////////////////////////////////////////////////////////////
 
///////////////////////////////////////////////////////////////////////////OTA//     //
  ArduinoOTA.onStart([]() {                                                   //     //
    String type;
    if (ArduinoOTA.getCommand() == U_FLASH) {
      type = "sketch";
    } else { // U_SPIFFS
      type = "filesystem";
    }

    // NOTE: if updating SPIFFS this would be the place to unmount SPIFFS using SPIFFS.end()
    Serial.println("Start updating " + type);
  });
  ArduinoOTA.onEnd([]() {                                                     //     //
    Serial.println("\nEnd");
  });
  ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {       //     //
    Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
  });
  ArduinoOTA.onError([](ota_error_t error) {                                  //     //
    Serial.printf("Error[%u]: ", error);
    if (error == OTA_AUTH_ERROR) {
      Serial.println("Auth Failed");
    } else if (error == OTA_BEGIN_ERROR) {
      Serial.println("Begin Failed");
    } else if (error == OTA_CONNECT_ERROR) {
      Serial.println("Connect Failed");
    } else if (error == OTA_RECEIVE_ERROR) {
      Serial.println("Receive Failed");
    } else if (error == OTA_END_ERROR) {
      Serial.println("End Failed");
    }
  });
  ArduinoOTA.begin();                                                         //     //
  Serial.println("OTA Ready");                                                //     //
  Serial.print("IP address: ");                                               //     //
  Serial.println(WiFi.localIP());//////////////////////////////////////////OTA//  


  ///////////////////////////Funciones asociadas a web server (botones)///////
  server.on("/", handle_OnConnect);
  server.on("/emergencia_on", handle_emergenciaon);
  server.on("/emergencia_off", handle_emergenciaoff);
  server.on("/cerrando_", handle_cierra);
  server.on("/abriendo_", handle_abre);
  server.onNotFound(handle_NotFound);
  server.begin();
  Serial.println("HTTP server started");
  /////////////////////////////////////////////////////////////////////////////
  pinMode(D1,INPUT_PULLUP);// sensor abierto 
  pinMode(D2,INPUT_PULLUP);// sensor cerrado 
  pinMode(D5, OUTPUT);// triac  
  pinMode(D7, OUTPUT);// rele abre 
  pinMode(D8, OUTPUT);// rele cierra 
  digitalWrite(D5, LOW);
  digitalWrite(D7, LOW);
  digitalWrite(D8, LOW);
  botonabre=0;
  botoncierra=0;
 attachInterrupt(digitalPinToInterrupt(D1), fin_de_carrera, FALLING);
 attachInterrupt(digitalPinToInterrupt(D2), fin_de_carrera, FALLING);
}
///////////////////////////////////////////////////////////////////////////////////////loop
void loop() {
  Blynk.run();
  ArduinoOTA.handle();
  server.handleClient();
  timer.run();
 } ///////////////////////////////////////////////////////////////////////////////////////////////////////////fin de loop
void lup(){
if (variablepare==1){pare();}
findecarreraabierto = digitalRead(D1);
findecarreracerrado = digitalRead(D2);
if (estaabriendo==1 && findecarreraabierto==0){ pare();Serial.println("abierto");}
if (estacerrando==1 && findecarreracerrado==0){ pare();Serial.println("cerrado");}
if(botonabre==1    && findecarreraabierto==1 && estaabriendo==0 && variablepare==0){
  pare();
  timer.setTimeout(500,abre);
  Serial.println("abriendo");}
if (botoncierra==1  && findecarreracerrado==1 && estacerrando==0 && variablepare==0){
  pare();
  timer.setTimeout(500,cierra);
  Serial.println("cerrando");}
}

void pare(){
  Serial.println("pare"); 
     digitalWrite(D5, LOW);
     digitalWrite(D7, LOW);
     digitalWrite(D8, LOW);
     botonabre=0;
     botoncierra=0;
     estaabriendo=0;
     estacerrando=0;
     variablepare=0;
}
void cierra(){Serial.println("cierra");
    digitalWrite(D8, HIGH);
    timer.setTimeout(50,triac);
    estacerrando=1;
}
void abre(){Serial.println("abre");
    digitalWrite(D7, HIGH);
    timer.setTimeout(50,triac);
    estaabriendo=1;
}

void triac(){
 digitalWrite(D5, HIGH);
}
////////////////////////////////////////////////web server
void handle_OnConnect() {
  LED1status = LOW;
  LED2status = LOW;
  Serial.println("GPIO7 Status: OFF | GPIO6 Status: OFF");
  server.send(200, "text/html", SendHTML(LED1status,LED2status)); 
}

void handle_emergenciaon(){
  variablepare=1;
  server.send(200, "text/html", SendHTML(false,HIGH));
}

void handle_emergenciaoff(){
  server.send(200, "text/html", SendHTML(true,LOW));
}
void handle_cierra() {
  botoncierra=1;
  LED2status = HIGH;
  Serial.println("html cierra ");
  server.send(200, "text/html", SendHTML(LED1status,false)); 
}
void handle_abre() {
  botonabre=1;
  LED2status = LOW;
  Serial.println("html abre ");
  server.send(200, "text/html", SendHTML(LED1status,false)); 
}
void handle_NotFound(){
  server.send(404, "text/plain", "Not found");
}

String SendHTML(uint8_t led1stat,uint8_t led2stat){
  String ptr = "<!DOCTYPE html> <html>\n";
  ptr +="<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n";
  ptr +="<title>Porton automatico </title>\n";
  ptr +="<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}\n";
  ptr +="body{margin-top: 50px;} h1 {color: #444444;margin: 50px auto 30px;} h3 {color: #444444;margin-bottom: 50px;}\n";
  ptr +=".button {display: inline-block;width: 80px;height: 80px; background-color: #1abc9c;border: none;color: white;padding: 13px 30px;text-decoration: none;font-size: 25px;margin: 0px auto 35px;cursor: pointer;border-radius: 4px;}\n";
  ptr +=".button-on {background-color: #1abc9c;}\n";
  ptr +=".button-on:active {background-color: #BB070C;}\n";//16a085
  ptr +=".button-off {background-color: #1abc9c;}\n"; //34495e
  ptr +=".button-off:active {background-color: #BB070C;}\n";//2c3e50
  ptr +=".button1 {display: block;width: 200px;height: 60px; background-color: #1abc9c;border: none;color: white;padding: 13px 13px;text-decoration: none;font-size: 20px;margin: 0px auto 15px;cursor: pointer;border-radius: 4px;}\n";
  ptr +=".button1-off {background-color: #1abc9c;}\n";
  ptr +=".button1-on:active {background-color: #BB070C;}\n";//16a085
  ptr +=".button1-on {background-color: #BB070C;font-size: 40px;}\n"; //34495e
  ptr +=".button1-off:active {background-color: #2c3e50;}\n";
  ptr +="p {font-size: 14px;color: #888;margin-bottom: 10px;}\n";
  ptr +="</style>\n";
  ptr +="</head>\n";
  ptr +="<body>\n";
  ptr +="<h1>   </h1>\n";
   // ptr +="<h3>DOS BOTONES</h3>\n";
  
  if(led2stat)
  {ptr +="<a class=\"button1 button1-off\" href=\"/emergencia_off\">STOP activado       pulse para desactivar</a>\n";}
  else
  {ptr +="<a class=\"button1 button1-on\" href=\"/emergencia_on\">STOP</a>\n";}
  ptr +="<h3> </h3>\n";
  ptr +="<p>PORTON</p><a class=\"button button-off\" href=\"/abriendo_\">ABRE</a><a>     </a><a class=\"button button-off\" href=\"/cerrando_\">CIERRA</a>\n";//}
  ptr +="</body>\n";
  ptr +="</html>\n";
  return ptr;
}

Normally, you should declare variables that will be changed inside an interrupt as volatile, but in your case I think you get away without doing this because you are using a Boolean variable which is only one byte in size. But, if you change your code in future, or use interrupts again, then you should understand why volatile variable types are neededā€¦

Anyway, Iā€™m glad you managed to get it working and thanks for sharing your working code.

Pete.

1 Like

There is another thing related to same problem: when there isnā€™t internet the local web server is too slow, also the wifi on board for local access isnā€™t broadcasting the ssid.