IoT based Voice Controlled Neopixel LED – Set any Colour using Voice Commands on Google Assistant

IoT based Voice Controlled Neopixel LED

With the advancement in virtual assistants like Google Assistant, Amazon Alexa, and Apple Siri, home automation and voice-controlled applications are becoming quite popular. We have previously built many home automation projects, from simple Alexa Controlled Home Automation to Voice controlled Home Automation using Raspberry Pi. In this project, we are going to control the Neopixel LED strip using Google Assistant and Blynk App. The Blynk app which is a free IoT platform is linked to IFTTT (if this, then that) website that is used to create if-else conditional statements or in other words, Applets. The voice commands for Google assistant have been added through the IFTTT applet. The commands given through the Google assistant are decoded and then sent to the Blynk using IFTTT Webhooks. The data in the Blynk app is then accessed by the microcontroller. The microcontroller used here is ESP-01 because of its small size and Wi-Fi capabilities.

 

Components Required to Control Neopixel using NodeMCU

  • ESP8266-01
  • Neo Pixel LED Strip
  • LM1117 Voltage Regulator
  • DC Power Jack (Female)
  • 2× 10µf Capacitor

 

Programming ESP8266-01 Using Arduino Uno

Instead of using the FTDI board, here I am using Arduino Uno to program the ESP8266-01. The circuit diagram for programming ESP8266-01 using Arduino is given below:

ESP8266-01 Using Arduino Uno

Connect the VCC and GND of ESP-01 to 3.3V and GND of Arduino also connect CH_PD to 3.3V and GPIO_0 to GND of Arduino. Connect RX and TX of ESP-01 to RX & TX of Arduino Uno respectively. GPIO_0 is grounded to enable the programming mode of ESP8266. After making the circuit as per the diagram, connect the Reset pin of the Arduino to GND to bypass the Arduino. It will disable Arduino and upload code directly to the ESP8266 board. Connect RST pin of ESP-01 to ground, remove the RST after half a second (the blue LED flashes for some millisecond).

Now, power up the Arduino Uno and open the Arduino IDE. Select the “Generic ESP8266 Module” in Board type and upload the code. 

 

Circuit Diagram to Interface Neopixel with ESP8266 

After uploading the code, remove the Arduino Uno and connect the Neopixel LED strip with ESP-01 as per the diagram.

interfacing Neopixel with ESP8266

VCC and CH_PD pins of ESP-01 are connected to the output pin of LM1117 while the GND pin is connected to the –ve rail of the 5V power supply. The data pin of the Neopixel LED is connected to the GPIO2 pin of ESP-01. This complete setup will be powered by a 5V Adapter. The LM117 voltage regulator is used to regulate 3.3V for the ESP8266-01 board.

 

After soldering all the components on the perf board, it will look something like below:

ESP8266 based Neopixel LED Controller

 

Setting up the Blynk App

Blynk is an application that can run on Android and iOS devices to control any IoT device. By using the Blynk app, the user can create their own Graphical User Interface to design the IoT application GUI. We previously used Blynk in many other IoT based projects.

Before the setup, download the Blynk Application from the Google Play store (iOS users can download it from Apple Store) and sign-up if you don’t have an account.

 

Creating a New Project:

After successful installation, open the application and click on “New Project”. On the next screen set the parameters like project name, board type, and connection type. For this project, select the device as “ESP8266” and connection type as Wi-Fi and click on “Create”.

Blynk New Project

 

Creating the GUI:

Open the project in Blynk, click on the “+” sign where it will show many widgets. In our case, we need an RGB Color Picker which is listed as “zeRGBa” and a Button that will be used for changing the mode of operation in the LED strip.

Blynk GUI

 

Setting the Parameter in Widgets:

After adding all the widgets, now set the widget parameters that are used to send the color and mode of control values to ESP-01.

Click on ZeRGBa, and we will get a screen named ZeRGBa Settings. Set the Output option to “Merge” and set the pin to “V2” as shown in the image below. Similarly, in Button settings, set the output pin to “V3” as shown in the figure below.

Blynk Widget

 

Getting the Auth Token:

Once you create a new project, Blynk mails you the Auth Token for that project. You can also get your Blynk auth token from your project page. Just click on the nut icon and copy the auth token using the copy all option and paste it somewhere safe. We will need it while programming the ESP-01.

Blynk Auth Token

 

Setting up IFTTT with Google Assistant and Blynk

IFTTT aka ‘If This, Then That’ is a web-based service to create chains of simple conditional statements, called Applets. It enables users to create triggers and execute actions based on the triggers. In this project, we are using IFTTT to create a trigger when we say a specific line using Google Assistant. For that, we have to create an applet in which we will integrate the Google Assistant with Blynk App using Webhooks.

First of all, create an account on IFTTT. To do so, navigate to the IFTTT website and click on signup. Then fill your details and click on create an account. Now, as you are signed in to your account, click on your profile and then click on ‘Create.’

 

NOTE: Sign in to IFTTT using the same Email ID as used in your Android phone’s Google account. For example, if your phone is signed using the xyz@gmail.com Email ID, then sign in to IFTTT using the same Email ID.

IFTTT Create

 

Now create an applet using If ‘This’ Then ‘That.’ Here ‘This’ is the service name by which we will give input and ‘That’ will generate trigger according to input. So in this project, we will use Google Assistant as ‘This’ and Webhooks as ‘That.’ So to create an applet, click on the ‘This’ icon and search for ‘Google Assistant.’ Here IFTTT will ask for permission for using your Google account.

IFTTT Applet

 

Now in Google Assistant, click on ‘Say a simple phrase with a text ingredient.’

IFTTT with Google Assistant

 

Now in the next window, it will ask you about the phrase that you want to say to your Google Assistant and what you want to hear in response to that phrase. You can also add some optional phrases. Now click on 'Create Trigger'.

IFTTT Trigger

 

Now, one part of this applet is complete. For the second part, click on the ‘That.’

IFTTT

 

In the search window, search for ‘webhooks’, and in the next window click on ‘Make a web request’.

IFTTT Webhooks

 

In the next window, enter the URL. The syntax of API is as below:

http://188.166.206.43/He3ot0ZXrYQcROYlwOIuVu-F/update/V1?value=

Where: 188.166.206.43 is the Blynk IP address in India, He3ot0ZXrYQcROYlwOIuVu-F is the Auth Token, and V1 is the virtual pin1.

Setting up IFTTT with Blynk

 

3D Printed Casing for ESP-01

I measured the dimensions of the setup using the scale and also measured the dimensions of the barrel jack to design a casing for my setup. Once it was done, my design looked something like this.

3D Printed Casing for ESP-01

 

After finishing the design I exported it as an STL file, sliced it based on printer settings, and finally printed it. The STL file is also available for download from Thingiverse and you can print your casing using it. After the printing was done, I proceeded with assembling the project set up in a permanent enclosure to install it in a facility. With the complete connection made, I assembled the circuit into my casing and everything was a nice fit as you can see here.

Neopixel LED Controller using ESP-01

 

Programming ESP-01 for Controlling Neopixel

The complete code for Controlling Neopixel using Google Assistant can be found at the bottom of this page. The explanation of the same is as follows. In this project, we are going to use Adafruit_NeoPixel.h and BlynkSimpleEsp8266.h libraries. These libraries can be directly downloaded from Arduino IDE. For that, go to the Sketch > Include Library > Manage Libraries. Search for ‘Adafruit Neo’ in the search box and download, and install the Blynk ESP8266 library.

Adafruit Neopixel Library

 

Follow the same procedure for installing the Blynk library for ESP8266.

Blynk Library for ESP8266

 

After installing the libraries, begin the code by including all the required library files and defining the input and output pins

#include <Adafruit_NeoPixel.h>
#include <ESP8266WiFi.h>
#define BLYNK_PRINT Serial
#include <BlynkSimpleEsp8266.h>
#define PIXEL_PIN    2 
#define PIXEL_COUNT 56 

 

In the next lines, enter the Blynk and Wi-Fi credentials like auth token and the Wi-Fi name and password for the Wi-Fi to which ESP-01 should connect with. The blink auth token can be obtained from the Blynk application.

char auth[] = "wgdhfbm5uPqSp03bdMkxjr_VQwwCJ8Kw";
char ssid[] = "Galaxy-M20";
char pass[] = "ac312124";

 

After that, declare the NeoPixel strip object where Argument 1 is the number of pixels in the NeoPixel strip and Argument 2 is the ESP-01 pin where the LED strip is connected.

Adafruit_NeoPixel strip(PIXEL_COUNT, PIXEL_PIN, NEO_GRB + NEO_KHZ800);

 

The BLYNK_WRITE() function is used to check for incoming data at V1, V2, and V3 Virtual pins. The virtual pin V1 is for receiving the Google Assistant data from webhooks URL while V2 and V3 pins are used to change the Neopixel color and mode from the Blynk app.

BLYNK_WRITE(V1)
{
  ON_message = param.asStr();
  Serial.println (ON_message);
  }
BLYNK_WRITE(V2)
{
r = param[0].asInt();
g = param[1].asInt();
b = param[2].asInt();
if(data==0)
static1(r,g,b);
}
BLYNK_WRITE(V3)
{
data = param.asInt();
if(data==0)
{
  static1(r,g,b);
}

 

Inside the loop() function, Blynk.run() checks for incoming commands from Blynk GUI. The incoming string is then saved into a variable and using the if condition, it executes the operations accordingly.

void loop() {
      Blynk.run();
      if(ON_message.indexOf("off") >= 0)
  {
    colorWipe(strip.Color(  0,   0,   0), 50);   
    delay(1000);
   }
  if(ON_message.indexOf("red") >= 0)
  {
    colorWipe(strip.Color(255,   0,   0), 50);    // Red
    delay(1000);
   }
…………………………….

 

Controlling Neopixel with Blynk and Google Assistant

Once your code and hardware are ready, upload the code on ESP-01 using Arduino Uno. After that, connect the Neopixel LED and say "Okay Google, turn on rainbow mode" or “turn on theatre mode” to your Google Assistant. Google Assistant will recognize the phrase and respond with "ok turning on" and Neopixel will illuminate according to the command. You can also use the Blynk to control the Neopixel color.

Controlling Neopixel with Blynk and Google Assistant

This is how you can control ESP8266 with Google Assistant. The complete working video and code for this project are given below. I hope you enjoyed building this project. If you have any questions, please leave them in the comment section.

Code

#include <Adafruit_NeoPixel.h>
#include <ESP8266WiFi.h>
#define BLYNK_PRINT Serial
#include <BlynkSimpleEsp8266.h>
#define PIXEL_PIN    2  // Digital IO pin connected to the NeoPixels.
#define PIXEL_COUNT 56  // Number of NeoPixels
char auth[] = "wgdhfbm5uPqSp03bdMkxjr_VQwwCJ8Kw"; //get from blynk application 
char ssid[] = "Galaxy-M20";
char pass[] = "ac312124";
Adafruit_NeoPixel strip(PIXEL_COUNT, PIXEL_PIN, NEO_GRB + NEO_KHZ800);
int     mode     = 0;    // Currently-active animation mode, 0-9
int r,g,b,data;
String ON_message;
void setup() {
  Serial.begin(9600);
  Blynk.begin(auth, ssid, pass);
  Serial.print("\n\nConnecting Wifi... ");
  WiFi.begin(ssid, pass);
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
  }
  Serial.println("OK!");
  strip.begin(); // Initialize NeoPixel strip object (REQUIRED)
  strip.show();  // Initialize all pixels to 'off'
 }
void loop() {
      Blynk.run();
      if(ON_message.indexOf("off") >= 0)
  {
    colorWipe(strip.Color(  0,   0,   0), 50);    // Black/off
    delay(1000);
   }
  if(ON_message.indexOf("red") >= 0)
  {
    colorWipe(strip.Color(255,   0,   0), 50);    // Red
    delay(1000);
   }
  if(ON_message.indexOf("green") >= 0)
   {
     colorWipe(strip.Color(  0, 255,   0), 50);    // Green
     delay(1000);
   }
  if(ON_message.indexOf("blue") >= 0)
  {
   colorWipe(strip.Color(  0,   0, 255), 50);    // Blue
   delay(1000);
  }
  if(ON_message.indexOf("white") >= 0)
   {
    theaterChase(strip.Color(127, 127, 127), 50); // White
    delay(1000);
   }
  if(ON_message.indexOf("theater") >= 0)
  {
   theaterChase(strip.Color(127,   0,   0), 50); // Red
   delay(1000);
   theaterChase(strip.Color(  0,   0, 127), 50); // Blue
   delay(1000);
  }
  if(ON_message.indexOf("rainbow") >= 0)
  {
   rainbow(10);
   delay(1000);
   theaterChaseRainbow(50);
   delay(1000);
  }
}
BLYNK_WRITE(V1)
{
  ON_message = param.asStr();
  Serial.println (ON_message);
}
BLYNK_WRITE(V2)
{
r = param[0].asInt();
g = param[1].asInt();
b = param[2].asInt();
if(data==0)
static1(r,g,b);
}
BLYNK_WRITE(V3)
{
data = param.asInt();
Serial.println(data);
if(data==0)
{
  static1(r,g,b);
}
else if(data==1)
{
  animation1(); 
}
}
void static1(int r, int g, int b)
{
  for(int i=0;i<=PIXEL_COUNT;i++)
  {
  strip.setPixelColor(i, strip.Color(r,g,b));
  strip.show();
  }
}
void animation1()
{
  for(int i=0;i<PIXEL_COUNT;i++)
  {
    strip.setPixelColor(i, strip.Color(255,0,0));
    strip.show();
    delay(100);
  }
  for(int i=PIXEL_COUNT;i>=0;i--)
  {
    strip.setPixelColor(i, strip.Color(0,255,0));
    strip.show();
    delay(100);
  }
  for(int i=0;i<PIXEL_COUNT;i++)
  {
    strip.setPixelColor(i, strip.Color(0,255,255));
    strip.show();
    delay(100);
  }
  for(int i=PIXEL_COUNT;i>=0;i--)
  {
    strip.setPixelColor(i, strip.Color(255,255,0));
    strip.show();
    delay(100);
  }
}
void colorWipe(uint32_t color, int wait) {
  for(int i=0; i<strip.numPixels(); i++) { // For each pixel in strip...
    strip.setPixelColor(i, color);         //  Set pixel's color (in RAM)
    strip.show();                          //  Update strip to match
    delay(wait);                           //  Pause for a moment
  }
}
void theaterChase(uint32_t color, int wait) {
  for(int a=0; a<10; a++) {  // Repeat 10 times...
    for(int b=0; b<3; b++) { //  'b' counts from 0 to 2...
      strip.clear();         //   Set all pixels in RAM to 0 (off)
      // 'c' counts up from 'b' to end of strip in steps of 3...
      for(int c=b; c<strip.numPixels(); c += 3) {
        strip.setPixelColor(c, color); // Set pixel 'c' to value 'color'
      }
      strip.show(); // Update strip with new contents
      delay(wait);  // Pause for a moment
    }
  }
}
void rainbow(int wait) {
  for(long firstPixelHue = 0; firstPixelHue < 3*65536; firstPixelHue += 256) {
    for(int i=0; i<strip.numPixels(); i++) { // For each pixel in strip...
      int pixelHue = firstPixelHue + (i * 65536L / strip.numPixels());
      strip.setPixelColor(i, strip.gamma32(strip.ColorHSV(pixelHue)));
    }
    strip.show(); // Update strip with new contents
    delay(wait);  // Pause for a moment
  }
}
void theaterChaseRainbow(int wait) {
  int firstPixelHue = 0;     // First pixel starts at red (hue 0)
  for(int a=0; a<30; a++) {  // Repeat 30 times...
    for(int b=0; b<3; b++) { //  'b' counts from 0 to 2...
      strip.clear();         //   Set all pixels in RAM to 0 (off)
      for(int c=b; c<strip.numPixels(); c += 3) {
        int      hue   = firstPixelHue + c * 65536L / strip.numPixels();
        uint32_t color = strip.gamma32(strip.ColorHSV(hue)); // hue -> RGB
        strip.setPixelColor(c, color); // Set pixel 'c' to value 'color'
      }
      strip.show();                // Update strip with new contents
      delay(wait);                 // Pause for a moment
      firstPixelHue += 65536 / 90; // One cycle of color wheel over 90 frames
    }
  }
}

Video