Friday, April 24, 2020

ESP makes Google Assistant talk part 2

For an index to all my stories click this line.

Before I go on you have to know that this story relies heavily on the previous story in this series. So please read the previous story thoroughly. You can find it here.
https://lucstechblog.blogspot.com/2020/03/esp32-makes-google-assistant-talk.html

The previous story showed you how to have the Google Assistant say all kind of sentences. I hope you had fun with that and did not make it to gross.
If you played around with it and already made some projects with this technique then you could skip this story and wait for the next one. Something really cool is coming up.

Before I give you the breadboard setup and program please refer to the first story in this series and make sure you have the libraries installed and know the name of your Google Assistant.

This time we are going to have the Assistant say some meaningfull things. We are going to have her read out loud some sensor values. You'll need a puhbutton and a Dallad DS18B20 thermometer for this. You can adapt the setup easily for other sensors though.

Breadboard

I am using a DOIT ESP32 Devkit and as you know this will not fit on a regular breadboard. Use this trick for getting the ESP32 properly on a breadboard:
http://lucstechblog.blogspot.com/2018/08/breadboard-hack-for-esp32-and-esp8266.html


 

I attached a Dallas DS18B20 digital thermometer to the ESP32 on GPIO 23 and connected a 4.7k pull-up resistor to its datapin.
Further I placed a pushbutton which is connected with a 10K pull-up resistor to GPIO 34.

The program.

What I am going to do is to have the program wait for the button to be pushed and when that is done it will let the Google Assistant say that the button was pressed and speak out the present temperature. This is an easy example to demonstrate how you can have the Google Assistant speak out sensor values.

There are a few pitfalls which I will show along the road. First the program.



#include <WiFi.h>
#include <esp8266-google-home-notifier.h>

const char* ssid     = "YOURROUTERNAME";
const char* password = "YOURPASSWORD";
String command ="";
int Button = 34;

#include <OneWire.h>
#include <DallasTemperature.h>

#define ONE_WIRE_BUS 23    

OneWire oneWire(ONE_WIRE_BUS); 
DallasTemperature dallas(&oneWire);

GoogleHomeNotifier ghn;

void setup() 
{
  pinMode(Button, INPUT);
  
  Serial.begin(115200);
  Serial.println("");
  Serial.print("connecting to Wi-Fi");
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) 
  {
    delay(250);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("connected.");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
  
  const char displayName[] = "Living Room speaker";

  Serial.println("connecting to Google Home...");
  if (ghn.device(displayName, "en") != true) 
  {
    Serial.println(ghn.getLastError());
    return;
  }
  Serial.print("found Google Home(");
  Serial.print(ghn.getIPAddress());
  Serial.print(":");
  Serial.print(ghn.getPort());
  Serial.println(")");

  dallas.begin();
}

void loop() 
{
   int buttonState = digitalRead(Button);
   if (buttonState==0)
   {
   dallas.requestTemperatures(); 
   Serial.print("Temperature is: ");
   Serial.println(dallas.getTempCByIndex(0));

   ghn.notify("You pressed the button, let me check the temperature");
   delay (1000);
   
   command = "The temperature is ";
   dallas.requestTemperatures();
   command = command + String(int(dallas.getTempCByIndex(0)));
   command = command + "degrees celsius";
   ghn.notify (command.c_str());
   delay (5000);
   }
}


The first lines will not present any problem.
The needed libraries are loaded and some variables are defined. Do not forget to replace YOURROUTERNAME and YOURPASSWORD


#include <OneWire.h>
#include <DallasTemperature.h>

#define ONE_WIRE_BUS 23   

OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature dallas(&oneWire);

The above lines define the Dallas DS18B20 sensor and attach it to pin 23 of the ESP32.

The setup starts with connecting to the router and establishing an internet connection. When done it prints the IP number of the ESP32 in the serial monitor.

const char displayName[] = "Living Room speaker";

This line tells the library the name of your Google Assistant. Replace this with your own Assistant's name like I showed you in the previous article otherwise the library can not connect to the Assistant.

When connected to the Assistant the program shows the IP number of the Assistant in the Serial Monitor. This way you'll now that all connections are made.

dallas.begin()

This line actually starts the library for the Dallas thermometer.

In the loop you will find the tricky parts.

First the loop tests wether the button is pressed.

   dallas.requestTemperatures();
   Serial.print("Temperature is: ");
   Serial.println(dallas.getTempCByIndex(0));

If the button is pressed the temperature is requested and printed in the serial monitor.

   ghn.notify("You pressed the button, let me check the temperature");
   delay (1000);

We know that the button was pressed so we'll have the Google Assistant say that. This is how the state of the first sensor (the button) is spoken by the Assistant.

delay (1000);

As you might remember from the previous story we are actually using two libraries to have the Assistant speak to us. The first library sends the text to a Google service to translate it into an MP3 file and the second library plays that MP3 file. This will take some time. Therefore the delay is needed. If you send the second command directly after this without the delay the first sentence will not be spoken completely as it will be overwritten by the new MP3 file.
Just play with the delay function (and try leaving it out) so you can check for yourself what the effetct is.

command = "The temperature is ";

Here we start a new sentence that will be spoken by the Assistant.

dallas.requestTemperatures();

This does a new request for the temperature. Leave this out and you will get false readings. Actually the esp8266-google-home-notifier interferes with the DallasTemperature libarary and therefore we need to initiate it again.

command = command + String(int(dallas.getTempCByIndex(0)));
command = command + "degrees celsius";

here the sentence is completed. The complete sentence is now:
The temperature is XX degrees celsius

ghn.notify (command.c_str());

This is a real pitfall and took me some time to figure out.

The command for the library to send text to the Google Assistant is:
ghn.notify("string");

However we are not sending a string but a variable. And the library does not understand that. So this is a neat trick to tell the compiler where to find the variable in the ESP's memory and then send that chunk of bytes.

What can you use it for.

Besides the fact that this is fun to play with you can make some real projects with this.

How about attaching a vibration sensor to your cookie-jar. Let the Google assistant speak a warning when someone tries to take a cookie. Sometime ago I made an alarm in ESP-Basic with a vibration sensor but you can easily adapt it to Arduino Language (C++). You can find the information for the vibration sensor here:
http://lucstechblog.blogspot.com/2018/05/vibration-detection.html

You can make an alarm with a PIR or a radar module. Have your Assistant speak a warning when someone enters your room or mancave. The demonstration program above can easily be adapted. You can find information over the PIR and radar in the following links:
http://lucstechblog.blogspot.com/2017/01/pir-basics-movement-detection.html
http://lucstechblog.blogspot.com/2018/08/motion-detection-with-rcwl-0516-radar.html

How about putting some velostat in your chair and have your assistant warn you if you stay too long seated:
http://lucstechblog.blogspot.com/2018/04/flex-and-pressure-sensors.html

I can imagine at least half a dozen other projects which can be realised with this technique. And do not forget that the ESP32 has many IO pins so you can have it check a lot of sensors simultane.

If you make an interesting project do not hestitate to mail me. My emailadress is on the top right side of this page.

Something really Cool coming up.

While working with this libary I realised I could do something really cool with it. I could use this to ask my Assistant for the status of the sensors in my house. Not by pressing a button but by really just asking the question. It is more complicated as the above setup but really worthwile. Now I can check, and command sensors and the status of lamps etc. throughout my whole house from my lazy chair, just by asking my Assistant. Cool !! Just wait for the next part in this series.

Till then.
Have fun


Luc Volders