Physical Button freeze (not acting)

Blynk 2.0 version, physical INPUT_PULLUP button.

Hi,
I am trying to use the physical button, tested blynk examples - This example shows how to synchronize Button widget
and physical button state.

During testing, I realized that sometimes the physical button did not act, after pushing it led to not turning on or off.
Or if wifi is lost, also freezing.
Have another example or how can i fix that?
Some forums user advice use separate function as with internet and without internet, also added delay or while commands which blynk not advised users to use it.

here is my code

#define ddd"
#define ddd"

// Send Blynk user messages to the hardware serial port…
#define BLYNK_PRINT Serial 

#include <ESP8266_Lib.h>
#include <BlynkSimpleShieldEsp8266.h>

char auth[] = BLYNK_AUTH_TOKEN;

char ssid[] = "ddd";
char pass[] = "ddd";

// Define your ESP8266 baud rate:
#define ESP8266_BAUD 115200

// Tell the Blynk library to use the  Hardware Serial port 1 for WiFi..
ESP8266 wifi(&Serial3);
const int ledPin = 26;
const int btnPin = 2;



BlynkTimer timer;
void checkPhysicalButton();

int ledState = LOW;
int btnState = HIGH;

BLYNK_CONNECTED() {
 // Request the latest state from the server
 Blynk.syncVirtual(V0);

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

BLYNK_WRITE(V0) {
 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()
{
 
// Initialise the debug serial port
Serial.begin(115200);

// Initialise the Hardware serial1 port…
Serial3.begin(ESP8266_BAUD);
delay(10);

Blynk.begin(auth, wifi, ssid, pass);

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

Blynk.begin is a blocking function and your sketch will never proceed beyond that point if there is no internet.
You need to manage your internet connection yourself, then use Blynk.config and Blynk.begin if the connection was successful.

As far as missed button pushes is concerned, it may be that you didn’t keep it pressed continuously for the 200ms necessary for the timer and denounce code to register the button press.

Pete.

Dear Pete,
inside #include <ESP8266_Lib.h> library which function checking wifi status?
WL_CONNECTED give error. i am using this code

#define BLYNK_DEVICE_NAME "   "
#define BLYNK_AUTH_TOKEN "   "

// Send Blynk user messages to the hardware serial port…
#define BLYNK_PRINT Serial 

#include <ESP8266_Lib.h>
#include <BlynkSimpleShieldEsp8266.h>

char auth[] = BLYNK_AUTH_TOKEN;

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

// Define your ESP8266 baud rate:
#define ESP8266_BAUD 115200

// Tell the Blynk library to use the  Hardware Serial port 1 for WiFi..
ESP8266 wifi(&Serial3);
const int ledPin = 26;
const int btnPin = 2;



BlynkTimer timer;
void checkPhysicalButton();

int ledState = LOW;
int btnState = HIGH;


//for "no server" settings 
int ReCnctFlag;  // Reconnection Flag
int ReCnctCount = 0;  // Reconnection counter

BLYNK_CONNECTED() {
 // Request the latest state from the server
 Blynk.syncVirtual(V0);

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

BLYNK_WRITE(V0) {
 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);
Serial.println(btnPin);
     // Update Button Widget
    // if(ReCnctFlag == 0) {
     Blynk.virtualWrite(V0, ledState); 
    // }
   }
   btnState = LOW;
 } else {
   btnState = HIGH;
 }
}


void setup()
{
 
 
// Initialise the debug serial port
Serial.begin(115200);

// Initialise the Hardware serial1 port…
Serial3.begin(ESP8266_BAUD);
delay(10);

Blynk.begin(auth, wifi, ssid, pass);
Blynk.connect();
 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()
{
   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


   
 }



   
} 

And have there any interrupt command for interrupting blynk server? for physical button i want make interrupt blynk server. I mean this command going to interrupt blynk when is physical button is pressed. I would like to do this for security. Because sometimes, despite the fact that there is wifi, the connection to the server is cut off and the button does not work.

I’m not sure if you can get the WiFi connected status when using BlynkSimpleShieldEsp8266.h
If you can, then you’ll need to use the wifi (all lower case) object.

Life would be much easier if you used a NodeMCU or ESP32.

I have no idea what you are asking here. You need to clarify.

Pete.

Let me explain, example - when the physical button is hit, arduino going to turn off or on the pump. Let’s think for a moment that the pump needs to be turned off, but then the connection to the server is lost and the pump will not turn off immediately. If we can immediately interrupt the blynk server, the loop will not freeze and the pump will stop immediately.
I don’t know if my opinion is correct or not, I would like to write a interrupt command for security on all physical buttons.

I read in your previous posts that you mentioned that there is no point in doing Blynk.run () without wifi. I would like to check wifi first and then check blynk.connected ().

That function can be called interrupt or bypass. Important that function not allow freeze loop due to blynk server or another wifi, internet lost.

This approach makes no sense.
If you are able to process code to disconnect from Blynk then you are able to process code to turn off your relay.

Pete.

Dear Pete,
I probably didn’t explain it very well. I don’t want any freezing when the button is pressed. It doesn’t matter if the servers are connected or not, or if there is no internet, or if blynk want to connect to the server.

It works without freezing in the above code, but when blynk try to connect to the blynk server after a certain period of time, the loop freezes and does not perform button its function (checkPhysicalButton()) despite the push of a button.

Dear Pete,
arduino have special interrupt command - attachInterrupt()
Let me check it, maybe I will solve this problem with that command.
I will write result here.
Thanks

Mega has 6 interrupt allowed pins

Mega, Mega2560, MegaADK 2, 3, 18, 19, 20, 21 (pins 20 & 21 are not available to use for interrupts while they are used for I2C communication)

I understood what you were saying, you didn’t understand my answer.
But, the answer is still the same.

I’m well aware of how interrupts work, but they won’t help with your issue. If you do use interrupts on physical buttons then you’ll need to use debounce code within your ISR.

Is there any reason why you’re using an Uno and not a NodeMCU or ESP32 ?

Pete.

a lot pins needed for my project.

  1. 2 temperature sensor
  2. 2 level sensor
  3. 1 outdoor temperature sensor
  4. 6 input for light switch
  5. 12 output for relay
    e.t.c

Pete.

ESP32 development board has 23 GPIO pins.

ESP some pins give HiGH when booting.

so there is no another solution?

pins 5, 14, and 15 only.

Personally, I’d say that you should be re-thinking your device topography.
It very rarely makes sense to have all of your loads and all of your physical switches wired back to a single MCU.
It almost always makes more sense to have a segmented system where your MCUs and relays are located close to the devices that are being controlled.
For example, I have 10 devices in the room where I’m sitting and they all use relays to control devices and all have physical switches and can be controlled via Blynk or Amazon Alexa.
Each device has its load connected directly to it, so they are all connected via WiFi rather than being hard-wired back to a central hub.
If the WiFi or connection to Blynk fails then they continue to work via the physical buttons.
This setup also makes the system extremely flexible and re-configurable.

Even if I were building a system where everything was wired back to a central control box, I wouldn’t use a single MCU for everything, I’d segment my system and not have a single point of failure.

Pete.

1 Like