Hackster is hosting Hackster Holidays, Ep. 6: Livestream & Giveaway Drawing. Watch previous episodes or stream live on Monday!Stream Hackster Holidays, Ep. 6 on Monday!
Subhajit
Published © GPL3+

IoT Based Home Automation With Blynk and NodeMCU

This smart relay can sense the room temperature and sunlight to turn on and off the fan and light bulb. You can monitor the same from mobile

IntermediateFull instructions provided10 hours3,567
IoT Based Home Automation With Blynk and NodeMCU

Things used in this project

Hardware components

NodeMCU ESP8266 Breakout Board
NodeMCU ESP8266 Breakout Board
×1

Software apps and online services

Arduino IDE
Arduino IDE

Hand tools and fabrication machines

Soldering iron (generic)
Soldering iron (generic)

Story

Read more

Schematics

Circuit of the Smart Relay V4

Circuit for the IoT based home automation

Code

Code_SmartRelay_V4_1.3_OLED.ino

Arduino
If you use 1.3" OLED then refer this sketch
/**********************************************************************************
 *  TITLE: Blynk Home Automation with Physical Buttons and Tempareture and Light control Smart Relay V4 (OLED 1.3" I2C)
 *  Click on the following links to learn more. 
 *  YouTube Video: https://youtu.be/rRUUYXzJ4ZQ
 *  Related Blog : https://easyelectronicsproject.com/esp32-projects/
 *  by Tech StudyCell
 *  Download the libraries
 *  https://github.com/blynkkk/blynk-library/releases/download/v0.6.1/Blynk_Release_v0.6.1.zip
 *  https://github.com/adafruit/DHT-sensor-library
 *  https://github.com/ThingPulse/esp8266-oled-ssd1306
 **********************************************************************************/

#define BLYNK_PRINT Serial            
#include <BlynkSimpleEsp8266.h>  
#include <DHT.h>
#include <SH1106Wire.h> 

void checkPhysicalButton();

int toggleState_1 = 0;
int pushButton1State = LOW;

int toggleState_2 = 0;
int pushButton2State = LOW;

float temperature1 = 0;
float humidity1   = 0;
int   ldrVal;
int   switchMode = 0;

//Set values for Auto Control Mode
const float maxTemp = 34.10;
const float minTemp = 33.8;

const int maxLight = 1000;
const int minLight = 200;

#define AUTH "AUTH TOKEN"                 // You should get Auth Token in the Blynk App.  
#define WIFI_SSID "WIFI NAME"             //Enter Wifi Name
#define WIFI_PASS "WIFI PASSWORD"         //Enter wifi Password

#define PUSH_BUTTON_CMODE  15 //D8
#define LDR_PIN            A0 //A0
#define DHTPIN             10 //SD3  pin connected with DHT

#define RELAY_PIN_1      14   //D5
#define RELAY_PIN_2      12   //D6

#define PUSH_BUTTON_1    16   //D0
#define PUSH_BUTTON_2    13   //D7

#define VPIN_BUTTON_1    V1 
#define VPIN_BUTTON_2    V2
#define VPIN_BUTTON_C    V3

#define VPIN_HUMIDITY    V5
#define VPIN_TEMPERATURE V6

// Declaration for an SH1106 display connected to I2C (SDA, SCL pins)
SH1106Wire display(0x3c, D2, D1);

// Uncomment whatever type you're using!
#define DHTTYPE DHT11     // DHT 11
//#define DHTTYPE DHT22   // DHT 22, AM2302, AM2321
//#define DHTTYPE DHT21   // DHT 21, AM2301

DHT dht(DHTPIN, DHTTYPE);
BlynkTimer timer;

void changeMode(){      
  delay(200);
  if (switchMode == 0){
    switchMode = 1;
  }
  else if (switchMode == 1) {
    switchMode = 0;
  }
  display.clear();

  display.setFont(ArialMT_Plain_24);
  display.drawString(10, 5, "Set Mode: ");

  display.setFont(ArialMT_Plain_24);
  display.drawString(20, 35, String(modeDecode(switchMode)));    
  display.display();
  delay(500);
  Blynk.virtualWrite(VPIN_BUTTON_C, switchMode);
  //display.clear();
}

void relayOnOff(int relay){

    switch(relay){
      case 1: 
             if(toggleState_1 == 0){
              digitalWrite(RELAY_PIN_1, HIGH); // turn on relay 1
              toggleState_1 = 1;
              }
             else{
              digitalWrite(RELAY_PIN_1, LOW); // turn off relay 1
              toggleState_1 = 0;
              }
             delay(100);
      break;
      case 2: 
             if(toggleState_2 == 0){
              digitalWrite(RELAY_PIN_2, HIGH); // turn on relay 2
              toggleState_2 = 1;
              }
             else{
              digitalWrite(RELAY_PIN_2, LOW); // turn off relay 2
              toggleState_2 = 0;
              }
             delay(100);
      break;
      default : break;      
      }
  
}
String modeDecode(int count){
  if (count == 0){
    return " Manual ";
  }
  else if (count == 1){
    return " Auto ";
  }
}

void displayData(){
  display.clear();

  display.setFont(ArialMT_Plain_24);
  display.drawString(20, 0, String(temperature1) + " 'C");
  display.drawString(20, 25, String(humidity1) + " %");

  display.setFont(ArialMT_Plain_16);
  display.drawString(10, 48, "Mode -> ");
  display.drawString(68, 48, String(modeDecode(switchMode)));
  display.display();

  Serial.print(F("Temperature: "));
  Serial.print(temperature1);
  Serial.print("   ");
  Serial.print(F("humidity: "));
  Serial.print(humidity1);
  Serial.print("   ");
  Serial.println(ldrVal); 
  Serial.println("");
}

void readSensor(){
    
  ldrVal = analogRead(LDR_PIN);
  
  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;
  }  
}

void sendSensor()
{
  readSensor();
  // You can send any value at any time.
  // Please don't send more that 10 values per second.
  Blynk.virtualWrite(VPIN_HUMIDITY, humidity1);
  Blynk.virtualWrite(VPIN_TEMPERATURE, temperature1);
}

BLYNK_CONNECTED() {
  // Request the latest state from the server
  Blynk.syncVirtual(VPIN_BUTTON_1);
  Blynk.syncVirtual(VPIN_BUTTON_2);
  Blynk.syncVirtual(VPIN_BUTTON_C);
}

// When App button is pushed - switch the state

BLYNK_WRITE(VPIN_BUTTON_1) {
  toggleState_1 = param.asInt();
  digitalWrite(RELAY_PIN_1, toggleState_1);
}

BLYNK_WRITE(VPIN_BUTTON_2) {
  toggleState_2 = param.asInt();
  digitalWrite(RELAY_PIN_2, toggleState_2);
}

BLYNK_WRITE(VPIN_BUTTON_C) {
  switchMode = param.asInt();
}

void checkPhysicalButton()
{
  if (digitalRead(PUSH_BUTTON_1) == HIGH) {
      relayOnOff(1);
      // Update Button Widget
      Blynk.virtualWrite(VPIN_BUTTON_1, toggleState_1);
    }
  if (digitalRead(PUSH_BUTTON_2) == HIGH) {
      relayOnOff(2);
      // Update Button Widget
      Blynk.virtualWrite(VPIN_BUTTON_2, toggleState_2);
    }
}

void setup()
{
  Serial.begin(9600);
  
  // Initialising the UI will init the display too.
  display.init();
  display.flipScreenVertically();
  display.setFont(ArialMT_Plain_16);
  display.setTextAlignment(TEXT_ALIGN_LEFT);
  delay(1000);  

  display.setColor(WHITE);
  display.clear();

  pinMode(RELAY_PIN_1, OUTPUT);
  pinMode(PUSH_BUTTON_1, INPUT);
  digitalWrite(RELAY_PIN_1, toggleState_1);

  pinMode(RELAY_PIN_2, OUTPUT);
  pinMode(PUSH_BUTTON_2, INPUT);
  digitalWrite(RELAY_PIN_2, toggleState_2);

  Blynk.begin(AUTH, WIFI_SSID, WIFI_PASS);  
  // Setup a function to be called every 500 ms
  timer.setInterval(500L, checkPhysicalButton);
  
  dht.begin();
  // Setup a function to be called every second
  timer.setInterval(1000L, sendSensor);
  // Setup a function to be called every 2 second
  timer.setInterval(2000L, displayData);
}

void loop()
{
  if (digitalRead(PUSH_BUTTON_CMODE) == HIGH){
    changeMode();
  }   
  else{    
    if(switchMode == 1){ //if Auto Mode
      //DHT11 control Relay 1
      if(temperature1 > maxTemp){
        if(toggleState_1 == 0){
          digitalWrite(RELAY_PIN_1, HIGH); // turn ON relay 1
          toggleState_1 = 1;
          // Update Button Widget
          Blynk.virtualWrite(VPIN_BUTTON_1, toggleState_1);
        }
      }
      else if (temperature1 < minTemp){
        if(toggleState_1 == 1){
           digitalWrite(RELAY_PIN_1, LOW); // turn OFF relay 1
           toggleState_1 = 0;
           // Update Button Widget
           Blynk.virtualWrite(VPIN_BUTTON_1, toggleState_1);
          }
      }
      //LDR control Relay 2
      if( ldrVal < minLight){
        if(toggleState_2 == 0){
          digitalWrite(RELAY_PIN_2, HIGH); // turn ON relay 2
          toggleState_2 = 1;
          // Update Button Widget
          Blynk.virtualWrite(VPIN_BUTTON_2, toggleState_2);
        }
      }
      else if (ldrVal > maxLight){
        if(toggleState_2 == 1){
           digitalWrite(RELAY_PIN_2, LOW); // turn OFF relay 2
           toggleState_2 = 0;
           // Update Button Widget
           Blynk.virtualWrite(VPIN_BUTTON_2, toggleState_2);
          }
      } 
    }
    timer.run();
    Blynk.run();
  }
}

Code_SmartRelay_V4_0.96_OLED.ino

Arduino
If you use 0.96" OLED then refer this sketch
/**********************************************************************************
 *  TITLE: Blynk Home Automation with Physical Buttons and Tempareture and Light control Smart Relay V4 (OLED 0.96" I2C)
 *  Click on the following links to learn more. 
 *  YouTube Video: https://youtu.be/rRUUYXzJ4ZQ
 *  Related Blog : https://easyelectronicsproject.com/esp32-projects/
 *  by Tech StudyCell
 *  Download the libraries
 *  https://github.com/blynkkk/blynk-library/releases/download/v0.6.1/Blynk_Release_v0.6.1.zip
 *  https://github.com/adafruit/DHT-sensor-library
 *  https://github.com/adafruit/Adafruit_SSD1306
 **********************************************************************************/

#define BLYNK_PRINT Serial            
#include <BlynkSimpleEsp8266.h> 
#include <DHT.h>                
#include <Adafruit_SSD1306.h>  

void checkPhysicalButton();

int toggleState_1 = 0;
int pushButton1State = LOW;

int toggleState_2 = 0;
int pushButton2State = LOW;

float temperature1 = 0;
float humidity1   = 0;
int   ldrVal;
int   switchMode = 0;

//Set values for Auto Control Mode
const float maxTemp = 30.5;
const float minTemp = 24.8;

const int maxLight = 1000;
const int minLight = 200;

#define AUTH "AUTH TOKEN"                 // You should get Auth Token in the Blynk App.  
#define WIFI_SSID "WIFI NAME"             //Enter Wifi Name
#define WIFI_PASS "WIFI PASSWORD"         //Enter wifi Password


#define PUSH_BUTTON_CMODE  15 //D8
#define LDR_PIN            A0 //A0
#define DHTPIN             10 //SD3  pin connected with DHT

#define RELAY_PIN_1      14   //D5
#define RELAY_PIN_2      12   //D6

#define PUSH_BUTTON_1    16   //D0
#define PUSH_BUTTON_2    13   //D7

#define VPIN_BUTTON_1    V1 
#define VPIN_BUTTON_2    V2
#define VPIN_BUTTON_C    V3

#define VPIN_HUMIDITY    V5
#define VPIN_TEMPERATURE V6

// Uncomment whatever type you're using!
#define DHTTYPE DHT11     // DHT 11
//#define DHTTYPE DHT22   // DHT 22, AM2302, AM2321
//#define DHTTYPE DHT21   // DHT 21, AM2301

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 32 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET     -1 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

DHT dht(DHTPIN, DHTTYPE);
BlynkTimer timer;

void changeMode(){      
  delay(200);
  if (switchMode == 0){
    switchMode = 1;
  }
  else if (switchMode == 1) {
    switchMode = 0;
  }
  display.clearDisplay();
  display.setCursor(5,2);
  display.print("Set Mode: ");
  display.println();
  display.drawLine(0,18, display.width()-1,18, WHITE);
  display.setCursor(15,24);
  display.print(modeDecode(switchMode));     
  display.display();
  delay(500);
  Blynk.virtualWrite(VPIN_BUTTON_C, switchMode);
  //display.clearDisplay();
}

void relayOnOff(int relay){

    switch(relay){
      case 1: 
             if(toggleState_1 == 0){
              digitalWrite(RELAY_PIN_1, HIGH); // turn on relay 1
              toggleState_1 = 1;
              }
             else{
              digitalWrite(RELAY_PIN_1, LOW); // turn off relay 1
              toggleState_1 = 0;
              }
             delay(100);
      break;
      case 2: 
             if(toggleState_2 == 0){
              digitalWrite(RELAY_PIN_2, HIGH); // turn on relay 2
              toggleState_2 = 1;
              }
             else{
              digitalWrite(RELAY_PIN_2, LOW); // turn off relay 2
              toggleState_2 = 0;
              }
             delay(100);
      break;
      default : break;      
      }
  
}
String modeDecode(int count){
  if (count == 0){
    return " Manual Mode ";
  }
  else if (count == 1){
    return " Auto Mode ";
  }
}

void displayData(){
  display.clearDisplay();
  display.setTextSize(1);
  display.setCursor(8,2);
  display.print(temperature1);
  display.print(" ");
  display.print("C    ");
  display.print(humidity1); // display humidity
  display.print(" %");
  
  display.drawLine(0,18, display.width()-1,18, WHITE);
   
  display.setCursor(15,24);
  display.print(modeDecode(switchMode));   
  display.display();

  Serial.print(F("Temperature: "));
  Serial.print(temperature1);
  Serial.print("   ");
  Serial.print(F("humidity: "));
  Serial.print(humidity1);
  Serial.print("   ");
  Serial.println(ldrVal); 
  Serial.println("");
}

void readSensor(){
    
  ldrVal = analogRead(LDR_PIN);
  
  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;
  }  
}

void sendSensor()
{
  readSensor();
  // You can send any value at any time.
  // Please don't send more that 10 values per second.
  Blynk.virtualWrite(VPIN_HUMIDITY, humidity1);
  Blynk.virtualWrite(VPIN_TEMPERATURE, temperature1);
}

BLYNK_CONNECTED() {

  // Request the latest state from the server

  Blynk.syncVirtual(VPIN_BUTTON_1);
  Blynk.syncVirtual(VPIN_BUTTON_2);
  Blynk.syncVirtual(VPIN_BUTTON_C);
}

// When App button is pushed - switch the state

BLYNK_WRITE(VPIN_BUTTON_1) {
  toggleState_1 = param.asInt();
  digitalWrite(RELAY_PIN_1, toggleState_1);
}

BLYNK_WRITE(VPIN_BUTTON_2) {
  toggleState_2 = param.asInt();
  digitalWrite(RELAY_PIN_2, toggleState_2);
}

BLYNK_WRITE(VPIN_BUTTON_C) {
  switchMode = param.asInt();
}

void checkPhysicalButton()
{
  if (digitalRead(PUSH_BUTTON_1) == HIGH) {
      relayOnOff(1);
      // Update Button Widget
      Blynk.virtualWrite(VPIN_BUTTON_1, toggleState_1);
    }
  if (digitalRead(PUSH_BUTTON_2) == HIGH) {
      relayOnOff(2);
      // Update Button Widget
      Blynk.virtualWrite(VPIN_BUTTON_2, toggleState_2);
    }
}

void setup()
{
  Serial.begin(9600);
  
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    for(;;);
  }
  delay(1000);  
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.clearDisplay();

  pinMode(RELAY_PIN_1, OUTPUT);
  pinMode(PUSH_BUTTON_1, INPUT);
  digitalWrite(RELAY_PIN_1, toggleState_1);

  pinMode(RELAY_PIN_2, OUTPUT);
  pinMode(PUSH_BUTTON_2, INPUT);
  digitalWrite(RELAY_PIN_2, toggleState_2);

  Blynk.begin(AUTH, WIFI_SSID, WIFI_PASS);  
  // Setup a function to be called every 500 ms
  timer.setInterval(500L, checkPhysicalButton);
  
  dht.begin();
  // Setup a function to be called every second
  timer.setInterval(1000L, sendSensor);
  // Setup a function to be called every 2 second
  timer.setInterval(2000L, displayData);
}

void loop()
{
  if (digitalRead(PUSH_BUTTON_CMODE) == HIGH){
    changeMode();
  }   
  else{    
    if(switchMode == 1){ //if Auto Mode
      //DHT11 control Relay 1
      if(temperature1 > maxTemp){
        if(toggleState_1 == 0){
          digitalWrite(RELAY_PIN_1, HIGH); // turn ON relay 1
          toggleState_1 = 1;
          // Update Button Widget
          Blynk.virtualWrite(VPIN_BUTTON_1, toggleState_1);
        }
      }
      else if (temperature1 < minTemp){
        if(toggleState_1 == 1){
           digitalWrite(RELAY_PIN_1, LOW); // turn OFF relay 1
           toggleState_1 = 0;
           // Update Button Widget
           Blynk.virtualWrite(VPIN_BUTTON_1, toggleState_1);
          }
      }
      //LDR control Relay 2
      if( ldrVal < minLight){
        if(toggleState_2 == 0){
          digitalWrite(RELAY_PIN_2, HIGH); // turn ON relay 2
          toggleState_2 = 1;
          // Update Button Widget
          Blynk.virtualWrite(VPIN_BUTTON_2, toggleState_2);
        }
      }
      else if (ldrVal > maxLight){
        if(toggleState_2 == 1){
           digitalWrite(RELAY_PIN_2, LOW); // turn OFF relay 2
           toggleState_2 = 0;
           // Update Button Widget
           Blynk.virtualWrite(VPIN_BUTTON_2, toggleState_2);
          }
      } 
    }
    timer.run();
    Blynk.run();
  }
}

Credits

Subhajit

Subhajit

47 projects • 126 followers
I have studied Electrical Engineering. I do love to make different DIY electronics projects & share it on my YouTube channel Tech StudyCell.

Comments