Ok Google Voice commands to push buttons

Hi all

I have a simple question about my sketch.

It’s quite a simple sketch where I have two push buttons.

Essentially I push each button and each are connected to a digital input (both relays for gates), mimicking me physically pushing a button on gate remote.

I would like to use a google voice command to “activate gate 1” - which works essentially by stimulating pushing a button for a 1-1.5 secs then releasing

Ideally would be nice to not have to edit my sketch.

Is there a online tutorial or documentation I could follow?

With Siri I call a virtual pin that triggers it high and I use a Lambda timer to trigger the low after a designated number of millis().

Your description would be much simpler to follow if you differentiated between physical buttons and button widgets.

If you’re using button widgets then I’d recommend attaching them to virtual pins instead of digital pins. This will also make IFTTT integration with Google Assistant much easier.

Pete.

Hi PeteKnight,

is there a guide for this, I am googling but landing in all sorts

A guide for what part of your project exactly?

Pete.

The very basics 101, i.e assigning these buttons to a virtual pin, because truly I don’t understand the purpose of virtual pins.

Is a way in plain English that describes how a virtual pin plays a role in what I am trying to do?

I guess I’ll try to work out the integration later.

Also, I used to edit /update my sketch by plugging in via USB. I’m using a nodemcu on my home WiFi. It’s it possible to update the sketch wirelessly?

Okay, I’ve written this just for you (not really :grinning…

Yes, you need read-up about OTA Updates.
OTA is one of the main benefits of using an ESP8266 or ESP32 based device in my opinion.
You need to install Python on your PC for OTA to work, but that’s quite straightforward.
You also need to add some OTA code to your sketch, but that’s also straightforward.

Pete.

Hi PeteKnight,

I will have a read as time permits, appreciate your input!

Ok thanks, I just had a read. From that I see a virtual pin is like an excel macro… i.e call macro, but the macro has a number of actions tied to it.

So in plain English I’d imagine the idea for me would be to creat a virtual pin that:

  1. Sets relevant pin to high turning my relay on.
  2. Setting a time delay of X seconds
  3. Setting the previous pin back to low, turning the relay off.

I’d imagine I would also have to have a start-up action to also set/keep the pin Low.

Am I on the right path?

But, as @daveblynk has already said, this needs to be a lambda Timer, not a delay()

If that’s the behaviour you want then yes. You’d do this in void setup, with a digitalWrite command immediately after your pinMode command.

Pete.

Thank you!

BTW where do I begin with Lamba timer?
Googling doesn’t return a dedicated page about it.

Search this forum.

Pete.

Hi, am I on the right track with this code?

/*************************************************************
  Download latest Blynk library here:
    https://github.com/blynkkk/blynk-library/releases/latest

  Blynk is a platform with iOS and Android apps to control
  Arduino, Raspberry Pi and the likes over the Internet.
  You can easily build graphic interfaces for all your
  projects by simply dragging and dropping widgets.

    Downloads, docs, tutorials: http://www.blynk.cc
    Sketch generator:           http://examples.blynk.cc
    Blynk community:            http://community.blynk.cc
    Follow us:                  http://www.fb.com/blynkapp
                                http://twitter.com/blynk_app

  Blynk library is licensed under MIT license
  This example code is in public domain.

 *************************************************************
  This example runs directly on NodeMCU.

  Note: This requires ESP8266 support package:
    https://github.com/esp8266/Arduino

  Please be sure to select the right NodeMCU module
  in the Tools -> Board menu!

  For advanced settings please follow ESP examples :
   - ESP8266_Standalone_Manual_IP.ino
   - ESP8266_Standalone_SmartConfig.ino
   - ESP8266_Standalone_SSL.ino

  Change WiFi ssid, pass, and Blynk auth token to run :)
  Feel free to apply it to any other example. It's simple!
 *************************************************************/

/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial


#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>

BlynkTimer timer;

// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "YourAuthToken";

// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "YourNetworkName";
char pass[] = "YourPassword";

void setup()
{
  // Debug console
  Serial.begin(9600);

  Blynk.begin(auth, ssid, pass);
  // You can also specify server:
  //Blynk.begin(auth, ssid, pass, "blynk-cloud.com", 80);
  //Blynk.begin(auth, ssid, pass, IPAddress(192,168,1,100), 8080);

  pinMode(12, OUTPUT); // Initialise digital pin 6 as an output pin (GPIO12)
  Blynk.syncVirtual(V6);  // will cause BLYNK_WRITE(V6) to be executed
}
BLYNK_WRITE(V6) // Executes when the value of virtual pin 6 changes
{
  if(param.asInt() == 6)
  {
    // execute this code if the switch widget is now ON
    digitalWrite(12,HIGH);  // Set digital pin 6 (GPIO12) to HIGH
    timer.setTimeout(1000L, []() {  // Wait 1 second then...
     digitalWrite(12,LOW);  // Set digital pin 6 (GPIO12) to LOW  
  });  // END of Lambda Function
  }
  else
  {
    // execute this code if the switch widget is now OFF
    digitalWrite(12,LOW);  // Set digital pin 6 (GPIO12) to LOW  
  }
}

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

Does it work?

Pete.

1 Like

The code compiles, but yet to test it on actual nodemcu. It’s quite late here now (Australia) and it’s a bit of effort to get to where I’ve located it, so maybe tomorrow I’ll test.

Do you see any potential issues with the code?

Hello,

An update, and a fairly good one for a novice like me.

I have ended up with the below code, which seems to do exactly what I want, and together with IFTTT, I can now use “OK Google” to activate the 4 different relays exactly how I want.

I went further and set up my smartwatch with an HTTP request and can now open my gate - quite happy with that.

But I do have some questions,

  1. What happens in the event of network disconnection mid-way between a set of actions? How can I be sure the virtual pins are always in sync with the Blynk dashboard.

  2. If an HTTP request has been carried out, is there a snippet of code somewhere that can alert me to that via the Blynk app? - but only for HTTP requests such as the ok google/IFTTT requests and not the actions through the apps dashboard?

  3. Is there the possibility for any other reason that the code could stop - and potentially keeping my relay always on?

  4. The OTA function - I am struggling to find a good and relevant tutorial for this on the NodeMCU. I found one which initially sets up the SSID/pass but then I thought that was doubling up with Blynk’s own Blynk.begin(auth, ssid, pass, etc - is this a conflict and do I need to remove the SSID, pass from the Blynk line?

#define BLYNK_PRINT Serial


#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>

BlynkTimer timer;

// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "auth";


// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "ssid";
char pass[] = "pass";

void setup() {
  Serial.begin(9600);

 Blynk.begin(auth, ssid, pass, IPAddress(45,55,96,146), 80);
  // You can also specify server:
  //Blynk.begin(auth, ssid, pass, "blynk-cloud.com", 80);
  //Blynk.begin(auth, ssid, pass, IPAddress(192,168,1,100), 8080);

  pinMode(4, OUTPUT); // Initialise NodeMCU D2 as an output pin
  pinMode(12, OUTPUT); // Initialise NodeMCU D6 as an output pin
  pinMode(13, OUTPUT); // Initialise NodeMCU D7 as an output pin
  pinMode(15, OUTPUT); // Initialise NodeMCU D8 as an output pin
  Blynk.syncVirtual(V2);  // will cause BLYNK_WRITE(V2) to be executed
  Blynk.syncVirtual(V6);  // will cause BLYNK_WRITE(V6) to be executed
  Blynk.syncVirtual(V7);  // will cause BLYNK_WRITE(V7) to be executed
  Blynk.syncVirtual(V8);  // will cause BLYNK_WRITE(V8) to be executed
}
BLYNK_WRITE(V2) // Executes when the value of virtual pin 2 changes
{
  if(param.asInt() == 1)
  {
    // execute this code if the switch widget is now ON
    digitalWrite(4,HIGH);  // Set NodeMCU D2 to HIGH
    timer.setTimeout(1000L, []() {  // Wait 1s then...
     digitalWrite(4,LOW);  // Set NodeMCU D2 to LOW
     Blynk.virtualWrite(V2,0);  // Turn the widget attached to V2 Off
  });  // END of Lambda Function
  }
  else
  {
    // execute this code if the switch widget is now OFF
    digitalWrite(4,LOW);  // Set NodeMCU D2 to LOW
  }
}

BLYNK_WRITE(V6) // Executes when the value of virtual pin 6 changes
{
  if(param.asInt() == 1)
  {
    // execute this code if the switch widget is now ON
    digitalWrite(12,HIGH);  // Set NodeMCU D6 to HIGH
    timer.setTimeout(1000L, []() {  // Wait 1s then...
     digitalWrite(12,LOW);  // Set NodeMCU D6 to LOW
     Blynk.virtualWrite(V6,0);  // Turn the widget attached to V2 Off
  });  // END of Lambda Function
  }
  else
  {
    // execute this code if the switch widget is now OFF
    digitalWrite(12,LOW);  // Set NodeMCU D6 to LOW
  }
}


BLYNK_WRITE(V7) // Executes when the value of virtual pin 7 changes
{
  if(param.asInt() == 1)
  {
    // execute this code if the switch widget is now ON
    digitalWrite(13,HIGH);  // Set NodeMCU D7 to HIGH
    timer.setTimeout(1000L, []() {  // Wait 1s then...
     digitalWrite(13,LOW);  // Set NodeMCU D7 to LOW
     Blynk.virtualWrite(V7,0);  // Turn the widget attached to V7 Off
  });  // END of Lambda Function
  }
  else
  {
    // execute this code if the switch widget is now OFF
    digitalWrite(13,LOW);  // Set NodeMCU D7 to LOW
  }
}

BLYNK_WRITE(V8) // Executes when the value of virtual pin 8 changes
{
  if(param.asInt() == 1)
  {
    // execute this code if the switch widget is now ON
    digitalWrite(15,HIGH);  // Set NodeMCU D8 to HIGH
    timer.setTimeout(1000L, []() {  // Wait 1s then...
     digitalWrite(15,LOW);  // Set NodeMCU D8 to LOW
     Blynk.virtualWrite(V8,0);  // Turn the widget attached to V8 Off
  });  // END of Lambda Function
  }
  else
  {
    // execute this code if the switch widget is now OFF
    digitalWrite(15,LOW);  // Set NodeMCU D8 to LOW
  }
}

void loop()
{
  Blynk.run();
  timer.run();
}
  1. Do some testing and see what happens. If the network is disconnected then your device can’t remain synchronised with the Blynk app, as there is no communication taking place.

  2. No, pin changes via API calls, App inputs or Bridge commands aren’t differentiated. The solution would be to set-up two different virtual pins, which perform almost identical actions and have one which is controlled from the app and another that is controlled via API calls. You can then choose what actions each BLYNK_WRITE(vPin) performs, and one of those could include a message to show that an action received via the API stream was successful.

  3. Provided that your relays default to a ‘fail safe’ state when power is disconnected then you’ve done everything you can.

  4. This is a good starting point:
    OTA Updates — ESP8266 Arduino Core 2.7.1-110-gc1118dfc documentation

Pete.

Thanks PeteKnight

  1. Ok

  2. I have found this snippet of code in the examples

{
  // Invert state, since button is "Active LOW"
  int isButtonPressed = !digitalRead(2);
  if (isButtonPressed) {
    Serial.println("Button is pressed.");

    // Note:
    //   We allow 1 notification per 15 seconds for now.
    Blynk.notify("Yaaay... button is pressed!");
  }
}

I can’t wrap head around that, could you elaborate more on int isButtonPressed = !digitalRead(2);?
I see that we are first declaring an integer of ‘isButtonPresses’ with the default reading being 2?
I am completely lost around this and I have even had my morning coffee.

I thought I could add some code after Blynk.virtualWrite such as

Serial.println("Device activated by Smartwatch");
Blynk.notify("Device activated by Smartwatch");

Doing this shows up the text in the serial monitor, but I don’t get a push notification. I have reinstalled the app and ensured the app has full access to android notifications and can override Do Not Disturb etc. Can I do it this way?

  1. All good then, that will happen.
  2. Perfect - great article, done in 5 mins.

Thanks for you guidance.

I have no idea how this relates to your question, but here here goes…

This is basically saying “set the integer variable isButtonPressed to the opposite of the result that you get when you do a digital read on pin GPIO2”

The exclamation mark operator “!” means NOT, which is effectively saying “the opposite of”, so if digitalRead(2) returns HIGH then the result od applying a NOT operator will be LOW (or 0 as it’s an integer).

Do you have the Notification widget in the app?

Have you tested doing an OTA upload?

Pete.