Help With Multiple GetData Instances

Hi All,

I’ll try and give a brief summary of my goal. I have 5 buttons in my Blynk app and I am attempting to tie each one to a specific behaviour I want to be exhibited. I’ve been reading through examples and have tried to implement the timer capabilities as my last issue was overloading the requests by calling to getData within void loop().

Hopefully I’m not over-complicating things with my approach to this problem:

#define BLYNK_PRINT Serial

#include <ESP8266WiFi.h>
#include <SPI.h>
#include <BlynkSimpleEsp8266.h>
#define BLYNK_PRINT Serial

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

BlynkTimer timer;

void behaviour1(){
  //do if button V0 is pressed
  }

void behaviour2(){
  //do if button V4 is pressed
  }

void behaviour3(){
  //do if button V2 is pressed
  }

void behaviour4(){
  //do if button V1 is pressed
  }

void behaviour5(){
  //do if button V5 is pressed
  }

BLYNK_WRITE(V0){
  if (param.asInt()){
    buttonOff();
    behaviour1();
  }
}

BLYNK_WRITE(V4){
  if (param.asInt()){
    buttonOff();
    behaviour2();
  }
}

BLYNK_WRITE(V2){
  if (param.asInt()){
    buttonOff();
    behaviour3();
  }
}

BLYNK_WRITE(V1){
  if (param.asInt()){
    buttonOff();
    behaviour4();
  }
}

BLYNK_WRITE(V5){
  if (param.asInt()){
    buttonOff();
    behaviour5();
  }
}

// buttonOff is an attempt at turning all the virtual buttons to being 
//"unpressed" very unsure as to syntax and implementation

void buttonOff(){
  Blynk.virtualWrite(V0,LOW);
  Blynk.virtualWrite(V4,LOW);
  Blynk.virtualWrite(V2,LOW);
  Blynk.virtualWrite(V1,LOW);
  Blynk.virtualWrite(V5,LOW);
}

void setup() {

  Serial.begin(115200);
  Blynk.begin(auth,ssid,pass);

  //the issue is here I think....
  timer.setInterval(500L, BLYNK_WRITE(V5)); 
  timer.setInterval(500L, BLYNK_WRITE(V4));
  timer.setInterval(500L, BLYNK_WRITE(V0));
  timer.setInterval(500L, BLYNK_WRITE(V2));
  timer.setInterval(500L, BLYNK_WRITE(V1));
}

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

As a result of this code I am getting the following error thrown:

C:\filelocation\BlynkHandlers.h:163:31: note: in expansion of macro 'BLYNK_WRITE_2 #define BLYNK_WRITE(pin) BLYNK_WRITE_2(pin)

C:\filelocation\codeName.ino 119:27: note: in expansion of macro ‘BLYNK_WRITE’
timer.setInterval(500L, BLYNK_WRITE(V1));

exit status 1
Error compiling for board NodeMCU 1.0 (ESP-12E Module)

It throws multiple of these errors (for each BLYNK_WRITE) and I believe it’s a result of the timer.setInterval calls I have created and how they interact. If anyone has some recommendations about how to achieve my goal, or what I can change here, it would be greatly appreciated! Thanks! :smile:

What / where is getData ?

You can’t call BLYNK_WRITE() from timer.
Do you actually need timed events as pressing each Blynk button will call the buttonOff() and behaviourX() functions?

1 Like

Sorry I worded that title poorly - I think more accurately I’m handling multiple outputs from the app; getData may not be the best name for it.

I believe I do need timed events unless I’m misunderstanding the polling behaviour of the program. Do I not need to actively check the buttons on the app? Is the use of BLYNK_WRITE(pin) going to automatically be triggered when I press the button on the app? Thanks!

Yes that’s the power of Blynk.

1 Like

Guess I was over-complicating things - thanks for helping out.

Just to expand upon the Blynk magic.

Blynk.run() in loop() takes care of all your widgets and the server heartbeat etc.
Use of the BlynkTimer (Arduino SimpleTimer) is essential when you want to call your own functions at intervals, but not the inbuilt Blynk functions like BLYNK_WRITE().

1 Like

Okay great; that makes a bit more sense to me. If I can ask you a thing more…

If I have my code set up such that:

void behaviour1(){
    analogWrite(ledPin,analogValue)
    delay(1000);
    analogWrite(ledPin,0)
    delay(1000);
}

And I want that behaviour to continue endlessly (while V0 is HIGH on Blynk) so I created this:

BLYNK_WRITE(V0){
  while (param.asInt()){
    Blynk.virtualWrite(V5,LOW);
    Blynk.virtualWrite(V4,LOW);
    Blynk.virtualWrite(V2,LOW);
    Blynk.virtualWrite(V1,LOW);
    behaviour1();
  }
}

However I can’t get the program to drop the loop when the button goes to LOW. Where should I put in the check for BLYNK_WRITE(V0) so I can get a LOW value that will break my while statement?

I need to know a little bit more about what you are trying to do.

Presumably you are intending for your project to do something without pressing Blynk buttons. If so what is that?

BlynkTimer should be used in place of this. Sometimes you will get away with a 1s delay but it’s best avoided.

Yes that’s correct - for this behaviour I want to output a signal on a specific pin to illuminate an LED briefly. Then, I want it to go dark, and to repeat this indefinitely until the button on Blynk V0 is turned off.

So pseudo code wise…

Button is pressed on app
Loop Behaviour1 begins
Light is illuminated
Light is off
Repeat behaviour 1 while button is pressed

Something to that effect.

Ok.

timer.setInterval() doesn’t have to be in setup() it can be in BLYNK_WRITE() but if you put it in setup() you can disable the timer straight after you create it.

Set it as 1000L and the associated function to negate the current LED status, which makes the LED flash at 1s intervals.

In BLYNK_WRITE() button ON can create the timer if it’s not already in setup() or start the timer if it is in setup().

In BLYNK_WRITE() button OFF can delete or suspend the timer.

Okay great, that makes plenty of sense. I’m more stuck on the issue of how to get my function to re-check the virtual pin V0 to exit my while true statement. See below:

void pulse(){
  int delayValue = (255-frequency)*10;                   //delay set-up for testing
  analogWrite(ledPin,amplitude);
  Serial.print("This is the amplitude for pulse: ");     //debugging
  Serial.print(amplitude);
  Serial.print(" \n");
  delay(delayValue);
  analogWrite(ledPin,0);
  delay(delayValue);

  //BLYNK_WRITE(V0); I thought including this line would re-check the button in the app but it doesn't seem to be doing so
  }

BLYNK_WRITE(V0){
  while (param.asInt()){                                      //while button is pressed, do:
    Blynk.virtualWrite(V5,LOW);
    Blynk.virtualWrite(V4,LOW);
    Blynk.virtualWrite(V2,LOW);
    Blynk.virtualWrite(V1,LOW);
    Serial.print("Pulse \n");   //debugging
    pulse();                                                        //function to be performed
  }

Is this an issue that can be solved with the magic of Blynk or am I fundamentally missing something somewhere. Also the delays I have set-up right now are just for testing, I will move those to timer controlled values later.

The syntax to call a widget via code is:

Blynk.virtualWrite(Vx, y); // x is virtual pin number and y the String to send to the widget.

Is your button PUSH or SWITCH mode?

My button is in SWITCH mode. My understanding is that every time the state changes (ie: I enable/disable it by tapping the button on the app) the function BLYNK_WRITE(V0) will be called.

Your understanding is correct.

So by that logic, can you help me understand why my loop isn’t behaving as I expect?

  1. I press the button on the app, this initiates BLYNK_WRITE(V0)
  2. BLYNK_WRITE(V0) calls pulse() while param.asInt() (the button is SWITCHED to ON)
  3. pulse() runs the desired hardware functionality
  4. If at anytime the state of virtual pin V0 changes, the BLYNK_WRITE(V0) is called
  5. In this case, I have pressed the button on the app again (SWITCHED to OFF)
  6. The while condition should no longer be met (param.asInt()!=1) and the pulse() function should no longer be written

Although this is my expectation, the reality is that pressing the button a second time (SWITCHED to OFF) is not stepping out of the loop as the pulse() is continuing to run. Any ideas? Thanks!

@Spamkey I’m not a fan of while and certainly not for virtualWrite() as that will normally flood the server and get you disconnected.

I still need to get my head around what it is you are doing but in simple terms V0 for SWITCH mode would be:

BLYNK_WRITE(V0){
  if (param.asInt()){                   // while button is ON, do:
    Blynk.virtualWrite(V5,LOW);
    Blynk.virtualWrite(V4,LOW);
    Blynk.virtualWrite(V2,LOW);
    Blynk.virtualWrite(V1,LOW);
    Serial.print("Pulse \n");       //debugging
    pulse();                               //function to be performed
  }
  else{
    // do something when button goes to OFF
  }
}

I’m not a fan of implementing solutions using while loops either, but it’s the only solution I can currently see. :frowning_face:

I started off using basically the exact same implementation you have posted above (if loop).

This method will call pulse() once which is good, but I want pulse() to repeat over and over so long as the button on V0 is ON. The if loop gives a single pulse each time V0 is SWITCHED ON so 1 press of the button = 1 pulse of light on the LED. The while loop will repeat the pulse() calls which is exactly what I want functionally so 1 press of the button (ON) = infinite repetitive pulses of light until the next press turns the button OFF. I cannot seem to break out of that while loop when switching V0 OFF. Hopefully that’s a clearer explanation.

As posted earlier that scenario requires the use of BlynkTimer. V0 ON starts the timer and the function repeats over and over again until you press OFF in V0 and the timer is then deleted / suspended. But you have to provide the coding for this.

Not sure if you are familiar with SimpleTimer (BlynkTimer) and the details are not great but covered at http://playground.arduino.cc/Code/SimpleTimer

BlynkTimer is not a “Blynk” function and doesn’t require a connection to the server to operate. It’s SimpleTimer “renamed” but included in the Blynk library as it’s an essential part of project building with Blynk.

Until quite recently it was included as a separate library in the GitHub download but that just confused people as far as installation went.