Okay, the first thing you need to know about when using virtual pins is that when you have a widget (we’ll talk about buttons, but all widgets work the same way) in your app then any change to that widget triggers a callback function called BLKYNK_WRITE(vPin).
So, if you have a button widget attached to V10 which is configured in Switch (latching) mode it will by default send a “1” when it’s turned on, and a “0” when it’s turned off.
If you have this in your code:
BLYNK_WRITE(V10)
{
Serial.println("The button attached to V10 changed value");
}
then the “The button attached to V10 changed value” message will be printed to your serial monitor every time the button changes state.
That’s okay if you just want top know that the button widget was pressed, but not much use if you want to know whether it was turned on or off.
To get that piece of information, we need to find out what value (a 1 or a 0) was sent from the button widget via the Blynk server.
we do this using the param.as
method. There are three versions of param.as
:
param.asInt()
param.asString()
param.asFloat()
As the switch widget is sending us a 1 or a 0 - which are integers - then we’ll use the param.asInt()
version. If we wanted to use the state of the switch widget elsewhere then we could save this value to a globally defined integer like this:
int V10_switch_state;
BLYNK_WRITE(V10)
{
V10_switch_state = param.asInt();
Serial.print("V10_switch_state = ");
Serial.println(V10_switch_state);
}
In reality, we’ll want to do different things based on whether the switch widget was on or off. That means using an if
statement. This is one way to do it…
BLYNK_WRITE(V10)
{
int V10_switch_state = param.asInt();
if (V10_switch_state == 1) // The button widget is on
{
Serial.println("The button attached to V10 is ON");
}
else // The button widget is not on, so it's off
{
Serial.println("The button attached to V10 is OFF");
}
}
Because in C++ an integer value of 1=true and 0=false, you’ll often see this simplified like this…
BLYNK_WRITE(V10)
{
if (param.asInt()) // The button widget sent a 1 (true)
{
Serial.println("The button attached to V10 is ON");
}
else // The button widget is not true, so it's false (0)
{
Serial.println("The button attached to V10 is OFF");
}
}
So, your code might look like this:
BLYNK_WRITE(V10)
{
if (param.asInt()) // The button widget sent a 1 (true)
{
digitalWrite(D0,LOW);
Serial.println("LED 1 & 3 on via button V10");
Blynk.virtualWrite(V12,"LED 1 & 3 on via button V10");
}
else // The button widget is not true, so it's false (0)
{
digitalWrite(D0,HIGH);
Serial.println("LED 1 & 3 off via button V10");
Blynk.virtualWrite(V12,"LED 1 & 3 ff via button V10");
}
}
When it comes to syncing, you’ll need to decide what is being synchronised with what.
If the app (actually the Blynk server) is the ‘master’ system and when the MCU starts-up you want to synchronise the LEDs with the state of the buttons in the app then you’d use the BLYNK_CONNECTED
callback function. This is another special function that is triggered automatically each time your MCU connects or re-connects with the Blynk server. This usually happens after a reboot, but could be caused by a drop in the connection.
Inside the BLYNK_CONNECTED
callback function you can use Blynk.syncVirtual(vPin)
. This forces the server to send the current values to your MCU. From the MCU’s point of view it seems like the value of the virtual pin has changed, so the corresponding `BLYNK_WRITE(vPin) callback function is triggered…
BLYNK_CONNECTED()
{
Blynk.syncVirtual(V10); // trigger the BLYNK_WRITE(V10) callback
}
If on the other hand you want to synchronise the app with the current state of the LEDs when your device is powered-up then you’d do this with a Blynk.virtualWrite(vPin,value) command, which could be placed in your BLYNK_CONNECTED
callback.
Does this help?
Pete.