IoT based projects using ESP32 with Google Alexa

IoT based projects using ESP32 with Google Home & Alexa

Make simple IoT-based Projects using ESP32 to control Relays with Google Assistant and Alexa with voice commands. With Circuit & Code.

In this ESP32 project, I have explained how to make IoT-based projects using ESP32 with Google Home & Alexa. With this Internet of Things project, you can control 3 home appliances with Google Assistant, Alexa, and manual switches. You can also control the relays from Google Home and Amazon Alexa App from anywhere in the world.

And you don’t need any Google Nest or Amazon Echo Dot devices for this voice control home automation project.

Smart Home with Google Assistant and Alexa

With this home automation project, you can control & monitor the real-time feedback of the relays in the Google Home and Alexa App from anywhere in the world. If the Wi-Fi is available, the ESP32 will automatically connect with the Wi-Fi.

IoT based projects using ESP32

For this project, I have used all the FREE tools. So if you follow all the steps, you can easily make this Smart Home System with Google Home and Amazon Alexa to control the appliances with voice commands.

Circuit of the ESP32 Home Automation

Circuit of the ESP32 Home Automation

The circuit is very simple, I have used D23, D22, D21 & D19 GPIO to control the 4-channel relay module.

And the GPIO D13, D12, D14 & D27 are connected with switches to control the relay module manually.

I have used the INPUT_PULLUP function in Arduino IDE instead of using the pull-up resistors with each push button.

As per the source code, when the control pins of the relay module receive a LOW signal the relay will turn on and the relay will turn off for the HIGH signal in the control pin.

I have used a 5V 5Amp mobile charger to supply the circuit.

Required Components for the ESP32 projects

ESP32 Home automation
  1. ESP32 DevKIT V1 Amazon
  2. 4-channel 5V SPDT Relay Module Amazon
  3. Manual Switches or Pushbuttons Amazon
  4. Amazon Echo Dot (optional) Amazon
  5. Google Nest Mini (optional)

Tutorial video on Smart Home with Google & Alexa

In the tutorial video, I have covered the following steps in details.

  • Control 3 relays with Google Assistant, Alexa, and switches.
  • Create an account and add devices in Sinric Pro
  • Programming the ESP32 with Arduino IDE
  • Connect Sinric Pro with Amazon Alexa App.
  • Connect Sinric Pro with Google Home App.

Sinric Pro FREE account setup

For this smart house project, I have used the Sinric Pro Free account. First, you have to add 3 devices to the Sinric Pro account.

I have already explained, how to set up and add devices to Sinric Pro in following article.

Program ESP32 with Arduino IDE

In the Tutorial video, I have explained all the steps to program the ESP32 using Arduino IDE.

  1. Update the Preferences –> Additional Boards Manager URLs: https://dl.espressif.com/dl/package_esp32_index.json, http://arduino.esp8266.com/stable/package_esp8266com_index.json
  2. Then install the ESP32 board from the Board Manager or Click Here to download the ESP32 board.
  3. Download the required libraries from the following links:
  • Sinric Pro by Boris Jaeger (Download Sinric Pro examples for ESP8266 & ESP32)
  • WebSockets by Markus Sattler (minimum Version 2.3.5)
  • ArduinoJson by Benoit Blanchon (minimum Version 6.12.0)

Click Here to visit the GitHub page of Sinric Pro for more details.

**Please download the latest version of the libraries from the given links. Then install the libraries at Arduino IDE – SketchInclude LibraryAdd Zip Library.

Code for ESP32 home automation system

// Uncomment the following line to enable serial debug output
//#define ENABLE_DEBUG

#ifdef ENABLE_DEBUG
       #define DEBUG_ESP_PORT Serial
       #define NODEBUG_WEBSOCKETS
       #define NDEBUG
#endif 

#include <Arduino.h>
#include <WiFi.h>
#include "SinricPro.h"
#include "SinricProSwitch.h"

#include <map>

#define WIFI_SSID         "YOUR-WIFI-NAME"    
#define WIFI_PASS         "YOUR-WIFI-PASSWORD"
#define APP_KEY           "YOUR-APP-KEY"      // Should look like "de0bxxxx-1x3x-4x3x-ax2x-5dabxxxxxxxx"
#define APP_SECRET        "YOUR-APP-SECRET"   // Should look like "5f36xxxx-x3x7-4x3x-xexe-e86724a9xxxx-4c4axxxx-3x3x-x5xe-x9x3-333d65xxxxxx"

//Enter the device IDs here
#define device_ID_1   "SWITCH_ID_NO_1_HERE"
#define device_ID_2   "SWITCH_ID_NO_2_HERE"
#define device_ID_3   "SWITCH_ID_NO_3_HERE"
#define device_ID_4   "SWITCH_ID_NO_4_HERE"

// define the GPIO connected with Relays and switches
#define RelayPin1 23  //D23
#define RelayPin2 22  //D22
#define RelayPin3 21  //D21
#define RelayPin4 19  //D19

#define SwitchPin1 13  //D13
#define SwitchPin2 12  //D12
#define SwitchPin3 14  //D14
#define SwitchPin4 27  //D27

#define wifiLed   2   //D2

// comment the following line if you use a toggle switches instead of tactile buttons
//#define TACTILE_BUTTON 1

#define BAUD_RATE   9600

#define DEBOUNCE_TIME 250

typedef struct {      // struct for the std::map below
  int relayPIN;
  int flipSwitchPIN;
} deviceConfig_t;


// this is the main configuration
// please put in your deviceId, the PIN for Relay and PIN for flipSwitch
// this can be up to N devices...depending on how much pin's available on your device ;)
// right now we have 4 devicesIds going to 4 relays and 4 flip switches to switch the relay manually
std::map<String, deviceConfig_t> devices = {
    //{deviceId, {relayPIN,  flipSwitchPIN}}
    {device_ID_1, {  RelayPin1, SwitchPin1 }},
    {device_ID_2, {  RelayPin2, SwitchPin2 }},
    {device_ID_3, {  RelayPin3, SwitchPin3 }},
    {device_ID_4, {  RelayPin4, SwitchPin4 }}     
};

typedef struct {      // struct for the std::map below
  String deviceId;
  bool lastFlipSwitchState;
  unsigned long lastFlipSwitchChange;
} flipSwitchConfig_t;

std::map<int, flipSwitchConfig_t> flipSwitches;    // this map is used to map flipSwitch PINs to deviceId and handling debounce and last flipSwitch state checks
                                                  // it will be setup in "setupFlipSwitches" function, using informations from devices map

void setupRelays() { 
  for (auto &device : devices) {           // for each device (relay, flipSwitch combination)
    int relayPIN = device.second.relayPIN; // get the relay pin
    pinMode(relayPIN, OUTPUT);             // set relay pin to OUTPUT
    digitalWrite(relayPIN, HIGH);
  }
}

void setupFlipSwitches() {
  for (auto &device : devices)  {                     // for each device (relay / flipSwitch combination)
    flipSwitchConfig_t flipSwitchConfig;              // create a new flipSwitch configuration

    flipSwitchConfig.deviceId = device.first;         // set the deviceId
    flipSwitchConfig.lastFlipSwitchChange = 0;        // set debounce time
    flipSwitchConfig.lastFlipSwitchState = true;     // set lastFlipSwitchState to false (LOW)--

    int flipSwitchPIN = device.second.flipSwitchPIN;  // get the flipSwitchPIN

    flipSwitches[flipSwitchPIN] = flipSwitchConfig;   // save the flipSwitch config to flipSwitches map
    pinMode(flipSwitchPIN, INPUT_PULLUP);                   // set the flipSwitch pin to INPUT
  }
}

bool onPowerState(String deviceId, bool &state)
{
  Serial.printf("%s: %s\r\n", deviceId.c_str(), state ? "on" : "off");
  int relayPIN = devices[deviceId].relayPIN; // get the relay pin for corresponding device
  digitalWrite(relayPIN, !state);             // set the new relay state
  return true;
}

void handleFlipSwitches() {
  unsigned long actualMillis = millis();                                          // get actual millis
  for (auto &flipSwitch : flipSwitches) {                                         // for each flipSwitch in flipSwitches map
    unsigned long lastFlipSwitchChange = flipSwitch.second.lastFlipSwitchChange;  // get the timestamp when flipSwitch was pressed last time (used to debounce / limit events)

    if (actualMillis - lastFlipSwitchChange > DEBOUNCE_TIME) {                    // if time is > debounce time...

      int flipSwitchPIN = flipSwitch.first;                                       // get the flipSwitch pin from configuration
      bool lastFlipSwitchState = flipSwitch.second.lastFlipSwitchState;           // get the lastFlipSwitchState
      bool flipSwitchState = digitalRead(flipSwitchPIN);                          // read the current flipSwitch state
      if (flipSwitchState != lastFlipSwitchState) {                               // if the flipSwitchState has changed...
#ifdef TACTILE_BUTTON
        if (flipSwitchState) {                                                    // if the tactile button is pressed 
#endif      
          flipSwitch.second.lastFlipSwitchChange = actualMillis;                  // update lastFlipSwitchChange time
          String deviceId = flipSwitch.second.deviceId;                           // get the deviceId from config
          int relayPIN = devices[deviceId].relayPIN;                              // get the relayPIN from config
          bool newRelayState = !digitalRead(relayPIN);                            // set the new relay State
          digitalWrite(relayPIN, newRelayState);                                  // set the trelay to the new state

          SinricProSwitch &mySwitch = SinricPro[deviceId];                        // get Switch device from SinricPro
          mySwitch.sendPowerStateEvent(!newRelayState);                            // send the event
#ifdef TACTILE_BUTTON
        }
#endif      
        flipSwitch.second.lastFlipSwitchState = flipSwitchState;                  // update lastFlipSwitchState
      }
    }
  }
}

void setupWiFi()
{
  Serial.printf("\r\n[Wifi]: Connecting");
  WiFi.begin(WIFI_SSID, WIFI_PASS);

  while (WiFi.status() != WL_CONNECTED)
  {
    Serial.printf(".");
    delay(250);
  }
  digitalWrite(wifiLed, HIGH);
  Serial.printf("connected!\r\n[WiFi]: IP-Address is %s\r\n", WiFi.localIP().toString().c_str());
}

void setupSinricPro()
{
  for (auto &device : devices)
  {
    const char *deviceId = device.first.c_str();
    SinricProSwitch &mySwitch = SinricPro[deviceId];
    mySwitch.onPowerState(onPowerState);
  }

  SinricPro.begin(APP_KEY, APP_SECRET);
  SinricPro.restoreDeviceStates(true);
}

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

  pinMode(wifiLed, OUTPUT);
  digitalWrite(wifiLed, LOW);

  setupRelays();
  setupFlipSwitches();
  setupWiFi();
  setupSinricPro();
}

void loop()
{
  SinricPro.handle();
  handleFlipSwitches();
}


Enter the APP KEY and APP SECRET with Wi-Fi name and Wi-Fi password in the code.

You can get the APP KEY and APP SECRET under the Credentials menu in Sinric Pro

#define WIFI_SSID         "YOUR-WIFI-NAME"    
#define WIFI_PASS "YOUR-WIFI-PASSWORD"
#define APP_KEY "YOUR-APP-KEY"
#define APP_SECRET "YOUR-APP-SECRET"

Also enter the device id in the code. You will find the Device ID from Devices menu.

//Enter the device IDs here
#define device_ID_1 "SWITCH_ID_NO_1_HERE"
#define device_ID_2 "SWITCH_ID_NO_2_HERE"
#define device_ID_3 "SWITCH_ID_NO_3_HERE"
#define device_ID_4 "SWITCH_ID_NO_4_HERE"

**When you add a device in Sinric Pro, a unique ID will be assigned to that device. If you create 3 devices, then there will be 3 unique device IDs.

As I am using a free Sinric pro account, so I have entered the 3-device IDs. (Sinric Pro gives 3 devices for FREE)

Uncomment the following line if you use pushbuttons instead of toggle switches.

//#define TACTILE_BUTTON 1

After uploading the code to ESP32, please refer to the following articles for connecting the Sinric Pro Account with Amazon Alexa and Google Home App.

After doing all these steps, now you control the appliances with Google Assistant and Alexa.

ESP32 control Relays with Alexa App

If the ESP32 is connected with Wi-Fi, then you can ask Alexa, to turn on the light [“Alexa, Turn ON Room Light“]. Thus, you can control the appliances like light, fan, etc with voice commands using Amazon Alexa App, and also monitor the current status of the switches from anywhere in the world from the Alexa App.

ESP32 control Relays with Google Assistant

You can also ask Google Assistant, to control the light [“Hey Google, Turn ON the Room Light“]. Thus, you can control the appliances like light, fan, etc with voice commands using Google Assistant, and also monitor the real-time feedback and control the relays from anywhere in the world from the Google Home App.

Control relays manually with Switches

Control relays with Switches

You can always control the appliances manually with switches or push buttons and monitor the real-time status in Google Home and Alexa App.

I hope you like this Smart house IoT projects idea with the Espressif ESP32.

Click Here for more such ESP32 projects.

Please do share your feedback on this IoT project. Thank you for your time.