Introduction: How to Make a Google Assistant Control Car

About: I am creator in the field of electronic
We will use various softwares to make the car :-
1) https://io.adafruit.com
2) https://ifttt.com/
3) Arduino IDE

Step 1: Materials Required

The following tools were used in this project:

1)Solder iron and wire . The DC motors already came with wires soldered to its terminals... But it will eventually break and you might have to resolder it. So consider having a good solder iron and wire neaby.

2)EVA foam sheet (or other non-conductive material). The robot chassis I used in this project is made of aluminum, and circuit boards are installed on this metal parts. I used a layer of foam sheet between the boards and the metal plate to avoid possible short-circuits.

3)Double sided tape. It was used for glueing the foam sheets to the circuit boards, and for the installation of the H-Bridge modue.
Scissors, for cutting some foam sheet rectangles.
I used the following hardware parts for my project:

4)Wemos D1 ESP8266 dev board . Wemos D1 board is really easy to use and program with Arduino IDE. It has the same footprint of and ordinary Arduino Uno! This way most of Arduino shield will also work with this board. It has built-in Wi-Fi module, so you can use it in a variaty of projects.You can also use other ESP8266 based boards .

5)L298N dual channel H-bridge module . This module allows the 3.3V signals from the Wemos (or an Arduino) to be amplified to the 12V needed for the motors.

6)DIY Robot Chassis Tank . This awesome kit has with everything you need to built a tank: two DC motors, gears, tracks, bolts, nuts, etc. It already comes with the tools need for assembling the chassis, which is great for beginners!

7)18650 3.7V batteries (x3) . I used to power the whole circuit. This tank uses 12V motors. I used three 3.7V batteries in series for powering them.

8)3S 18650 battery holder . It can hold three 18650 batteries in serie, and can be easilly be attached to the back of the tank.
18650 battery charger . Your batteries will eventually run out of power. When that happens, a battery charger will come to your rescue.

9)Jumpers . I used 6 male-female jumpers for signals between the h-bridge an the Wemos, and 2 male-male jumpers for 5V and Gnd. You might need more if you plan to add some sensors.

10)Micro USB cable. You'll need this for uploading your code. Most of the boards already come with its own cable.
The links above are only a suggestion of where you can find the items used in this tutorial (and maybe support my future tutorials). Feel free to search for them elsewhere and buy at your favorite local or online store.

Step 2: Wiring and Connection

Wemos D1 inputs/outputs:

Digital pin D3 (GPIO5) => H-Bridge ENB pin
Digital pin D4 (GPIO4) => H-Bridge IN4 pin
Digital pin D5 (GPIO14) => H-Bridge IN3 pin
Digital pin D6 (GPIO12) => H-Bridge IN2 pin
Digital pin D7 (GPIO13) => H-Bridge IN1 pin
Digital pin D8 (GPIO0) => H-Bridge ENA pin
5V pin => H-Bridge 5V pin
Gnd pin => H-bridge Gnd pin
H-Bridge inputs/outputs:

ENB pin => Wemos D3 pin
IN4 pin => Wemos D4 pin
IN3 pin => Wemos D5 pin
IN2 pin => Wemos D6 pin
IN1 pin => Wemos D7 pin
ENA pin => Wemos D8 pin
5V pin => Wemos 5V pin
Gnd pin => Wemos Gnd pin
Gnd pin => Battery pack negative wire
12V pin => Battery pack positive wire
OUT1 => Right motor negative wire
OUT2 => Right motor positive wire
OUT3 => Left motor positive wire
OUT4 => Left motor negative wire

Step 3: Setting Up the Arduono IDE for Wemos D1

For this project I used Arduino IDE for programming my Wemos. It's the easier way if you've already used an Arduino before, and you won't need to learn a new programming language, like Python or Lua for instance.

If you've never done this before, first you'll have to add ESP8266 board support to the Arduino software.

1. Download and install Arduino IDE latest version

You can find the latest version for Windows, Linux or MAC OSX on Arduino's website: https://www.arduino.cc/en/main/software

Download it for free, install it on your computer and launch it.

2. Adding ESP8266 board

Arduino IDE already comes with support to a lot of different boards: Arduino Nano, Mine, Uno, Mega, Yún, etc. Unfortunatly ESP8266 isn't by default among those suported development boards. So in order to upload your codes to a ESP8266 base board, you'll have to add its properties to Arduino's software first.

Navigate to File > Preferences (Ctrl +, on Windows OS);

Add the following URL to Additional Boards Manager textbox (the one on the bottom of the Preferences window):
http://arduino.esp8266.com/stable/package_esp8266com_index.json

Navigate for Tools > Board > Boards Manager for adding your ESP8266 board.

If the text box wasn't blank, it means had already add other boards before on Arduino IDE before. Add a comma at the end of the previous URL and the one above.
Hit "Ok" button and close the Preferences Window.
Type "ESP8266" on the search text box, select "esp8266 by ESP8266 Community" and install it.
Now your Arduino IDE will be ready to work with a lot of ESP8266 based development boards, like the generic ESP8266, NodeMcu (which I used in this tutorial), Adafruit Huzzah, Sparkfun Thing, WeMos, etc.

3. Adding the libraries

The following libraries will be used for our Arduino code:

Arduino http client library (https://github.com/arduino-libraries/ArduinoHttpClient)
Arduino IO library (https://github.com/adafruit/Adafruit_IO_Arduino)
Adafruit MQTT library (https://github.com/adafruit/Adafruit_MQTT_Library)
Navigate to Sketch-> Include Library -> Manage Libraries... on your Arduino IDE and add the libraries above.

............

Now that your dev environment is ready, let's move on to the next step!

Step 4: IFTTT Configuration

IFTTT is a free platform that helps you connects apps and devices. You can use it to connect your smartphone with other gadgets, or to share data between your favourite webservices (like Google, Facebook, Twitter, Instragram, etc.) and other physical devices, for instance. And the best part is that it's really easy to use!

IFTTT uses a "if this then that" logic, where "this" represents a service that will trigger a given action given by "that". This way you create small applets connecting webservices and devices. For the project described in this tutorial, I used Google Assistant to send voice commands from a smartphone to Adafruit.io, which is then received by the robot.

First you'll have to sign in at:

https://ifttt.com/

Then install IFTTT app on your smartphone. You can find it at Google Play Store:

https://play.google.com/store/apps/details?id=com.ifttt.ifttt

https://itunes.apple.com/us/app/ifttt/id660944635?mt=8

On the website, navigate to New Applet (click the arrow button next to your login to access the menu).

In the next step I'll show you how to create IFTTT applets.

Step 5: Adafruot IO Configuration

There are a lot of datalogging services available for communicating a microcontroller to the web. With those services you can upload/download data to/from the cloud, and do a lot of cool stuff. Take a look on my tutorial on how to use an Arduino + ESP8266 to send data from a mini-weather station for Thinkgspeak for instance (link).

Adafruit.IO is one of those free services. It's really easy to use and promises to bring internet of things to everyone!

Create Adafruit IO Web Feed

Under Feeds >Create a new Feed add a new feed named "voice commands". It will create a database, and we will use it store the commands received by the gadget.

Sign in at https://io.adafruit.com/
On the next step I will show you how to configure IFTTT, another platform I used in this project. The idea here is simple: IFTTT will have some triggers configured and send some data to Adafruit.IO platform when a given logic is true. The gadget will be able to read the data stored in a given feed on Adafruit.IO, execute some logic and perform some actions.

It's also a good time to copy your Adafruit.IO key, which will be later used for allowing your device accessing the database. Navigate for Settings > View AIO key and copy the active key code. You'll need it for your Arduino (NodeMCU) code on next steps.

Step 6: Coding

Code for Wemos d1 :-


/************************ Adafruit IO Configuration *******************************/

// visit io.adafruit.com if you need to create an account,
// or if you need your Adafruit IO key.
#define IO_USERNAME "xxxxx"
#define IO_KEY “yyyyyy "

/******************************* WIFI Configuration **************************************/

#define WIFI_SSID “Wifi name"
#define WIFI_PASS "Wifi password"

#include "AdafruitIO_WiFi.h"
AdafruitIO_WiFi io(IO_USERNAME, IO_KEY, WIFI_SSID, WIFI_PASS);

/************************ Main Program Starts Here *******************************/
#include
#include
#include
#include

// These are used to set the direction of the bridge driver.
#define ENB D3 //ENB
#define MOTORB_1 D4 //IN3
#define MOTORB_2 D5 //IN4
#define MOTORA_1 D7 //IN1
#define MOTORA_2 D6 //IN2
#define ENA D8 //ENA

AdafruitIO_Feed *command = io.feed("voice-commands"); // Set up the 'command' feed

// SETUP
void setup()
{
// Configure pins
pinMode(ENA, OUTPUT);
pinMode(MOTORA_1, OUTPUT);
pinMode(MOTORA_2, OUTPUT);
pinMode(ENB, OUTPUT);
pinMode(MOTORB_1, OUTPUT);
pinMode(MOTORB_2, OUTPUT);

// disable both motors
digitalWrite(ENA,LOW);
digitalWrite(ENB,LOW);

// Start serial communication
Serial.begin(9600);

// connect to io.adafruit.com
Serial.print("Connecting to Adafruit IO");
io.connect();

// set up a message handler for the 'command' feed.
// the handleMessage function (defined below)
// will be called whenever a message is
// received from adafruit io.
command->onMessage(handleMessage);

while(io.status() < AIO_CONNECTED) {
Serial.print(".");
delay(50);
}

// we are connected
Serial.println();
Serial.println(io.statusText());
}

// MAIN CODE
void loop()
{
io.run();
}

// this part of the code runs whenever there's a new message on Adafruit.io feed
void handleMessage(AdafruitIO_Data *data) {

String commandStr = data->toString(); // store the incoming commands in a string

// received message
Serial.print("received <- ");
Serial.println(commandStr);

String cmd;
int angle;

// separate text and number ingredients
for (int i = 0; i < commandStr.length(); i++) {
if (commandStr.substring(i, i+1) == ":") {
cmd = commandStr.substring(0, i);
angle = commandStr.substring(i+1).toInt();
break;
}
}

// print command
Serial.println(cmd);
Serial.println(angle);

// perform movements
// LEFT
if (cmd.equalsIgnoreCase("left")){
Serial.println("Turning left");
digitalWrite(ENA,HIGH);
digitalWrite(ENB,HIGH);
digitalWrite(MOTORA_1,HIGH);
digitalWrite(MOTORA_2,LOW);
digitalWrite(MOTORB_1,HIGH);
digitalWrite(MOTORB_2,LOW);
delay(angle*15);
Serial.println("Stop");
digitalWrite(ENA,LOW);
digitalWrite(ENB,LOW);
digitalWrite(MOTORA_1,LOW);
digitalWrite(MOTORA_2,LOW);
digitalWrite(MOTORB_1,LOW);
digitalWrite(MOTORB_2,LOW);
}
// RIGHT
if (cmd.equalsIgnoreCase("right")){
Serial.println("Turning right");
digitalWrite(ENA,HIGH);
digitalWrite(ENB,HIGH);
digitalWrite(MOTORA_1,LOW);
digitalWrite(MOTORA_2,HIGH);
digitalWrite(MOTORB_1,LOW);
digitalWrite(MOTORB_2,HIGH);
delay(angle*15);
Serial.println("Stop");
digitalWrite(ENA,LOW);
digitalWrite(ENB,LOW);
digitalWrite(MOTORA_1,LOW);
digitalWrite(MOTORA_2,LOW);
digitalWrite(MOTORB_1,LOW);
digitalWrite(MOTORB_2,LOW);
}
// FORWARD
if (cmd.equalsIgnoreCase("forward")){
Serial.println("Moving forward");
digitalWrite(ENA,HIGH);
digitalWrite(ENB,HIGH);
digitalWrite(MOTORA_1,HIGH);
digitalWrite(MOTORA_2,LOW);
digitalWrite(MOTORB_1,LOW);
digitalWrite(MOTORB_2,HIGH);
delay(angle*15);
Serial.println("Stop");
digitalWrite(ENA,LOW);
digitalWrite(ENB,LOW);
digitalWrite(MOTORA_1,LOW);
digitalWrite(MOTORA_2,LOW);
digitalWrite(MOTORB_1,LOW);
digitalWrite(MOTORB_2,LOW);
}
// BACK
if (cmd.equalsIgnoreCase("back")){
Serial.println("Moving back");
digitalWrite(ENA,HIGH);
digitalWrite(ENB,HIGH);
digitalWrite(MOTORA_1,LOW);
digitalWrite(MOTORA_2,HIGH);
digitalWrite(MOTORB_1,HIGH);
digitalWrite(MOTORB_2,LOW);
delay(angle*15);
Serial.println("Stop");
digitalWrite(ENA,LOW);
digitalWrite(ENB,LOW);
digitalWrite(MOTORA_1,LOW);
digitalWrite(MOTORA_2,LOW);
digitalWrite(MOTORB_1,LOW);
digitalWrite(MOTORB_2,LOW);
}
}

Step 7: IFTTT Applet

For this applet we will create a voice command that will make the robot move in a given direction or turn left/right.

Create the applet on the website:

1 - Click +This;

2 - Type "Google Assistant" on Seach service text box and select Google Assistant widget;

3 - Choose "Say a phrase with both a number and a text ingredient" trigger. As it's described on IFTTT website, it will create a trigger that fires every time you say "Ok Google" followed by a phrase with a text ingredient and a number ingredient;

4 - To complete the trigger, you'll have to define the phrase you want to say. IFTTT allows you to configure more than one phrase as a trigger. $ represent the text ingredient and # the number ingredient. In my case, I define the following commands:

Turn $ # degrees
Rotate $ # degrees
Move $ #
5 - You'll also have to define the message it will say in response if it understands you command. In my case I configured it to Say "Turning $".

6 - Now choose +That;

7 - Type "adafruit" and select Adafruit > Send data to Adafruit IO. This will send data to a feed in your Adafruit IO account whenever the trigger you configured previously (+This) is activated;

8 - Configure Feed name as "voice command". In "Data to save" choose "Add ingredient" and add the TextField and NumberField. Add ":" between then. This will work as a delimiter later on Arduino code.

9 - Finish your applet and turn it on.

Now whenever you say one of the phrase (for instance: "Turn left 90 degrees" or "Move forward 10"), it will store the command and the number on Adafruit.io feed (in previous example, "left:90" or "forward:10" will be stored).

Repeate previous instructions if you want to create different phrases.

In the following step I'll show you how to make the code the ESP8266 to perform an action when the command is received.

Step 8: Arduino Code

Download the code and open it on Arduino IDE.

You'll have to update the following parameters before uploading the code:

IO_USERNAME = Adafruit.io user name
IO_KEY = Adafruit.io key
WIFI_SSID = Wi-Fi network SSID
WIFI_PASS = Wi-Fi network password
Select 'Wemos D1 R2 & mini' (if you're using this board), plug it on your computer's USB port and upload the code. It will take a while (much more than compliling and uploading a sketch for an Arduino... be patient...). Now it's a good time for you to give a like on this tutorial while you wait! :D

When upload is completed, unplug the USB cable, and put the batteries. The code will start running immediatly and the Wemos board will automatically try to connect the Wi-Fi router and wait for the commands from Adafrui.io server.

Step 9: Project Completed

Robot ready, now it's time to try it! Launch Google Assistant on your phone. You may press the microphone icon on the app or just Say "Ok Google" and it will start listening your commands.

Say on of the phrases you configured before (Move [forward/back] [number] or Turn [right/left] [number]). If Google Assistant understands what you've just said, it will send a message to an Adafruit.io feed (using IFTTT app). ESP8266 board will listen to that feed and if a new message arrives, it will split it in two parts (a command and a number).

Command string might assume one of the following values: left, front, back or right, and will be used to select appropriate direction and speed of each track. Number part might represent the rotation angle (if 'left' or 'right' command was received) or the distance it has to move (if 'forward' or 'back' command was received).

Notice my robot uses an open-loop controller. This way, angles and distances won't be precise (and might even deppend on how much power there's left on the batteries). If you need precision on the movements, you'll have to add a closed-loop system (measure the rotation of each motor, for instance, and use it as a feedback).

Robotics Contest

Participated in the
Robotics Contest