BLYNK
BLYNK.IO       📲 GETTING STARTED       đź“— DOCS       👉 SKETCH BUILDER

Need help with this code (run the code if there is no internet or wifi)

i am making a project of standalone ESP8266 with single channel relay with a synced physical button. the code works fine. i just want to run the code if there is no internet or wifi is off.
The code does not run without Internet.
here is my code

#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>

// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "88decc9cb88340c9a5bead06423469d3";

// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "Tesla";
char pass[] = "3015854308";

// Set your LED and physical button pins here
const int ledPin = 0;
const int btnPin = 2;

BlynkTimer timer;
void checkPhysicalButton();

int ledState = LOW;
int btnState = HIGH;

// Every time we connect to the cloud...
BLYNK_CONNECTED() {
  // Request the latest state from the server
  Blynk.syncVirtual(V2);

  // Alternatively, you could override server state using:
  //Blynk.virtualWrite(V2, ledState);
}

// When App button is pushed - switch the state
BLYNK_WRITE(V2) {
  ledState = param.asInt();
  digitalWrite(ledPin, ledState);
}

void checkPhysicalButton()
{
  if (digitalRead(btnPin) == LOW) {
    // btnState is used to avoid sequential toggles
    if (btnState != LOW) {

      // Toggle LED state
      ledState = !ledState;
      digitalWrite(ledPin, ledState);

      // Update Button Widget
      Blynk.virtualWrite(V2, ledState);
    }
    btnState = LOW;
  } else {
    btnState = HIGH;
  }
}

void setup()
{
  // Debug console
  Serial.begin(9600);

  Blynk.begin(auth, ssid, pass);
  // You can also specify server:
  //Blynk.begin(auth, ssid, pass, "blynk-cloud.com", 80);
  //Blynk.begin(auth, ssid, pass, IPAddress(192,168,1,100), 8080);

  pinMode(ledPin, OUTPUT);
  pinMode(btnPin, INPUT_PULLUP);
  digitalWrite(ledPin, ledState);

  // Setup a function to be called every 100 ms
  timer.setInterval(100L, checkPhysicalButton);
}
void loop()
{
    Blynk.run();
  timer.run();
}

use Blynk.config and Blynk.connect instead Blynk.begin

1 Like
1 Like

I have successfully did it, Thank you so much for your help, wish i could buy you a cup of coffee :slight_smile: . This code works like a charm on stand alone esp8266 with single channel relay with sync button state and also physcial button connected to gpio 2 + GND (push button). Whether wifi is off or there is no internet it works and when internet comes back it reconnects to blynk server. i hope this code will help many many people. Thanks a bunch. here is picture of my prototype project, i am going to build more for my smart home.

/*************************************************************
  Download latest Blynk library here:
    https://github.com/blynkkk/blynk-library/releases/latest

  Blynk is a platform with iOS and Android apps to control
  Arduino, Raspberry Pi and the likes over the Internet.
  You can easily build graphic interfaces for all your
  projects by simply dragging and dropping widgets.

    Downloads, docs, tutorials: http://www.blynk.cc
    Sketch generator:           http://examples.blynk.cc
    Blynk community:            http://community.blynk.cc
    Follow us:                  http://www.fb.com/blynkapp
                                http://twitter.com/blynk_app

  Blynk library is licensed under MIT license
  This example code is in public domain.

 *************************************************************

  This example shows how to synchronize Button widget
  and physical button state.

  App project setup:
    Button widget attached to V2 (Switch mode)
 *************************************************************/

/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial


#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>

// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "xxxxxxxxxxxxx";

// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "xxxxxxxxx";
char pass[] = "xxxxxx";
char server[] = "blynk-cloud.com";  // URL for Blynk Cloud Server
int port = 8080;

int DeviceLED = 2;
int ReCnctFlag;  // Reconnection Flag
int ReCnctCount = 0;  // Reconnection counter

// Set your LED and physical button pins here
const int ledPin = 0;
const int btnPin = 2;

BlynkTimer timer;
void checkPhysicalButton();

int ledState = LOW;
int btnState = HIGH;


void setup()
{
  Serial.begin(115200);
  pinMode(ledPin, OUTPUT);
  pinMode(btnPin, INPUT_PULLUP);
  digitalWrite(ledPin, ledState);
  

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

  timer.setInterval(1000L, UpTime);

  // Setup a function to be called every 100 ms
  timer.setInterval(100L, checkPhysicalButton);
}

// Every time we connect to the cloud...
BLYNK_CONNECTED() {
  Serial.println("Cconnected");
  ReCnctCount = 0;
  // Request the latest state from the server
  Blynk.syncVirtual(V2);

  // Alternatively, you could override server state using:
  //Blynk.virtualWrite(V2, ledState);
}

// When App button is pushed - switch the state
BLYNK_WRITE(V2) {
  ledState = param.asInt();
  digitalWrite(ledPin, ledState);
}

void checkPhysicalButton()
{
  if (digitalRead(btnPin) == LOW) {
    // btnState is used to avoid sequential toggles
    if (btnState != LOW) {

      // Toggle LED state
      ledState = !ledState;
      digitalWrite(ledPin, ledState);

      // Update Button Widget
      Blynk.virtualWrite(V2, ledState);
    }
    btnState = LOW;
  } else {
    btnState = HIGH;
  }
}

void UpTime() {
  Blynk.virtualWrite(V0, millis() / 1000);  // Send UpTime seconds to App
  Serial.print("UpTime: ");
  Serial.println(millis() / 1000);  // Send UpTime seconds to Serial
  digitalWrite(DeviceLED, !digitalRead(DeviceLED));  // Blink onboard LED
}

void loop()
{
  timer.run();
  if (Blynk.connected()) {  // If connected run as normal
    Blynk.run();
  } else if (ReCnctFlag == 0) {  // If NOT connected and not already trying to reconnect, set timer to try to reconnect in 30 seconds
    ReCnctFlag = 1;  // Set reconnection Flag
    Serial.println("Starting reconnection timer in 30 seconds...");
    timer.setTimeout(30000L, []() {  // Lambda Reconnection Timer Function
      ReCnctFlag = 0;  // Reset reconnection Flag
      ReCnctCount++;  // Increment reconnection Counter
      Serial.print("Attempting reconnection #");
      Serial.println(ReCnctCount);
      Blynk.connect();  // Try to reconnect to the server
    });  // END Timer Function
  }
}
2 Likes

I tried using the code above for an arduino MKR wifi-1010 but it doesn’t work properly. After losing the internet connection, the code runs normal for a few seconds with the physical buttons and then it doesn’t work anymore.

Then the physical buttons only work again when the internet returns again.

Then it locks for a minute and returns to normal operation.

Can someone help me?

Here is the code:

#define BLYNK_PRINT Serial // Comment this out to disable prints and save space

#include <SPI.h>
#include <WiFiNINA.h>
#include <BlynkSimpleWiFiNINA.h>
#include <IoAbstraction.h>
#include <IoAbstractionWire.h>
#include <Wire.h>

// create both an Arduino and an IO expander based IO abstraction
IoAbstractionRef ioExpander = ioFrom8574(0x20);
IoAbstractionRef ioExpander1 = ioFrom8574(0x21);
IoAbstractionRef ioExpander2 = ioFrom8574(0x22);
IoAbstractionRef ioExpander3 = ioFrom8574(0x23);


char auth[] = "XXXXXXX";

char ssid[] = "XXXXX";
char pass[] = "XXXX";

char server[] = "blynk-cloud.com";  // URL for Blynk Cloud Server
int port = 8080;

int ReCnctFlag;  // Reconnection Flag
int ReCnctCount = 0;  // Reconnection counter


// Set your LED and physical button pins here
const int ledPin = 6;
const int btnPin = 7;
int ledState = LOW;  int btnState = HIGH;
int ledState2 = LOW; int btnState2 = HIGH;
int ledState3 = LOW; int btnState3 = HIGH;
int blackout = 0;

BlynkTimer timer;

void checkPhysicalButton();



void setup()
{
  // Debug console
  Serial.begin(9600);
  
 // Blynk.begin(auth, ssid, pass);

  WiFi.begin(ssid, pass);  // Non-blocking if no WiFi available
  Blynk.config(auth, server, port);
  Blynk.connect();
 
  Wire.begin();
  pinMode(ledPin, OUTPUT);
  pinMode(btnPin, INPUT_PULLUP);
  digitalWrite(ledPin, ledState); 
  timer.setInterval(100L, checkPhysicalButton); // Setup a function to be called every 100 ms
  
  // here we set the direction of pins on the IO expander
  ioDevicePinMode(ioExpander, 0, INPUT);
  ioDevicePinMode(ioExpander, 1, INPUT);
  ioDevicePinMode(ioExpander, 2, INPUT);
  ioDevicePinMode(ioExpander, 3, INPUT);
  ioDevicePinMode(ioExpander, 4, OUTPUT);
  ioDevicePinMode(ioExpander, 5, OUTPUT);
  ioDevicePinMode(ioExpander, 6, OUTPUT);
  ioDevicePinMode(ioExpander, 7, OUTPUT);
  }

  BLYNK_CONNECTED() {  

   Serial.println("Cconnected");
  ReCnctCount = 0;
  Blynk.syncVirtual(V2); // Request the latest state from the server
  Blynk.syncVirtual(V3); // Request the latest state from the server
  Blynk.syncVirtual(V4); // Request the latest state from the server
  //Blynk.virtualWrite(V2, ledState); // Alternatively, you could override server state using:

 
}

// When App button is pushed - switch the state
BLYNK_WRITE(V2) {ledState = param.asInt(); digitalWrite(ledPin, ledState);}
BLYNK_WRITE(V3) {ledState2 = param.asInt(); ioDeviceDigitalWrite(ioExpander, 4, ledState2);}
BLYNK_WRITE(V4) {ledState3 = param.asInt(); ioDeviceDigitalWrite(ioExpander, 5, ledState3);}

  
void checkPhysicalButton()
{
ioDeviceSync(ioExpander);

    if (digitalRead(btnPin) == LOW) { 
    if (btnState != LOW) {ledState = !ledState;
    digitalWrite(ledPin, ledState);      
    Blynk.virtualWrite(V2, ledState); }
    btnState = LOW;} else {btnState = HIGH; }

    if (ioDeviceDigitalRead(ioExpander, 0) == LOW) {
    if (btnState2 != LOW) {ledState2 = !ledState2;
    Blynk.virtualWrite(V3, ledState2);
    ioDeviceDigitalWrite(ioExpander, 4, ledState2);} 
    btnState2 = LOW;} else {btnState2 = HIGH;}
  
   

    if (ioDeviceDigitalRead(ioExpander, 1) == LOW) {
    if (btnState3 != LOW) {ledState3 = !ledState3;
    Blynk.virtualWrite(V4, ledState3);
    ioDeviceDigitalWrite(ioExpander, 5, ledState3);} 
    btnState3 = LOW;} else {btnState3 = HIGH;}
}


void loop()
{
   timer.run();  //timer2.run();
    if (Blynk.connected()) {  // If connected run as normal
    Blynk.run();
  } else if (ReCnctFlag == 0) {  // If NOT connected and not already trying to reconnect, set timer to try to reconnect in 30 seconds
    ReCnctFlag = 1;  // Set reconnection Flag
    Serial.println("Starting reconnection timer in 30 seconds...");
    timer.setTimeout(30000L, []() {  // Lambda Reconnection Timer Function
      ReCnctFlag = 0;  // Reset reconnection Flag
      ReCnctCount++;  // Increment reconnection Counter
      Serial.print("Attempting reconnection #");
      Serial.println(ReCnctCount);
      WiFi.begin(ssid, pass);  // Non-blocking if no WiFi available
      Blynk.config(auth, server, port);
      Blynk.connect();  // Try to reconnect to the server
    });  // END Timer Function
  }
}

Could you provide us serial monitor screenshot when connection is down?

1 Like

When showing the messages below that the arduino is stuck, the buttons do not work.

Attempting reconnection # 1
[124900] Connecting to blynk-cloud.com:8080

Attempting reconnection # 2
[182649] Connecting to blynk-cloud.com:8080

It only works when the message below appears:

Starting reconnection timer in 30 seconds…

So are you saying that the buttons so work for the 30 seconds between re-connection attempts?
If so, that’s different to what you said here:

Pete.

Sorry if I wasn’t clear.

I will explain the steps:

The internet goes down:

The buttons work until the message appears on the serial monitor:

Attempting reconnection # 1
[124900] Connecting to blynk-cloud.com:8080

When the message appears:

Starting reconnection timer in 30 seconds…

the buttons work again and stay in this cycle until the internet connection is reestablished.

Thanks

Take a look at my new code…it works flawlessly.

So, maybe the solution is that you do one or more of the following…

  1. reduce the re-connection attempts from 2 to 1
  2. increase the timeout timer delay so that its longer
  3. specify a timeout for Blynk.connect by using Blynk.connect(xx)

Pete.

2 Likes

When blynk is trying to connect to the server, code is blocked a few seconds.
There is now available solution to avoid that.
The only way to passthrough is to use ESP32.

I think @khoih may also have an alternative solution.

Pete.

If the switch operation is so critical for you that you can’t wait in max (yet configurable) 30s, the best way to do is to use ISR (directly or via Hardware Timer Interrupt).

There are so many discussions in the forum about this issue, you can just do some searching and will find them.

For example:





But using ISR correctly is not a simple task, you have to spend some time to study and use it correctly or the percentage of crashing is 100%.

1 Like

Why do I only use esp32 to avoid this problem? I am using MKR wifi 1010 and it is as powerful as esp32.

I wonder if there is any other solution without having to migrate to esp32

Thanks for the answer, but I don’t think it would be useful to control all the buttons on my home automation.

Because ESP32 is a two cores, but not MRK !
So, with ESP32 you can run Blynk.run on one core, no worry if it’s hanging , the other core, continue to run.
Else, use the alternative ISR solution as @khoih suggested you.

1 Like

If you have a serious home automation system then I think you’re using the wrong topology if you’re running Blynk on each device.

Life gets much easier when you have one gateway which talks to Blynk, and then multiple devices which talk to that gateway - using MQTT messaging.
Yes, you still need to deal with situations where the devices cant connect to the MQTT server and you want them to operate in stand-alone ,mode, but this scenario happens less often that an internet outage, and the re-connection routines can be much more seamless.

This approach makes integration with other services, such as Amazon Alexa Zigbee, cloud services etc much simpler. It also makes Blynk simply an app interface, rater than the core functionality within the system. This makes it easier to either swap to a different app front-end, or have multiple user interface systems such as Nextion touch screens - which give you almost unlimited user interface design options.

Pete.

Thanks for the advice, I’m doing the integration with Jarvis iot and blynk.

But I will research further on using other ways to create a 100% flawless system.

I think at the moment the solution for me is to install the local blynk server on a raspberry so that there is no problem when I lose the internet, the code does not block. And to use remotely I will try to use the Blynk API to update the app.

What do you think of this?