/**********************************************************************************
* TITLE: Blynk + Manual Button + IR + DHT11 control 4 Relays using ESP32 (Real time feedback + no WiFi control)
* Click on the following links to learn more.
* YouTube Video: https://youtu.be/VNeT5QgH-IM
* Related Blog : https://iotcircuithub.com/esp32-projects/
* by Tech StudyCell
* Preferences--> Aditional boards Manager URLs :
* https://dl.espressif.com/dl/package_esp32_index.json, http://arduino.esp8266.com/stable/package_esp8266com_index.json
*
* Download Board ESP32 : https://github.com/espressif/arduino-esp32
*
* Download the libraries
* Blynk Library (1.0.1): https://github.com/blynkkk/blynk-library
* AceButton Library (1.9.2): https://github.com/bxparks/AceButton
* IRremote Library (3.6.1): https://github.com/Arduino-IRremote/Arduino-IRremote
* DHT Library (1.4.3): https://github.com/adafruit/DHT-sensor-library
**********************************************************************************/
/* Fill-in your Template ID (only if using Blynk.Cloud) */
#define BLYNK_TEMPLATE_ID "TMPL6z6GCSvdn"
#define BLYNK_TEMPLATE_NAME "ESP32 Automatic Lamp Fan"
#define BLYNK_AUTH_TOKEN "GDNw3FKdbwVOmOai9mr5U6zhut1ckdT7"
// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "Wokwi-GUEST";
char pass[] = "";
bool fetch_blynk_state = true; //true or false
//Update the HEX code of IR Remote buttons 0x<HEX CODE>
#define IR_Button_1 0x80BF49B6
#define IR_Button_2 0x80BFC936
#define IR_Button_3 0x80BF33CC
#define IR_Button_4 0x80BF718E
#define IR_All_Off 0x80BF3BC4
//#define BLYNK_PRINT Serial
#include <WiFi.h>
#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>
#include <DHT.h>
#include <IRremote.h>
#include <AceButton.h>
using namespace ace_button;
#define DHTPIN 16 //D16 pin connected with DHT
#define IR_RECV_PIN 35 // D35 (IR receiver pin)
// Uncomment whatever type you're using!
#define DHTTYPE DHT22 // DHT 11
//#define DHTTYPE DHT22 // DHT 22, AM2302, AM2321
//#define DHTTYPE DHT21 // DHT 21, AM2301
IRrecv irrecv(IR_RECV_PIN);
decode_results results;
// 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
//Change the virtual pins according the rooms
#define VPIN_BUTTON_1 V1
#define VPIN_BUTTON_2 V2
#define VPIN_BUTTON_3 V3
#define VPIN_BUTTON_4 V4
#define VPIN_BUTTON_C V5
#define VPIN_TEMPERATURE V6
#define VPIN_HUMIDITY V7
// 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
int wifiFlag = 0;
float temperature1 = 0;
float humidity1 = 0;
char auth[] = BLYNK_AUTH_TOKEN;
ButtonConfig config1;
AceButton button1(&config1);
ButtonConfig config2;
AceButton button2(&config2);
ButtonConfig config3;
AceButton button3(&config3);
ButtonConfig config4;
AceButton button4(&config4);
void handleEvent1(AceButton*, uint8_t, uint8_t);
void handleEvent2(AceButton*, uint8_t, uint8_t);
void handleEvent3(AceButton*, uint8_t, uint8_t);
void handleEvent4(AceButton*, uint8_t, uint8_t);
BlynkTimer timer;
DHT dht(DHTPIN, DHTTYPE);
// When App button is pushed - switch the state
BLYNK_WRITE(VPIN_BUTTON_1) {
toggleState_1 = param.asInt();
digitalWrite(RelayPin1, !toggleState_1);
}
BLYNK_WRITE(VPIN_BUTTON_2) {
toggleState_2 = param.asInt();
digitalWrite(RelayPin2, !toggleState_2);
}
BLYNK_WRITE(VPIN_BUTTON_3) {
toggleState_3 = param.asInt();
digitalWrite(RelayPin3, !toggleState_3);
}
BLYNK_WRITE(VPIN_BUTTON_4) {
toggleState_4 = param.asInt();
digitalWrite(RelayPin4, !toggleState_4);
}
BLYNK_WRITE(VPIN_BUTTON_C) {
all_SwitchOff();
}
void all_SwitchOff(){
toggleState_1 = 0; digitalWrite(RelayPin1, HIGH); Blynk.virtualWrite(VPIN_BUTTON_1, toggleState_1); delay(100);
toggleState_2 = 0; digitalWrite(RelayPin2, HIGH); Blynk.virtualWrite(VPIN_BUTTON_2, toggleState_2); delay(100);
toggleState_3 = 0; digitalWrite(RelayPin3, HIGH); Blynk.virtualWrite(VPIN_BUTTON_3, toggleState_3); delay(100);
toggleState_4 = 0; digitalWrite(RelayPin4, HIGH); Blynk.virtualWrite(VPIN_BUTTON_4, toggleState_4); delay(100);
Blynk.virtualWrite(VPIN_HUMIDITY, humidity1);
Blynk.virtualWrite(VPIN_TEMPERATURE, temperature1);
}
void checkBlynkStatus() { // called every 3 seconds by SimpleTimer
bool isconnected = Blynk.connected();
if (isconnected == false) {
wifiFlag = 1;
Serial.println("Blynk Not Connected");
digitalWrite(wifiLed, LOW);
}
if (isconnected == true) {
wifiFlag = 0;
if (!fetch_blynk_state){
Blynk.virtualWrite(VPIN_BUTTON_1, toggleState_1);
Blynk.virtualWrite(VPIN_BUTTON_2, toggleState_2);
Blynk.virtualWrite(VPIN_BUTTON_3, toggleState_3);
Blynk.virtualWrite(VPIN_BUTTON_4, toggleState_4);
}
digitalWrite(wifiLed, HIGH);
//Serial.println("Blynk Connected");
}
}
BLYNK_CONNECTED() {
// Request the latest state from the server
if (fetch_blynk_state){
Blynk.syncVirtual(VPIN_BUTTON_1);
Blynk.syncVirtual(VPIN_BUTTON_2);
Blynk.syncVirtual(VPIN_BUTTON_3);
Blynk.syncVirtual(VPIN_BUTTON_4);
}
Blynk.syncVirtual(VPIN_TEMPERATURE);
Blynk.syncVirtual(VPIN_HUMIDITY);
}
void readSensor(){
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.println(temperature1);
// Serial.println(humidity1);
}
}
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);
}
void ir_remote(){
if (irrecv.decode(&results)) {
switch(results.value){
case IR_Button_1:
digitalWrite(RelayPin1, toggleState_1);
toggleState_1 = !toggleState_1;
Blynk.virtualWrite(VPIN_BUTTON_1, toggleState_1);
delay(100);
break;
case IR_Button_2:
digitalWrite(RelayPin2, toggleState_2);
toggleState_2 = !toggleState_2;
Blynk.virtualWrite(VPIN_BUTTON_2, toggleState_2);
delay(100);
break;
case IR_Button_3:
digitalWrite(RelayPin3, toggleState_3);
toggleState_3 = !toggleState_3;
Blynk.virtualWrite(VPIN_BUTTON_3, toggleState_3);
delay(100);
break;
case IR_Button_4:
digitalWrite(RelayPin4, toggleState_4);
toggleState_4 = !toggleState_4;
Blynk.virtualWrite(VPIN_BUTTON_4, toggleState_4);
delay(100);
break;
case IR_All_Off:
all_SwitchOff();
break;
default : break;
}
//Serial.println(results.value, HEX);
irrecv.resume();
}
}
void setup()
{
Serial.begin(9600);
pinMode(RelayPin1, OUTPUT);
pinMode(RelayPin2, OUTPUT);
pinMode(RelayPin3, OUTPUT);
pinMode(RelayPin4, OUTPUT);
pinMode(wifiLed, OUTPUT);
pinMode(SwitchPin1, INPUT_PULLUP);
pinMode(SwitchPin2, INPUT_PULLUP);
pinMode(SwitchPin3, INPUT_PULLUP);
pinMode(SwitchPin4, INPUT_PULLUP);
//During Starting all Relays should TURN OFF
digitalWrite(RelayPin1, !toggleState_1);
digitalWrite(RelayPin2, !toggleState_2);
digitalWrite(RelayPin3, !toggleState_3);
digitalWrite(RelayPin4, !toggleState_4);
irrecv.enableIRIn(); // Enabling IR sensor
dht.begin(); // Enabling DHT sensor
digitalWrite(wifiLed, LOW);
config1.setEventHandler(button1Handler);
config2.setEventHandler(button2Handler);
config3.setEventHandler(button3Handler);
config4.setEventHandler(button4Handler);
button1.init(SwitchPin1);
button2.init(SwitchPin2);
button3.init(SwitchPin3);
button4.init(SwitchPin4);
//Blynk.begin(auth, ssid, pass);
WiFi.begin(ssid, pass);
timer.setInterval(2000L, checkBlynkStatus); // check if Blynk server is connected every 2 seconds
timer.setInterval(1000L, sendSensor); // Sending Sensor Data to Blynk Cloud every 1 second
Blynk.config(auth);
delay(1000);
if (!fetch_blynk_state){
Blynk.virtualWrite(VPIN_BUTTON_1, toggleState_1);
Blynk.virtualWrite(VPIN_BUTTON_2, toggleState_2);
Blynk.virtualWrite(VPIN_BUTTON_3, toggleState_3);
Blynk.virtualWrite(VPIN_BUTTON_4, toggleState_4);
}
}
void loop()
{
ir_remote(); //IR remote Control
Blynk.run();
timer.run(); // Initiates SimpleTimer
button1.check();
button2.check();
button3.check();
button4.check();
}
void button1Handler(AceButton* button, uint8_t eventType, uint8_t buttonState) {
Serial.println("EVENT1");
switch (eventType) {
case AceButton::kEventReleased:
digitalWrite(RelayPin1, toggleState_1);
toggleState_1 = !toggleState_1;
Blynk.virtualWrite(VPIN_BUTTON_1, toggleState_1);
break;
}
}
void button2Handler(AceButton* button, uint8_t eventType, uint8_t buttonState) {
Serial.println("EVENT2");
switch (eventType) {
case AceButton::kEventReleased:
digitalWrite(RelayPin2, toggleState_2);
toggleState_2 = !toggleState_2;
Blynk.virtualWrite(VPIN_BUTTON_2, toggleState_2);
break;
}
}
void button3Handler(AceButton* button, uint8_t eventType, uint8_t buttonState) {
Serial.println("EVENT3");
switch (eventType) {
case AceButton::kEventReleased:
digitalWrite(RelayPin3, toggleState_3);
toggleState_3 = !toggleState_3;
Blynk.virtualWrite(VPIN_BUTTON_3, toggleState_3);
break;
}
}
void button4Handler(AceButton* button, uint8_t eventType, uint8_t buttonState) {
Serial.println("EVENT4");
switch (eventType) {
case AceButton::kEventReleased:
digitalWrite(RelayPin4, toggleState_4);
toggleState_4 = !toggleState_4;
Blynk.virtualWrite(VPIN_BUTTON_4, toggleState_4);
break;
}
}