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.
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.
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.
@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.
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
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.
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.
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.
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.