Widgets with Interrupts: does the library get suspended? (SOLVED)

Hi, I’m continuing my tests of the Blynk library and this time I decided to mix a few Widgets and testing interrupts as well. I got the inputs from the various test programs provided with the library:

  1. A Value Display shows some sequential values generated using millis() and periodically published to the could server using the SimpleTimer. This should simulate the readings from a set of sensors.

  2. I added a physical switch button tied to an interrupt line and my goal is to display the status of the button using a couple of LEDs in the Blynk app that are turned on alternatively (just for fun…).

This is what I observe:

A) It seems a large number of reconnect to the servers are needed, but this could be a temporary (hopefully) server issue…

B) As the program starts, the timer function periodically (1 s) publishes the simulated sensor values
When I push the physical button the ISR is entered and the the LEDS in the app are turned on/off,

C) After a few clicks of the switch button, the timer callback is called NO MORE and the values no more updated, either the periodically generated ones and the LED values-

D) The ISR is correctly called, given the Serial printouts.

So it seems that after a few clicks the library enters a “suspension status” and the app is no more updated.

Considering I am calling the blynk functions either from within an ISR (as in the button example) and in the main program, I think the blynk functions are not re-entrants of “interrupt safe”.

Is this the case ? Any suggestion?

In the following text you can see the source code (if you want to test) as well as the Serial printout.

Best regards
Luciano

//************************************
// LEDs, Interrupt Switch and Display
//************************************

#define BLYNK_PRINT Serial    // Comment this out to disable prints and save space
#include <SPI.h>
#include <Ethernet.h> 

#include <BlynkApiArduino.h> 
#include <BlynkSimpleEthernet.h> 
#include <BlynkWidgets.h>
#include <WidgetBridge.h>
#include <WidgetLED.h>
#include <SimpleTimer.h>

#define SWITCH_PIN 2

char auth[] = "token";

// assign a MAC address for the ethernet controller.
// fill in your address here:
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

// assign an IP address for the controller:
IPAddress ip(192, 168, 1, 113);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);
IPAddress dns_ip (192, 168, 1, 1);
IPAddress subnet_mask(255, 255, 255, 0); 

IPAddress blynk_server_ip (45, 55, 195, 102);

SimpleTimer timerSensors;

WidgetLED led1(1);
WidgetLED led2(2);

//==========================================================
// Callback to update Blynk Virtual Pin is button is pressed
//==========================================================
void checkSwitch() {
  Serial.print("ISR\n");

  if (digitalRead(SWITCH_PIN) == 1) {
      led1.on();
      led2.off();
      Serial.print("SWITCH is ON\n");
  } else {    
      led1.off();
      led2.on();
      Serial.print("SWITCH is OFF\n");
  }

}

//====================
//  sendSensorValues: simulates sensor values
//====================
void sendSensorValues() {

    int value1=0;    
    int value2=0;
    
    value1 = millis()/1000;
    value2 = millis()/100;
    
    Serial.print("Values: v1=");
    Serial.print(value1, 1);
    Serial.print(",\tv2=");
    Serial.println(value2, 1);
    
    // Publish simulated sensor values to Blynk
    Blynk.virtualWrite(10, value1);
    Blynk.virtualWrite(11, value2);
}
 
//====================
//        SETUP
//====================
void setup() {
  
  Serial.begin(115200);
  
  pinMode(SWITCH_PIN, INPUT);
  attachInterrupt(0, checkSwitch, CHANGE);
  
  Blynk.begin(auth, /*"cloud.blynk.cc"*/blynk_server_ip, 8442, ip, dns_ip, gateway, subnet_mask, mac);
  while (!Blynk.connect()) {
    // Wait until connected
  }

  Serial.println("Connected to Blynk, starting... ");
 
  led1.on();
  led2.on();
 
  timerSensors.setInterval(1000, sendSensorValues);

  // give the sensor and Ethernet shield time to set up:
  delay(1000);

}


//====================
//       LOOP
//====================

void loop() { 
  timerSensors.run();
  Blynk.run();
}

============
OUTPUT

[0] Using static IP
[0] Blynk v0.2.1
[1300] My IP: 192.168.1.113
[1301] Connecting to 45.55.195.102:8442
[8122] Connecting to 45.55.195.102:8442
[14944] Connecting to 45.55.195.102:8442
[52245] Connecting to 45.55.195.102:8442
[89545] Connecting to 45.55.195.102:8442
[126846] Connecting to 45.55.195.102:8442
[127075] Ready!
Connected to Blynk, starting... 
Values: v1=128,	v2=1280
Values: v1=129,	v2=1290
Values: v1=130,	v2=1300
Values: v1=131,	v2=1310
Values: v1=132,	v2=1320
Values: v1=133,	v2=1330
Values: v1=134,	v2=1340
Values: v1=135,	v2=1350
Values: v1=136,	v2=1360
Values: v1=137,	v2=1370
Values: v1=138,	v2=1380
Values: v1=139,	v2=1390
Values: v1=140,	v2=1400
Values: v1=141,	v2=1410
Values: v1=142,	v2=1420
Values: v1=143,	v2=1430
Values: v1=144,	v2=1440
ISR
SWITCH is ON
ISR
SWITCH is OFF
Values: v1=145,	v2=1450
Values: v1=146,	v2=1460
Values: v1=147,	v2=1470
Values: v1=148,	v2=1480
ISR
SWITCH is ON
ISR
SWITCH is OFF
Values: v1=149,	v2=1490
Values: v1=150,	v2=1500
Values: v1=151,	v2=1510
ISR
SWITCH is ON
ISR
SWITCH is OFF
Values: v1=152,	v2=1520
Values: v1=153,	v2=1530
Values: v1=154,	v2=1540
ISR
SWITCH is ON
ISR
SWITCH is OFF
ISR
SWITCH is ON
ISR
SWITCH is OFF

Anyone ?
This really seems a weird interaction due to the blynk APIs called from within an interrupt routine.

Please advise ?

Thanks
Luciano

Ok, solved, I had to wrap any Blynk function outside the ISR between the noInterrupts() and interrupts() Arduino functions.
This confirms the Blynk functions are not re-entrant.

Bye
Luciano

3 Likes