How to add an attachInterrupt using a virtual pin

Hi everyone
Here’s the thing
I want to make a this project
It keeps reading data every 10 seconds and shows the median value
BUT, if suddenly the user pushes “Calibrar” button in that moment it should start reading again and save the median value
I’m struggling with attachInterrupt since I’m not using any physical button
Is there any way to do it?
Let me attach my code

#define BLYNK_TEMPLATE_ID "TMPLI1MfuCkZ"
#define BLYNK_DEVICE_NAME "PHumedadSustratoMed"

#define BLYNK_FIRMWARE_VERSION        "0.1.0"
#define BLYNK_PRINT Serial
#define APP_DEBUG

#define USE_ESP32S2_DEV_KIT

#include "BlynkEdgent.h"
#include "QuickMedianLib.h"

unsigned long tempRef1 = millis();
unsigned long tempRef2 = millis();
int vector[10];
int medicion;
int med;
int humedadRef;
bool bCalibrar;

void setup()
{
  Serial.begin(115200);
  delay(100);

  BlynkEdgent.begin();
}

void loop()
{
  BlynkEdgent.run();

  lecturaMediana();
  Serial.print("\n\tLectura humedad ADC:\t Humedad referencia calibrada: ");
  Serial.print("\n\t");
  Serial.print(med);
  Serial.print("\t");
  Serial.print(humedadRef);  
  while (bCalibrar != 0) //Si se pulsa el boton virtual
  {
    Serial.print("\n\t--------------");
    Serial.print("Calibrando");
    Serial.print("\n\t--------------");

    calculoMediana();
    humedadRef = med;
    Serial.print("\n\tHumedad Referencia: ");
    Serial.print(humedadRef);
  }

}

void lecturaMediana()
{
  for (int i = 0; i < 10; i++)
  {
    medicion = analogRead(33);
    vector [i] = medicion;
    delay(1000);
  }
  med = QuickMedian<int>::GetMedian(vector, 10);
}

void calculoMediana()
{
  for (int i = 0; i < 10; i++)
  {
    medicion = analogRead(33);
    vector [i] = medicion;

    tempRef1 = millis();
    while ((millis() - tempRef1) <= 1000)
    {
      //se queda aqui sin hacer nada hasta que transcurra 1 segundo
    }
  }



  for (int i = 9; i >= 0; i--)
  {
    Blynk.virtualWrite(V1, i);
    tempRef2 = millis();
    while ((millis() - tempRef2) <= 1000)
    {
      //se queda aqui hasta que pase 1s
    }
  }
  med = QuickMedian<int>::GetMedian(vector, 10);
}

BLYNK_WRITE(V0)
{
  bCalibrar = param.asInt();
}

Thanks in advance

You can’t use attachinterrupt to a virtual pin.
You should use a flag to ignore the “calibrar” button

Thanks for your answer
Does it exist any way to interrupt the flow of the program?
I mean, if the user pushes the button, some other part of the code starts to run, just like interruptions do

First of all, you should read this
https://docs.blynk.io/en/legacy-platform/legacy-articles/keep-your-void-loop-clean

This is a very basic example of interrupts


const byte LED = 13;
const byte BUTTON = 2;

// Interrupt Service Routine (ISR)
void switchPressed ()
{
  if (digitalRead (BUTTON) == HIGH)
    digitalWrite (LED, HIGH);
  else
    digitalWrite (LED, LOW);
}  // end of switchPressed

void setup ()
{
  pinMode (LED, OUTPUT);  // so we can update the LED
  digitalWrite (BUTTON, HIGH);  // internal pull-up resistor
  attachInterrupt (digitalPinToInterrupt (BUTTON), switchPressed, CHANGE);  // attach interrupt handler
}  // end of setup

void loop ()
{
  // loop doing nothing 
} 

When you use interrupts, there are a few things that you should keep in mind like keep the Interrupt Service Routine (ISR) as short as possible, avoid delay, avoid serial prints, don’t declare any non-static variables inside the handler, etc…
You can search the internet for more details.

1 Like

If you are talking about a widget button attached to a virtual pin then the answer is yes, a callback called BLYNK_WRITE(vPinNumber) is triggered.
You can then get the value of the virtual button (normally 0 or 1 in the case of a button widget).

You should read this for more info…

Pete.

1 Like

I assume you are talking about virtual push button, you don’t have any physical button?
So , has I said, you have to use a flag .
And please, keep your void loop clean as @John93 said.

1 Like