ESP32

ESP32 Home Automation using ESP RainMaker

ESP32 Based Smart Home Automation

In this tutorial, we will make another ESP32 Home Automation using ESP RainMaker IoT Project to control 4 appliances with Google Assistant, Alexa, and manual switches. You can monitor the real-time feedback and the sensor readings on your smartphone from anywhere in the world. You can still control the appliances with manual switches when there is no internet. 

During the tutorial, We will also add some automation to turn ON and OFF the devices automatically according to the predefined time schedule.


Also Read:


Overview: ESP32 Smart Home Automation

ESP32 Rainmaker project

Now before going to the details, let me show you how the project works. If you see the blue LED glowing on ESP32 then it indicates that ESP32 is connected to your WiFi Network.


Control Appliances with Google Assistant

Home Automation using ESP RainMaker & Google Assistant

So I can control it with Google Assistant and Alexa. “Hey Google, turn on switch-1“. you can see the light turned on. “OK Google, turn on switch-3” Now let me give multiple commands at once to google assistant. “Hey Google, turn off switch-1 and switch-3”. As you can see the led bulbs connected to switch-1 & Switch-3 are off.

Home Automation using Google Assistant
ESP32 Home Automation using ESP RainMaker

Control Appliances with Amazon Alexa

Now let me turn it on with Alexa. “Alexa turn on switch 2 and Switch 4“. you can see the light turn on. and I can also easily turn on and off all the lights with a single command. “Hey, Google turn on all switches”. “Hey Google, Turn off all the switches” As you can see all the lights turn on and off together.

The best part of this project is if you have any Alexa or Google assistant supported device then you can control appliances from them directly. For demonstration, I have this smartwatch which has built-in Alexa support. So, I can directly control the appliances from this smartwatch as well. “Turn On switch 1. Isn’t it interesting and exciting features?

ESP32 Home Automation using Amazon Alexa

Control Appliances with Manual Switches

Now let me use manual switches to control these lights. you can see, that I can easily control all the lights with the manual switches. now let me turn off the Wi-Fi and show you how it works without the internet. after turning off the Wi-Fi you can see the blue LED turn OFF. So I can only control these appliances using manual switches. let me turn on the Wi-Fi again. if the Wi-Fi is available, the ESP32 will automatically connect with Wi-Fi and the blue LED will turn on. now again I can control all these lights with Alexa and Google Assistant.

Home Automation using ESP RainMaker
ESP32 Home Automation using ESP RainMaker

Now let me go to the Rainmaker app, to control switches and monitor the sensor readings. Now I can control switches using these buttons. here you can see, the sensor readings, temperature, humidity, and the LDR. First, let me cover the LDR sensor with my hand. and you can see the value decreased. If I remove my hand, you can see the value increasing. now let me increase the temperature with external heat. You can see the value is increasing. 


Add Automation on ESP RainMaker

Now let me add some automation to control the relays with the predefined time schedule. For that, we need to create a schedule. Tap on schedule, and then tap on “add schedule“. Give a name, you can give any name. Then tap on ok. Now select a time. you can also repeat this automation. in the action I want the 2nd relay and 4th relay to turn on.  now let me tap on done, now I will save it. Now it is 12:40 pm and as per the automation at 12:41 pm. the 2nd and 4th relay should turn on.  

ESP Rainmaker Automation
ESP32 Home Automation using ESP RainMaker

you can see the 2nd and 4th relay automatically turn on. so this is a very useful feature. you can add any automation according to your requirement with the ESP Rainmaker app


Components Required

For this project, you don’t need any devices like google or amazon echo. We can easily control appliances using free applications. We have used all the free tools,  so you don’t have to spend money on the software part. If you have ESP32, relay module, DHT11/ DHT22 Temperature & Humidity Sensor, LDR Sensor, a few switches, and jumper cables then you can easily make this project at your home. During this tutorial, I have shared the circuit Diagram, source code, and all other configuration details. So you can easily do this project after going through this complete guide.

S.NComponents NameQuantityGet Products from Amazon
1ESP32 DEV KIT1 https://amzn.to/3OnuHeB
2DHT22 Sensor1https://amzn.to/3cbRQnp
3DHT11 Sensor1https://amzn.to/3CkDziN
4LDR Sensor1https://amzn.to/3pAg3aa
54-Channel Relay Module1https://amzn.to/3RP6ZLv
610K ohm resistor1https://amzn.to/3K7xMiq
7Jumper Wires10https://amzn.to/2JWSR44
8Breadboard1https://amzn.to/3n33uRT

Circuit Diagram

Now without any further delay let’s make this project. this is the circuit for this project. I have given the 5-volt supply to ESP32, the relay module, and the sensors. and the switches are connected across the GPIO pins and ground pins. Please take proper safety precautions while connecting these appliances with the relay module. as you can see the circuit is very simple, you can easily make it. but I will highly recommend you to use a PCB for this project.

Circuit Diagram of ESP32 Home Automation using ESP RainMaker
Circuit Diagram of ESP32 Home Automation using ESP RainMaker

PCB Designing & Ordering Online

To test the project you can use breadboard assembly. But if you want to implement this project on your home electric board then I recommend you to use a zero PCB or use a custom PCB to avoid any loose connections and short circuits.  

  • ESP32 Home Automation PCB
  • ESP32 Home Automation PCB
  • ESP32 Home Automation PCB

I have already designed a custom PCB for this project. You can go to the download links to download the project Gerber file and order directly from PCBWay.com.

Because pcbway is a one-stop solution for all your PCB needs like PCB prototyping, SMD stencils, PCB assembly, etc. currently, they have moved to a new factory and offering you up to 20% discount on 4-layer PCBs and 6-layer PCBs. PCBWay provides high-quality material TG150-160 but keeps the same price as TG 130-140.

So, get your first prototype PCB ready from pcbway.com


Program Code

This is the source code for ESP32 Home Automation using ESP RainMaker project.

/**********************************************************************************
  -----------------------
  Smart Home Automation using ESP32 Rain Maker with Real time feedback + no WiFi control
  -----------------------
  Website: https://iotprojectsideas.com/
  -----------------------
    Preferences--> Aditional boards Manager URLs :
    https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
 **********************************************************************************/

#include "RMaker.h"
#include "WiFi.h"
#include "WiFiProv.h"
#include <DHT.h>
#include <SimpleTimer.h>

const char *service_name = "PROV_SmartHome";
const char *pop = "1234";

// define the Chip Id
uint32_t espChipId = 5;

// define the Node Name
char nodeName[] = "ESP32_Smarthome";

// define the Device Names
char deviceName_1[] = "Switch1";
char deviceName_2[] = "Switch2";
char deviceName_3[] = "Switch3";
char deviceName_4[] = "Switch4";

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

static uint8_t SwitchPin1 = 13;  //D13
static uint8_t SwitchPin2 = 12;  //D12
static uint8_t SwitchPin3 = 14;  //D14
static uint8_t SwitchPin4 = 27;  //D27

static uint8_t wifiLed      = 2;   //D2
static uint8_t gpio_reset   = 0;
static uint8_t DHTPIN       = 18; // D18  pin connected with DHT
static uint8_t LDR_PIN      = 39; // VN  pin connected with LDR

/* Variable for reading pin status*/
// Relay State
bool toggleState_1 = LOW; //Define integer to remember the toggle state for relay 1
bool toggleState_2 = LOW; //Define integer to remember the toggle state for relay 2
bool toggleState_3 = LOW; //Define integer to remember the toggle state for relay 3
bool toggleState_4 = LOW; //Define integer to remember the toggle state for relay 4

// Switch State
bool SwitchState_1 = LOW;
bool SwitchState_2 = LOW;
bool SwitchState_3 = LOW;
bool SwitchState_4 = LOW;

float temperature1 = 0;
float humidity1   = 0;
float ldrVal  = 0;

DHT dht(DHTPIN, DHT11);  //For DHT 11
//DHT dht(DHTPIN, DHT22);  //For DHT 22

SimpleTimer Timer;

//The framework provides some standard device types like switch, lightbulb, fan, temperature sensor.
static Switch my_switch1(deviceName_1, &RelayPin1);
static Switch my_switch2(deviceName_2, &RelayPin2);
static Switch my_switch3(deviceName_3, &RelayPin3);
static Switch my_switch4(deviceName_4, &RelayPin4);
static TemperatureSensor temperature("Temperature");
static TemperatureSensor humidity("Humidity");
static TemperatureSensor ldr("LDR");

void sysProvEvent(arduino_event_t *sys_event)
{
  switch (sys_event->event_id) {
    case ARDUINO_EVENT_PROV_START:
#if CONFIG_IDF_TARGET_ESP32
      Serial.printf("nProvisioning Started with name "%s" and PoP "%s" on BLEn", service_name, pop);
      printQR(service_name, pop, "ble");
#else
      Serial.printf("nProvisioning Started with name "%s" and PoP "%s" on SoftAPn", service_name, pop);
      printQR(service_name, pop, "softap");
#endif
      break;
    case ARDUINO_EVENT_WIFI_STA_CONNECTED:
      Serial.printf("nConnected to Wi-Fi!n");
      digitalWrite(wifiLed, true);
      break;
  }
}

void write_callback(Device *device, Param *param, const param_val_t val, void *priv_data, write_ctx_t *ctx)
{
  const char *device_name = device->getDeviceName();
  const char *param_name = param->getParamName();

  if (strcmp(device_name, deviceName_1) == 0) {

    Serial.printf("Lightbulb = %sn", val.val.b ? "true" : "false");

    if (strcmp(param_name, "Power") == 0) {
      Serial.printf("Received value = %s for %s - %sn", val.val.b ? "true" : "false", device_name, param_name);
      toggleState_1 = val.val.b;
      (toggleState_1 == false) ? digitalWrite(RelayPin1, HIGH) : digitalWrite(RelayPin1, LOW);
      param->updateAndReport(val);
    }

  } else if (strcmp(device_name, deviceName_2) == 0) {

    Serial.printf("Switch value = %sn", val.val.b ? "true" : "false");

    if (strcmp(param_name, "Power") == 0) {
      Serial.printf("Received value = %s for %s - %sn", val.val.b ? "true" : "false", device_name, param_name);
      toggleState_2 = val.val.b;
      (toggleState_2 == false) ? digitalWrite(RelayPin2, HIGH) : digitalWrite(RelayPin2, LOW);
      param->updateAndReport(val);
    }

  } else if (strcmp(device_name, deviceName_3) == 0) {

    Serial.printf("Switch value = %sn", val.val.b ? "true" : "false");

    if (strcmp(param_name, "Power") == 0) {
      Serial.printf("Received value = %s for %s - %sn", val.val.b ? "true" : "false", device_name, param_name);
      toggleState_3 = val.val.b;
      (toggleState_3 == false) ? digitalWrite(RelayPin3, HIGH) : digitalWrite(RelayPin3, LOW);
      param->updateAndReport(val);
    }

  } else if (strcmp(device_name, deviceName_4) == 0) {

    Serial.printf("Switch value = %sn", val.val.b ? "true" : "false");

    if (strcmp(param_name, "Power") == 0) {
      Serial.printf("Received value = %s for %s - %sn", val.val.b ? "true" : "false", device_name, param_name);
      toggleState_4 = val.val.b;
      (toggleState_4 == false) ? digitalWrite(RelayPin4, HIGH) : digitalWrite(RelayPin4, LOW);
      param->updateAndReport(val);
    }

  }
}

void readSensor() {

  ldrVal = map(analogRead(LDR_PIN), 400, 4200, 0, 100);
  Serial.print("LDR - "); Serial.println(ldrVal);
  float h = dht.readHumidity();
  float t = dht.readTemperature(); // or dht.readTemperature(true) for Fahrenheit

  if (isnan(h) || isnan(t)) {
    Serial.println("Failed to read from DHT sensor!");
    return;
  }
  else {
    humidity1 = h;
    temperature1 = t;
    Serial.print("Temperature - "); Serial.println(t);
    Serial.print("Humidity - "); Serial.println(h);
  }
}

void sendSensor()
{
  readSensor();
  temperature.updateAndReportParam("Temperature", temperature1);
  humidity.updateAndReportParam("Temperature", humidity1);
  ldr.updateAndReportParam("Temperature", ldrVal);
}

void manual_control()
{
  if (digitalRead(SwitchPin1) == LOW && SwitchState_1 == LOW) {
    digitalWrite(RelayPin1, LOW);
    toggleState_1 = 1;
    SwitchState_1 = HIGH;
    my_switch1.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_1);
    Serial.println("Switch-1 on");
  }
  if (digitalRead(SwitchPin1) == HIGH && SwitchState_1 == HIGH) {
    digitalWrite(RelayPin1, HIGH);
    toggleState_1 = 0;
    SwitchState_1 = LOW;
    my_switch1.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_1);
    Serial.println("Switch-1 off");
  }
  if (digitalRead(SwitchPin2) == LOW && SwitchState_2 == LOW) {
    digitalWrite(RelayPin2, LOW);
    toggleState_2 = 1;
    SwitchState_2 = HIGH;
    my_switch2.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_2);
    Serial.println("Switch-2 on");
  }
  if (digitalRead(SwitchPin2) == HIGH && SwitchState_2 == HIGH) {
    digitalWrite(RelayPin2, HIGH);
    toggleState_2 = 0;
    SwitchState_2 = LOW;
    my_switch2.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_2);
    Serial.println("Switch-2 off");
  }
  if (digitalRead(SwitchPin3) == LOW && SwitchState_3 == LOW) {
    digitalWrite(RelayPin3, LOW);
    toggleState_3 = 1;
    SwitchState_3 = HIGH;
    my_switch3.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_3);
    Serial.println("Switch-3 on");
  }
  if (digitalRead(SwitchPin3) == HIGH && SwitchState_3 == HIGH) {
    digitalWrite(RelayPin3, HIGH);
    toggleState_3 = 0;
    SwitchState_3 = LOW;
    my_switch3.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_3);
    Serial.println("Switch-3 off");
  }
  if (digitalRead(SwitchPin4) == LOW && SwitchState_4 == LOW) {
    digitalWrite(RelayPin4, LOW);
    toggleState_4 = 1;
    SwitchState_4 = HIGH;
    my_switch4.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_4);
    Serial.println("Switch-4 on");
  }
  if (digitalRead(SwitchPin4) == HIGH && SwitchState_4 == HIGH) {
    digitalWrite(RelayPin4, HIGH);
    toggleState_4 = 0;
    SwitchState_4 = LOW;
    my_switch4.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_4);
    Serial.println("Switch-4 off");
  }
}


void setup()
{

  Serial.begin(115200);

  // Set the Relays GPIOs as output mode
  pinMode(RelayPin1, OUTPUT);
  pinMode(RelayPin2, OUTPUT);
  pinMode(RelayPin3, OUTPUT);
  pinMode(RelayPin4, OUTPUT);
  pinMode(wifiLed, OUTPUT);

  // Configure the input GPIOs
  pinMode(SwitchPin1, INPUT_PULLUP);
  pinMode(SwitchPin2, INPUT_PULLUP);
  pinMode(SwitchPin3, INPUT_PULLUP);
  pinMode(SwitchPin4, INPUT_PULLUP);
  pinMode(gpio_reset, INPUT);

  // Write to the GPIOs the default state on booting
  digitalWrite(RelayPin1, !toggleState_1);
  digitalWrite(RelayPin2, !toggleState_2);
  digitalWrite(RelayPin3, !toggleState_3);
  digitalWrite(RelayPin4, !toggleState_4);
  digitalWrite(wifiLed, LOW);
  dht.begin();    // Enabling DHT sensor

  Node my_node;
  my_node = RMaker.initNode(nodeName);

  //Standard switch device
  my_switch1.addCb(write_callback);
  my_switch2.addCb(write_callback);
  my_switch3.addCb(write_callback);
  my_switch4.addCb(write_callback);

  //Add switch device to the node
  my_node.addDevice(my_switch1);
  my_node.addDevice(my_switch2);
  my_node.addDevice(my_switch3);
  my_node.addDevice(my_switch4);
  my_node.addDevice(temperature);
  my_node.addDevice(humidity);
  my_node.addDevice(ldr);

  Timer.setInterval(2000);

  //This is optional
  RMaker.enableOTA(OTA_USING_PARAMS);
  //If you want to enable scheduling, set time zone for your region using setTimeZone().
  //The list of available values are provided here https://rainmaker.espressif.com/docs/time-service.html
  // RMaker.setTimeZone("Asia/Shanghai");
  // Alternatively, enable the Timezone service and let the phone apps set the appropriate timezone
  RMaker.enableTZService();
  RMaker.enableSchedule();

  //Service Name
  for (int i = 0; i < 17; i = i + 8) {
    espChipId |= ((ESP.getEfuseMac() >> (40 - i)) & 0xff) << i;
  }

  Serial.printf("nChip ID:  %d Service Name: %sn", espChipId, service_name);

  Serial.printf("nStarting ESP-RainMakern");
  RMaker.start();

  WiFi.onEvent(sysProvEvent);
#if CONFIG_IDF_TARGET_ESP32
  WiFiProv.beginProvision(WIFI_PROV_SCHEME_BLE, WIFI_PROV_SCHEME_HANDLER_FREE_BTDM, WIFI_PROV_SECURITY_1, pop, service_name);
#else
  WiFiProv.beginProvision(WIFI_PROV_SCHEME_SOFTAP, WIFI_PROV_SCHEME_HANDLER_NONE, WIFI_PROV_SECURITY_1, pop, service_name);
#endif

  my_switch1.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, false);
  my_switch2.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, false);
  my_switch3.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, false);
  my_switch4.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, false);
}

void loop()
{
  // Read GPIO0 (external button to reset device
  if (digitalRead(gpio_reset) == LOW) { //Push button pressed
    Serial.printf("Reset Button Pressed!n");
    // Key debounce handling
    delay(100);
    int startTime = millis();
    while (digitalRead(gpio_reset) == LOW) delay(50);
    int endTime = millis();

    if ((endTime - startTime) > 10000) {
      // If key pressed for more than 10secs, reset all
      Serial.printf("Reset to factory.n");
      RMakerFactoryReset(2);
    } else if ((endTime - startTime) > 3000) {
      Serial.printf("Reset Wi-Fi.n");
      // If key pressed for more than 3secs, but less than 10, reset Wi-Fi
      RMakerWiFiReset(2);
    }
  }
  delay(100);

  if (WiFi.status() != WL_CONNECTED)
  {
    //Serial.println("WiFi Not Connected");
    digitalWrite(wifiLed, false);
  }
  else
  {
    //Serial.println("WiFi Connected");
    digitalWrite(wifiLed, true);
    if (Timer.isReady()) {
      //Serial.println("Sending Sensor Data");
      sendSensor();
      Timer.reset();      // Reset a second timer
    }
  }
  manual_control();
}

First of all, you have to update the ESP32 board to the latest version 2.0.4. So for that first, you have to copy the Preference links. then go to File, and select Preference. and here you have to update the URLs. After that click on OK. Then go to tools, select boards, then boards manager. Then search for ESP32. here you have to install the latest version 2.0.4. I have already installed it. You also need to install the DHT library from the library manager.

You can change the service name and password from here.

const char *service_name = "PROV_SmartHome";
const char *pop = "1234";

This is the name of a node and under this node, you will find all these 4 devices. If you want, you can change these names.  

// define the Node Name
char nodeName[] = "ESP32_Smarthome";

These are the device names, here I have given the names “Switch1“, “Switch2“, “Switch3“, and “Switch4” like that. but you can give any name as per your requirement, like Light, AC, TV, Fan, etc. 

// define the Device Names
char deviceName_1[] = "Switch1";
char deviceName_2[] = "Switch2";
char deviceName_3[] = "Switch3";
char deviceName_4[] = "Switch4";

Alexa and Google will identify the device with these names. The source code is compatible with both DHT11/DHT22 sensors so, you can uncomment this DHT22 part and comment the DHT11 part to use the DHT22 sensor instead of  DHT11. So, after doing the necessary changes,  you can directly upload this code to ESP32.  

For that, Go to tools and select the board as the ESP32 DEV module. then in the partition scheme and select the Rainmaker. and after that, Select the proper COM port. then hit the upload button. after uploading the code to ESP32.

Adding Device to ESP RainMaker

Open the serial monitor. here I have selected the baud rate 115200. Now you have to press and hold the boot button of the ESP32. Press and hold it for 4 seconds. Then release it. so you can see the QR code. I will just copy the link, just below the QR code. now you open a browser,  and here I will paste it, and press enter.

ESP Rainmaker QR Code

So now we have to scan the QR code with the  ESP Rainmaker App. you can download it from the Google Play Store or App Store. let me open the app. now first before I scan the QR code, I have to turn on the Bluetooth and GPS. after that I  will tap on “Add device“. now scan the QR code. then I have to enter the Wi-Fi details and tap on start. it may take some time. so now I will tap on done. so here you can see all the devices we have added.

Add device to ESP Rainmaker App

Now I will quickly connect to Amazon Alexa. so I will tap on the setting,  then I will tap on voice service. first I will tap on Amazon Alexa. and here tap on “Link with Amazon Alexa“. now you can enter the ID and password. now it is showing already linked with Amazon Alexa. now open the Amazon Alexa app. if I go to the device, I can see all the devices already added to the Amazon Alexa app.

Link Amazon Alexa with ESP RainMaker

Here, again I will go to the Rainmaker app.  now we will connect the Google Assistant. For that we have to open the Google Home app. let me open the Google home app. you can install this app from Google Play Store or App Store. now here tap on this “+” icon. first, I will create a Home. so I will tap on “create a new home“. and here let me give the name “ESP32 SmartHome”. you can give any name. now I will tap on continue. I will not enter any home address, so I will skip this step. and select continue without address. our home is created. now again I will tap on this “+” icon and select setup devices. and now tap on works with  Google. here I have to search for ESP RainMaker.

Link Google Assistant with ESP RainMaker

Let’s type the ESP. Now I have to tap on the ESP Rainmaker. Now tap on continue. Let me exit to the main dashboard. So here you can see, that all 4 devices were added successfully. and during this process, you can see the blue LED glowing which indicates now the ESP32 is connected to the Wi-Fi. 

ESP32 Rainmaker project
ESP32 Home Automation using ESP RainMaker

Conclusion

Therefore, this is a very useful ESP32 Home Automation using the ESP RainMaker IoT project, and you can easily make it at home. If you find this project helpful then please give a thumbs up and share it with your friends. Don’t forget to subscribe for more videos. Thank you for watching have a great day.


Related Articles

8 Comments

  1. Hi,
    Nice work!
    Is it possible to ask for the temperature or humidity in Google Home?
    like He google what is the temperature in the sleeping room.

    I tried but it only shows the switches in Google Home.

    Thanks in advance

  2. Hi,
    Good Project.
    Is it possible for temperature and humidity to add automation by setting the temperature or humidity set point then turn on/off some switches?

    Thanks for your reply.

  3. after recient updates to rainmaker and board firmware after uploading this code the esp32 boot loops

Leave a Reply

Your email address will not be published. Required fields are marked *

Back to top button