How to read a button status quickly?

Dear all, I have a very simple question related to the read of button status on my projects.
I need to switch on a boiler pressing a phisical button, as well as from the blynk app.
The problem is that the reading of the status is not snapshot, but it requires some seconds. I assume that it depends on other “timer.setInterval” present on setup code.
I would like to avoid to read the button status into “loop” as Blynk recommended, so I used a timer to run the read function every 100ms, but I have always a big delay.
Could you please help me to have a quick button status reads?
Thank you!

...
...
void setup()
{
  Serial.begin(9600);

  pinMode(D6, INPUT);
  pinMode(D7, OUTPUT);

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

  timer.setInterval(60000L, clockDisplay); //invia orario
  timer.setInterval(2000L, statoBoiler); //invia se acceso o spento
  timer.setInterval(5000L, inviaMisuraPotenza); //invia misura assorbimento e potenza
  timer.setInterval(30000L, inviaMisuraTempHum); //invia misura temperatura e umidità
  timer.setInterval(1000L, leggeRS232);
  timer.setInterval(100, ReadButton);
}
...
...
void ReadButton() 
{
int stato = digitalRead(D6);
if (stato == 1){
digitalWrite(D7, HIGH);
else {
digitalWrite(D7, LOW);
}
}
...
...

Go through this topic. You will get an idea on how to send the status of the button.

2 Likes

It would probably help if you posted your full sketch, as it’s difficult to tell what is causing this delay based on this small snippet of code.

By far the best approach is to attach an interrupt to the pin with the physical button attached to it, but this will require a bit of debounce code to be included in the interrupt service routine.

Pete.

Dear Pete, thank you. Hereafter the full sketch. The button read state is in timer.setInterval(100L, statoBoiler) routine

// Monitoraggio qualita'  aria (CO2, TVOC, TEMPERATURA e UMIDITA')
// Scheda da posizionare all'esterno
// 29/08/2022

#define BLYNK_PRINT Serial
#define BLYNK_TEMPLATE_ID "........"
#define BLYNK_DEVICE_NAME "Sensore inquinamento e temperatura"
#define BLYNK_AUTH_TOKEN "................"
#define BLYNK_FIRMWARE_VERSION "1.0.0"

#include <SoftwareSerial.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <SimpleTimer.h>
#include <WidgetRTC.h>
#include <WEMOS_SHT3X.h>

char auth[] = BLYNK_AUTH_TOKEN;
char ssid[] = ".......";
char pass[] = ".........";

#define pinout_d5 D5
#define pin_potenza A0
#define pin_pulsate D3

WidgetRTC rtc;
BlynkTimer timer;
WidgetLED led_boiler(V3);
WidgetMap myMap(V0);
SHT3X sht30(0x45);

SoftwareSerial ss(D6, D7);
LiquidCrystal_I2C lcd(0x27, 16, 2);

char stringa[20];
char appo[20];
int rx_number = 0;
float numero_estratto = 0;
int numero_estratto_int = 0;
float temp_minimo = 50;
float temp_massimo = 0;
float umid_minimo = 100;
float umid_massimo = 0;
float temp_minimo_ext = 50;
float temp_massimo_ext = 0;
float umid_minimo_ext = 100;
float umid_massimo_ext = 0;
float temp_minimo_ext_azzero = 0;
float temp_massimo_ext_azzero = 0;
float umid_minimo_ext_azzero = 0;
float umid_massimo_ext_azzero = 0;
//int index = 0;
//float lat = 12.6341;
//float lon = 41.9966;
boolean anti_r = LOW;
boolean pulsante = LOW;
boolean stato = LOW;

void setup()
{
  Serial.begin(9600);
  ss.begin(9600);

  pinMode(pin_pulsate, INPUT_PULLUP); //Accensione manuale
  pinMode(D6, INPUT); //RX SoftwareSerial
  pinMode(D7, OUTPUT); //TX SoftwareSerial
  pinMode(pinout_d5, OUTPUT);  //relè
  pinMode(pin_potenza, INPUT); //A0 Analogico
  pinMode(D4, OUTPUT);  //led potenza
  digitalWrite (D4, LOW);

  lcd.init();
  lcd.clear();
  lcd.backlight();
  Blynk.begin(auth, ssid, pass);
  rtc.begin();

  timer.setInterval(60000L, clockDisplay); //invia orario
  timer.setInterval(100L, statoBoiler); //invia se acceso o spento e accensione manuale
  timer.setInterval(2000L, inviaMisuraPotenza); //invia misura assorbimento e potenza
  timer.setInterval(10000L, inviaMisuraTempHum); //invia misura temperatura e umidità 
  timer.setInterval(1000L, leggeRS232);
  //timer.setInterval(4000L, gps);
  //timer.setInterval(500L, acc_manuale);

}

// recupera tutti i valori dal server nel caso in cui WeMas si spenga o resetti
BLYNK_CONNECTED() {
  Blynk.syncAll();
}

BLYNK_WRITE(V1) // Button Widget writes to Virtual Pin V1
{
  boolean valore = param.asInt();
  if (valore == 1) {
    digitalWrite(pinout_d5, HIGH);
  }
  else {
    digitalWrite(pinout_d5, LOW);
  }
}

BLYNK_WRITE(V2) // Widget timer writes to Virtual Pin V2
{
  boolean valore = param.asInt();
  if (valore == 1) {
    digitalWrite(pinout_d5, HIGH);
  }
  else {
    digitalWrite(pinout_d5, LOW);
  }
}

// Digital clock display of the time
void clockDisplay()
{
  // You can call hour(), minute(), ... at any time
  // Please see Time library examples for details

  String currentTime = String(hour()) + ":" + minute(); // + ":" + second();
  // String currentDate = String(day()) + " " + month(); // + " " + year();
  Blynk.virtualWrite(V50, currentTime);
  // Blynk.virtualWrite(V51, currentDate);
}

void statoBoiler() //leggo lo stato fisico del pin D5 e del pulsante su D3
{
  // accensione manuale da pulsante
  pulsante = digitalRead (pin_pulsate); //D3
  if (anti_r == LOW && pulsante == LOW)
  {
    stato = !stato;
    digitalWrite (D5, stato);
    if (stato == LOW) {
      Blynk.virtualWrite(V1, 0);
    }
    else {
      Blynk.virtualWrite(V1, 1);
    }

    anti_r == HIGH;
  }
  if (pulsante == HIGH) anti_r = LOW;

  int state = digitalRead(D5);
  if (state == 1) {
    Blynk.setProperty(V3, "color", "#64C800");
    led_boiler.on();
  }
  else {
    Blynk.setProperty(V3, "color", "#FF0000");
    led_boiler.on();
  }
}

/*
  void gps()
  {
  Blynk.virtualWrite(V0, lat, lon);
  }
*/

/*
  void acc_manuale()
  {
  pulsante = digitalRead (pin_pulsate);
  if (anti_r == LOW && pulsante == LOW)
  {
    stato = !stato;
    digitalWrite (D5, stato);
    digitalWrite (D4, stato);
    anti_r == HIGH;
  }
  if (pulsante == HIGH) anti_r = LOW;
  }
*/

void inviaMisuraPotenza()
{

  // misuro la potenza in ingresso =================
  // int lettura_analog = 0;
  float ampere = 0;
  for (byte i = 0; i < 10; i++) { //Esegue l'istruzione successiva 5 volte
    ampere += ((0.0322 * analogRead(pin_potenza) - 23.7) );
    // lettura_analog += analogRead(pin_potenza);
  }
  ampere /= 10; //Calcola la media dei valori letti
  Serial.print("ampere: ");
  Serial.println(ampere);
  // lettura_analog /= 5;
  // Serial.println(lettura_analog);
  // ===================================================

  float potenza = ampere * 220;

  if (ampere < 1) {
    ampere = 0;
    potenza = 0;
  }

  Blynk.virtualWrite(6, potenza);
  Blynk.virtualWrite(7, potenza);
  Blynk.virtualWrite(5, ampere); // invia al pin virtuale 5 il valore della potenza

  if (potenza > 500) {
    digitalWrite(D4, HIGH);
  }
  else
  {
    digitalWrite(D4, LOW);
  }
}

void inviaMisuraTempHum()
{
  if (sht30.get() == 0) {
    //  Serial.print("Temperature in Celsius : ");
    //  Serial.println(sht30.cTemp);
    Blynk.virtualWrite(10, sht30.cTemp);
    // Serial.print("Temperature in Fahrenheit : ");
    // Serial.println(sht30.fTemp);
    // Serial.print("Relative Humidity : ");
    // Serial.println(sht30.humidity);
    Blynk.virtualWrite(12, sht30.humidity);
    // Serial.println();

    if (sht30.cTemp < temp_minimo) {
      temp_minimo = sht30.cTemp;
    }
    if (sht30.cTemp > temp_massimo) {
      temp_massimo = sht30.cTemp;
    }
    if (sht30.humidity < umid_minimo) {
      umid_minimo = sht30.humidity;
    }
    if (sht30.humidity > umid_massimo) {
      umid_massimo = sht30.humidity;
    }

    Blynk.virtualWrite(20, temp_minimo);
    Blynk.virtualWrite(21, temp_massimo);
    Blynk.virtualWrite(30, umid_minimo);
    Blynk.virtualWrite(31, umid_massimo);

  }
  else
  {
    // Serial.println("Error!");
  }
}


void leggeRS232()
{
  while (ss.available() > 0) {
    ss.readBytes(stringa, 20);
    rx_number = atoi(stringa);
    //Serial.println(rx_number);

    if (stringa[0] == '1') {            // ================ umidità - Prima cifra che ricevo dalla SoftwareSerial ========
      appo[0] = stringa[1];
      appo[1] = stringa[2];
      appo[2] = stringa[3];
      appo[3] = stringa[4];
      numero_estratto = atoi(appo);
      //Serial.print("Umidità : ");
      //Serial.println(numero_estratto / 100);

      lcd.setCursor(0, 0);
      lcd.print("U:");
      lcd.setCursor(2, 0);
      lcd.print("    ");
      lcd.setCursor(2, 0);
      lcd.print(numero_estratto / 100, 0); // 1 significa stampare un solo numero decimale
      lcd.setCursor(5, 0);
      lcd.print("%");

      Blynk.virtualWrite(13, numero_estratto / 100);

      umid_minimo_ext_azzero = numero_estratto / 100;
      umid_massimo_ext_azzero = numero_estratto / 100;

      if ((numero_estratto / 100) < umid_minimo_ext) {
        umid_minimo_ext = (numero_estratto / 100);
      }
      if ((numero_estratto / 100) > umid_massimo_ext) {
        umid_massimo_ext = (numero_estratto / 100);
      }
      Blynk.virtualWrite(40, umid_minimo_ext);
      Blynk.virtualWrite(41, umid_massimo_ext);

      lcd.setCursor(6, 0);
      lcd.print("U");

    } else if (stringa[0] == '2') {    // ============== temperatura =================
      appo[0] = stringa[1];
      appo[1] = stringa[2];
      appo[2] = stringa[3];
      appo[3] = stringa[4];
      numero_estratto = atoi(appo);
      //Serial.print("Temp: ");
      //Serial.println(numero_estratto / 100);

      lcd.setCursor(8, 0);
      lcd.print("T:");
      lcd.setCursor(10, 0);
      lcd.print("    ");
      lcd.setCursor(10, 0);
      lcd.print(numero_estratto / 100, 1); // 1 significa stampare un solo numero decimale
      lcd.setCursor(15, 0);
      lcd.print("C");

      Blynk.virtualWrite(14, numero_estratto / 100);

      temp_minimo_ext_azzero = numero_estratto / 100;
      temp_massimo_ext_azzero = numero_estratto / 100;

      if ((numero_estratto / 100) < temp_minimo_ext) {
        temp_minimo_ext = (numero_estratto / 100);
      }
      if ((numero_estratto / 100) > temp_massimo_ext) {
        temp_massimo_ext = (numero_estratto / 100);
      }
      Blynk.virtualWrite(42, temp_minimo_ext);
      Blynk.virtualWrite(43, temp_massimo_ext);


      // TEST EVENT --------------------
      /*
            if ((numero_estratto / 100) > 29)
            {
              Blynk.logEvent("allarme_temperatura");
            }
      */
      // STOP TEST EVENT --------------------


      lcd.setCursor(6, 0);
      lcd.print("T");

    } else if (stringa[0] == '3') {    //================== CO2 ======================
      appo[0] = stringa[1];
      appo[1] = stringa[2];
      appo[2] = stringa[3];
      appo[3] = stringa[4];
      numero_estratto_int = atoi(appo);
      //Serial.print("CO2: ");
      //Serial.println(numero_estratto_int);

      lcd.setCursor(0, 1);
      lcd.print("CO:");
      lcd.setCursor(3, 1);
      lcd.print("     "); //prima cancella il dato vecchio
      lcd.setCursor(3, 1);
      lcd.print(numero_estratto_int);

      Blynk.virtualWrite(15, numero_estratto_int);

      lcd.setCursor(6, 0);
      lcd.print("C");

    } else if (stringa[0] == '4') {   //================== TVOC ========================
      appo[0] = stringa[1];
      appo[1] = stringa[2];
      appo[2] = stringa[3];
      appo[3] = stringa[4];
      numero_estratto_int = atoi(appo);
      //Serial.print("tVOC: ");
      //Serial.println(numero_estratto_int);

      lcd.setCursor(8, 1);
      lcd.print("VOC:");
      lcd.setCursor(12, 1);
      lcd.print("    ");
      lcd.setCursor(12, 1);
      lcd.print(numero_estratto_int);

      Blynk.virtualWrite(16, numero_estratto_int);

      lcd.setCursor(6, 0);
      lcd.print("V");

    }
  }
}

BLYNK_WRITE(V32) {
  boolean azzera = param.asInt();
  if (azzera) {
    temp_minimo = sht30.cTemp;
    temp_massimo = sht30.cTemp;
    umid_minimo = sht30.humidity;
    umid_massimo = sht30.humidity;
    temp_minimo_ext = temp_minimo_ext_azzero;
    temp_massimo_ext = temp_massimo_ext_azzero;
    umid_minimo_ext = umid_minimo_ext_azzero;
    umid_massimo_ext = umid_massimo_ext_azzero;
  }

  Blynk.virtualWrite(20, temp_minimo);
  Blynk.virtualWrite(21, temp_massimo);
  Blynk.virtualWrite(30, umid_minimo);
  Blynk.virtualWrite(31, umid_massimo);
  Blynk.virtualWrite(42, temp_minimo_ext);
  Blynk.virtualWrite(43, temp_massimo_ext);
  Blynk.virtualWrite(40, umid_minimo_ext);
  Blynk.virtualWrite(41, umid_massimo_ext);

}

void loop()
{
  Blynk.run();
  timer.run(); // esegue timer
}

I’d guess that your leggeRS232 function is what’s causing the delays. The while command will halt things until data is received.

Try disabling this timer and see what happens.

Pete.

1 Like