How do I implement interrupts in Blynk

I am using Blynk for a project that involves the following:
Geekcreit™ Doit NodeMcu Lua ESP8266 ESP-12E WIFI Development Board
A switch connected directly to a port on the board
A potentiometer connected to an analog port on the board
A DS18S20 temperature probe connected to a port on the board

My Blynk model as seen on the iPad has all these on the application screen plus a button which I use to turn on a LED attached to the board.

Everything functions but the time taken for the button action is very long and just about un-usable.The problem is the temperature probe conversion (where when I delete its code the button result is very fast). Is there a way where I can use an interrupt procedure so that any probe conversion is halted so that the button action has priority as any temperature conversion is of secondary importance and any delay is not a problem?

How often do you read the sensor temp and how do you do that?
Are you using simple timer?
Your code would be the starter point. Could you share it?

I started off using simple timer but removed it thinking it was causing a problem. Even if I didn’t read the sensor very often it could still be a problem if you happened to press the button during a probe conversion read. I cannot remember how to format the code correctly for user friendly Blynk - clicked the preformatted text icon but I don’t think that it is correct.

Not sure what happened to my code sample but here it is again

#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <SimpleTimer.h>
#include <SPI.h> //not sure if this is necessary
#include <Wire.h> 
#include <DallasTemperature.h>
#include <OneWire.h>

/*Is donny1 in Blynk
 * This uses the 
http://www.banggood.com/Geekcreit-Doit-NodeMcu-Lua-ESP8266-ESP-12E-WIFI-Development-Board-p-985891.html
Where Button on Blynk is labelled GP15 which applies to D8 on the Devel board but is GPIO 15
Note that pin 14 in the code is GPIO 14 and on the board is labelled D5 - all very confusing
This works well in conjunction with Blynk
// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
*/
char auth[] = "xxxxxxxxx";
#define ONE_WIRE_BUS 5 //which is D1 on the board
OneWire oneWire(ONE_WIRE_BUS); // Pass oneWire reference to Dallas Temperature probe.
DallasTemperature sensors(&oneWire);

void setup()
{
  Blynk.begin(auth, "xxxxxxxx", "xxxxxxxxxxx");
  // Make pin 14 default HIGH, and attach INT to our handler
  pinMode(14, INPUT_PULLUP);
  sensors.begin();
}
void loop()
{
  Blynk.run();
  // Invert state, since button is "Active LOW"
  int state = !digitalRead(14);
  if (state == 0)
  {
    Blynk.virtualWrite(V1, "OPEN");
  } 
  else
  {
    Blynk.virtualWrite(V1, "CLOSED");
  }
  sensors.requestTemperatures(); // Send the command to get temperatures
  float t = sensors.getTempCByIndex(0);
  Blynk.virtualWrite(10, t);
}

I don’t know what’s going on and as well I posted the WiFi authority so how can I get rid of this post as it is confidential?

Please check how i edited your code

thanks vhymanskyy for the editing as I inadvertently published my WiFi PW details. I have since changed my PW.
However, I would still love to get an answer to my problem.

@psoro is in the right way I think. You should use simpletimer. Check the PushData example from Blynk or find the doucmentation at arduino.cc. It’s really good. The loop() shouldn’t contain anything else but timer.run() and blynk.run(). I highly advice against using interrupts since it could possibly interfere a great deal with Blynk, especially if you have long (10s+) running routines or functions.

Other than that, the standard Arduino interrupt should work to halt everything and do something else. I’m not sure which pins on the ESP are interrupt capable, but that should be easy to find out.

Normally all of them except GPIO 16.

Thanks everyone for the help.
I ended up going back to using Simple Timer plus using a s/w counter to limit the frequency of the temperature conversion - it works well.
There is a slight delay when the button is pressed when the less frequent conversion is happening but I can cope with that. I’m a little bit uncertain about using an interrupt procedure here but in this case it is not necessary. I still don’t know how to format the code to make it more readable in Blynk. Can anyone help here? Thanks.

void RepeatTask()
{
count++;
// Invert state, since button is “Active LOW”
int state = !digitalRead(14);
if (state == 0)
{
Blynk.virtualWrite(V1, “OPEN”);
}
else
{
Blynk.virtualWrite(V1, “CLOSED”);
}
if (count >= 6)
{
sensors.requestTemperatures(); // Send the command to get temperatures
float t = sensors.getTempCByIndex(0);
Blynk.virtualWrite(10, t);
count = 0;
}
}

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

void RepeatTask()
{
  count++;
  // Invert state, since button is "Active LOW"
  int state = !digitalRead(14);
  if (state == 0)
  {
    Blynk.virtualWrite(V1, "OPEN");
  } 
  else
  {
    Blynk.virtualWrite(V1, "CLOSED");
  }
  if (count >= 6)
  {
    sensors.requestTemperatures(); // Send the command to get temperatures
    float t = sensors.getTempCByIndex(0);
    Blynk.virtualWrite(10, t);
    count = 0;
  }
}

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

3 backticks
code
3 backticks

#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <SimpleTimer.h>
#include <SPI.h> //not sure if this is necessary
#include <Wire.h> 
#include <DallasTemperature.h>
#include <OneWire.h>

char auth[] = "xxxxxxxxx";
#define ONE_WIRE_BUS 5 //which is D1 on the board
OneWire oneWire(ONE_WIRE_BUS); // Pass oneWire reference to Dallas Temperature probe.
DallasTemperature sensors(&oneWire);

enum buttonState {
  changeHigh,
  changeLow,
  iddle = 0
};

buttonState state;
SimpleTimer timer;

void setup() {
  // put your setup code here, to run once:
  Blynk.begin(auth, "xxxxxxxx", "xxxxxxxxxxx");
  pinMode(14, INPUT_PULLUP);
  sensors.begin();
  attachInterrupt(digitalPinToInterrupt(14), buttonCallback, CHANGE);
  timer.setInterval(1000, sendTemp);
}

void loop()
{
   //Put Blynk task here
   Blynk.run();
   timer.run();
   //do this stuff if interupt raises flag, has to be done synchronusly
   switch (state) {
      case changeHigh:
        Blynk.virtualWrite(V1, "CLOSED");
        state = iddle;
        break;
      case changeLow:
        Blynk.virtualWrite(V1, "OPEN");
        state = iddle;
        break;
      default: ;
   }
}

void buttonCallback() {
  (digitalRead(14)) ? state = changeHigh : state = changeLow;
}

void sendTemp() {
  sensors.requestTemperatures(); // Send the command to get temperatures
  float t = sensors.getTempCByIndex(0);
  Blynk.virtualWrite(10, t);
}

If you want interupts use this. FYI it’s fine to have this “switch” in loop(). This should work although there might be a mistake or two.

1 Like

Thanks conkerkh. You have introduced me to a couple of new insights such as enum as well as showing the way forward to using interrupts.
However, your interrupt is applied to (14) which is not what I want. My requirement was an interrupt to occur when the button on the dashboard was pressed which is is labelled GP15 which applies to D8 on the Devel board.

The Dallas library’s requestTemperatures() call is blocking - it waits for the conversion to complete by default. In essence, it delays :worried: - the big no-no with cooperative multi-tasking (which is what the example Blynk sketches are doing).

In the Dallas library source, find the call setWaitForConversion(), which takes a bool argument and sets requestTemperatures() to be blocking or non-blocking, accordingly. Set it non-blocking - then waiting for the conversion completion time will be up to you - you’ll need to use a timer and another callback function for that - but in the meanwhile your loop() function can continue running and detect and respond to your button in a more timely manner.

Structuring your code to use interrupts can work but is more complicated and will require more surgery on your existing code than will fixing the library to not block.

Thanks JRobert,
I couldn’t find the Dallas requestTemperatures() call but in this particular case, I am happy with the results I am getting with the existing method. I also used a spare input port to relay back to the Blynk dashboard the result of the button press which works fine and gives me that extra confidence. That doesn’t mean that there is a better method such as what you propose and I may try to use it next time but the degree of difficulty may be beyond my programming skills.

You’re welcome - I’m glad you’ve got something functional.
In case you want to look at it further, the requestTemperatures() call is the 3d to last line in your loop() function (“sensors.requestTemperatures();”). It is the call that starts the temperature conversion (and can wait for up to .750 sec for the data to be ready).

Thanks again jRobert,

I realise where the requestTemperatures() call is in my code. I was looking for ways to implement it in combination with the setWaitForConversion() in the .cpp and .h files but couldn’t find any reference to those calls there. Anyway, all’s good so I’d better quit before I display my ignorance any further.