Blynk_write_default

For the last few days I have been trying to get the BLYNK_WRITE_DEFAULT to work. I have several schedule timer input settings I want to process, in order to reduce the code size. I see that one can use BLYNK_WRITE_DEFAULT by just passing it the “trigger” virtual pin (V1----n) using the Blynk.virtualWrite() command (I might be mistaken)

I found an extract of code on the Arduino website as attached, but I simply cannot get this to work.

I also had a good look at this code Simple 4 relay irrigation scheduler

Before anyone shoots me down I did follow the guidelines before creating the topic.

Thanks
Les

#define BLYNK_PRINT Serial    // Comment this out to disable prints and save space
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <SimpleTimer.h>
#include <TimeLib.h>
#include <WidgetRTC.h>
#include <WidgetTimeInput.h> 
#include <time.h>
SimpleTimer timer;
WidgetRTC rtc;


//...........................................................................................
//WiFi Credentials

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

//.........................................................................................
//Setup the device and defaults

void setup()
{
    Serial.begin(9600);
    Blynk.begin(auth, ssid, pass);
    rtc.begin();
    timer.setInterval(1000L, activetoday);  // 10000 check every 1 SECOND
 }

//.......................................................................................

BLYNK_WRITE_DEFAULT()
{
 int virtualPinNb = request.pin; // which pin was it?
  int value = param.asInt(); // get the value as a number
  Serial.print(F("Virtual Pin "));
  Serial.print(virtualPinNb);  // Display the number of the vPin
  Serial.print(F(" value= "));
  Serial.println(value); // Display the value of the vPin
}


void activetoday()
{
  
  //Serial.println("Run Test");
  
    Blynk.virtualWrite(V4, 0);
  
} 

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

Hi @Badge, I think you’re running into an issue with the way that the Blynk server tries to prevent endless loops caused by code updating a virtual pin and triggering a subsequent BLYNK_WRITE for that pin.

If you add a button widget to your app which is connected to V4 then toggling that button should trigger your BLYNK_WRITE_DEFAULT() function and tell you which pin and value was received.

Pete.

Hi Peter, maybe my explanation was not clear.

Currently I read my schedule using

BLYNK_WRITE(V3) {
“process timer”
}
BLYNK_WRITE(V4)
BLYNK_WRITE(V20)
BLYNK_WRITE(V21)

As these all essentially contain the same code, I thought I will reduce my code size by using

BLYNK_WRITE_DEFAULT() {
“Common process timer Code”
}

My understanding is all I need to do and pass it the virtual PIN V3, V4, V20, V21 of which timer I want to read by using the command as follows:

Blynk.virtualWrite(V3, 0) //This allows me to process V3 timer
once processed I then follow up to the next timer
Blynk.virtualWrite(V4, 0) etc…

I don’t follow your comment about the server overload. Currently I read an update every 10 sec using the BLYNK_WRITE(V3) procedure and this all works fine. I just want to reduce the code size.

Les

@Badge please use triple backticks at the beginning and end of your code when you post code to the forum.

I never mentioned server overload, I was talking about preventing the code on a device going into an endless loop.

Your code contains this line:

That line won’t trigger either a BLYNK_WRITE(V4) callback or a BLYNK_WRITE_DEFAULT callback because if it did then it would be very easy to get into a situation where the code running on the device gets into an endless loop if the coder put a Blynk.virtualWrite(Vx) command into a BLYNK_WRITE(Vx) function.

As a result, only widgets attached to virtual pins or API calls will trigger a BLYNK_WRITE(Vx) or BLYNK_WRITE_DEFAULT callback.

You can indeed reduce your code in the way that you’ve suggested, it’s just that you can’t test it by doing a Blynk.virtualWrite from within your code.

Pete.

Hi Pete,

Your backticks comment noted.

Looks like I misunderstood how BLYNK_WRITE_DEFAULT works. I will just stick to my existing code.

Thanks for the explanation.

Les

In that case, maybe the Blynk.syncVirtual(x) command is what you’re looking for.
Calling ‘Blynk.syncVirtual(4)’ will cause the BLYNK_WRITE(V4) callback to trigger, or cause the BLYNK_WRITE_DEFAULT() callback to trigger and return 4 as the request.pin

Pete.

Geez as simple as that! Got it to work, been chasing a red herring all day.

Thanks for the feedback, case closed.
Les

1 Like

Mmm, not quite what I was expecting. Sorry about coming back but I thought I had its sorted.

This is an example of my current code structure.

/.............................................................
//Sync Schedule every 1 sec

test_every_1sec {

 
  Blynk.syncVirtual(V1);
  Blynk.syncVirtual(V2);
  Blynk.syncVirtual(V3);
  Blynk.syncVirtual(V4);
 
}

//.............................................................
//Sync Schedule of V1 timer

BLYNK_WRITE(V1) {
  //common code     
}

//.............................................................
//Sync Schedule of V2 timer

BLYNK_WRITE(V2) {
  //common code     
}

//.............................................................
//Sync Schedule of V3 timer

BLYNK_WRITE(V3) {
  //common code     
}

//.............................................................
//Sync Schedule of V4 timer

BLYNK_WRITE(V4) {
  //common code     
}

The above code works perfectly, I then implemented it as follows:

//...........................................................
// Definitions
int virtual_pinx;

//.............................................................
//Sync Schedule every 1 sec
test_every_1sec {

 for (int i = 1; i <= 4; i++) { 
         virtual_pinx = i;
         Blynk.syncVirtual(virtual_pinx);
     }
}

//.............................................................
//Sync Schedule of virtual_pinx timer

BLYNK_WRITE(virtual_pinx) {
  //common code     
}

However this does not compile. I suspect that one cannot pass the “virtual_pinx” to BLYNK_WRITE(). Is this a correct assumption? It seems to me that BLYNK_WRITE(Vx) must be hard coded.

Maybe there is another way to do it, but I can’t find an example.

Les

This could probably now become a new topic under BLYNK_WRITE(Vx). Not sure how to change the thread…

Hi Les,
I’m a bit confused as to why you’re doing this.
You don’t need to keep polling the virtual pins to see if the value has changed. This is the beauty of the BLYNK_WRITE and BLYNK_WRITE_DEFAULT functions - they are in effect callback functions that ‘fire’ automatically when the value of whatever is attached to them in the app changes.
In effect, they are interrupt driven functions that sit there dormant until a change occurs.

The Blynk.syncVirtual(Vx) function is really intended to synchronise the values of your variables that are changed within the BLYNK_WRITE functions with those on the Blynk server. This is really only needed at startup, and is there to avoid the users having to go into the app and ‘dirty’ the values of each widget by changing them and causing a subsequent BLYNK_WRITE within the code.
Blynk also has a special callback function that is triggered whenever the hardware connects to the server and this is called BLYNK_CONNECTED(), and their is where the Blynk.syncVirtual(Vx) commands would normally live.
There is also a Blynk.syncAll command that causes every pin (both digital and virtual) to be updated, but this is a bit of a sledgehammer to crack a nut and using this tool can cause timeout problems.

To answer your question, it is possible to loop through virtual pins in a loop, this is an example:

  for(int loop=0;loop<=7;loop++) 
  {
    Blynk.syncVirtual(loop); // This forces the BLYNK_WRITE_DEFAULT callback function to trigger for each virtual pin in turn 
  }

This is from my example code here:

and it lives in the BLYNK_CONNECTED() callback at the bottom of the code.

The code also uses the BLYNK_WRITE_DEFAULT() callback to make the code neater, otherwise 16 BLYNK_WRITE callbacks would be needed, or potentially 128 in the following post.

Pete.

Thanks Pete,

The reason I poll is that when the timer has run it’s course a relay is disconnected on my circuit.

I have a weekday AM and PM timer
Followed by a weekend AM and PM timer

I think I may have misunderstood how this all hangs together from your explanation.

Les

The timer widget value will change from 1 to 0 when it expires, triggering the BLYNK_WRITE(Vx) callback for the virtual pin that it is connected to. No need to poll it.

If you have more complex timing needs (as it sophd like you do), the you could use the Time Input widget along with the RTC widget:

This requires some more complex coding to check the start and stop times against the RTC, but it’s still not necessary to poll the time input widget or the RTC widget.

Pete.

Thanks Pete,

I think I now have a better understanding of how it works. Maybe a subject matter for a power point presentation…how it all hangs together. I am old school and understand a pictorial explanation better.

My system is fairly complex and I do use the RTC widget.

Thanks for the feedback.

Les