ESP32IoT Projects
Trending

IoT Temperature & Humidity Monitoring & Control System using ESP32 & Blynk 2.0

Temperature & Humidity Controller System with ESP32 & Blynk IoT

In this project, we will make a temperature and Humidity monitoring and control system using ESP32 WiFi module and view data on the blynk 2.0 IoT App.


Overview: IoT Temperature & Humidity Monitoring & Control System

There are many potential applications for an IoT-based temperature and humidity control system. Some examples include:

  • Controlling the temperature and humidity in a greenhouse.
  • Maintaining optimal conditions in a mushroom grow room.
  • Regulating temperature and humidity in a wine cellar.
  • Creating the perfect conditions for aging cheese.
  • Keeping a server room at the optimal temperature and humidity for equipment performance.
  • Maintaining the ideal conditions for drying and storing foods.
  • Optimizing the conditions for storing and displaying museum artifacts.
  • Regulating the temperature and humidity in a laboratory, incubator, commercial buildings, etc.

By the end of this tutorial, I will show you how this small device helped me to grow mushrooms at extremely low temperatures.


Features of IoT Temperature & Humidity Controller

Some of the features of this project include:

Temperature and Humidity control

The program allows the user to set the target temperature and humidity levels. Then the system will turn ON and OFF the heating and humidifying devices as needed to try to maintain those levels.

Mobile dashboard setup for IoT Temperature and Humidity Controller

To measure the temperature and Humidity of the surroundings I am using a cheap and easily available DHT11 sensor. You can also use the DHT22 sensor.

Mode feature

The program has a mode feature that the user can toggle in the Blynk app to switch between automatic and manual modes.

When the system is in auto mode, it continuously reads the current temperature and humidity levels from a sensor and compares them to the target temperature and humidity levels. Then the system will turn ON and OFF the heating and humidifying devices as needed to maintain those target levels.

Auto mode All ON on Temperature & Humidity Controller

When the system is in manual mode. The heating and humidifying devices are controlled manually by the user rather than being automatically turned ON and OFF to maintain a target temperature and humidity level.

Manual Mode Heater ON
IoT Temperature & Humidity Monitoring & Control System using ESP32 & Blynk 2.0

OLED display

The 0.96-inch OLED display will display the Blynk IoT Connection status, current temperature, and Humidity, Operating Mode, Temperature set value, and humidity set value.

IoT Temperature & Humidity Monitoring & Control System using ESP32

Manual control

The program has three buttons connected to the ESP32 that allow the user to manually control the devices. It comes in handy when you don’t have a mobile phone or your system is not connected to the internet. Because this device works even in offline mode. The first Green button allows the user to switch between modes. The other two red and blue buttons allow the user to control the heating and humidifying devices.

IoT Temperature & Humidity Controller System using ESP32

WiFi & Cloud Connectivity

The program uses the WiFi library to connect to a WiFi network and the Blynk library to connect to the Blynk cloud service and communicate with the Blynk app. The blynk app will show you DHT11 sensor data current temperature and humidity. Using the blynk IoT app we can also set temperature and Humidity threshold values. Additionally, you can switch between modes as well as control devices manually when needed.

Humidifier ON on Manual Mode
IoT Temperature & Humidity Monitoring & Control System using ESP32 & Blynk 2.0

Data Storage on EEPROM

The program uses the Preferences library to store data (e.g. ON or OFF state of the heating and humidifying device, auto or manual mode of the system, target temperature & humidity). This allows the device to remember its previous state and settings even if it is powered off.

So, without further delay, let’s get started with the hardware you’ll need for this project:


Components Required

Following is the list of the hardware components that are required for making this project. You can easily purchase them from the links provided below.

S.NCOMPONENTS NAMEQUANTITYPURCHASE LINKS
1ESP32 WiFi Module1 Amazon | AliExpress
2DHT11 Temperature & Humidity Sensor1 Amazon | AliExpress
30.96" I2C OLED Display1 Amazon | AliExpress
45V 2-Channel Relay1 Amazon | AliExpress
5220V 100W Halogen Bulb1 Amazon | AliExpress
6Mist Maker (Humidifier)1 Amazon | AliExpress
7Jumper Cables10 Amazon | AliExpress
7Zero PCB board1 Amazon | AliExpress

Circuit Diagram & Connection

Now that we have all of the materials that we need, let’s start by setting up the hardware.

Circuit Diagram of IoT Temperature & Humidity Monitoring & Control System using ESP32 & Blynk

First, connect the OLED display to the ESP32 using I2C (SCL & SDA) pins to D22 and D21 pins. Next, connect the DHT11 sensor to the ESP32 D23 pin. Then, connect the two-channel relay to the ESP32 D18 and D19 pins. While VCC is connected to the Vin pin for a 5V power supply. Interface buttons to D25, D26, and D27 pins respectively. Connect all GND pins to GND and VCC pins to the 3.3V pin of the ESP32 WiFi Module.

Circuit Connection with Relay

Now connect the Heating component (Halogen Bulb in my case) and the Mist maker (humidifier) to the relay module and power supply. Here you are dealing with AC current so be careful while connecting wires.

So we have a complete hardware setup for IoT Temperature & Humidity Monitoring & Control System using ESP32.


Project PCB Gerber File & PCB Ordering Online

If you don’t want to assemble the circuit on a zero PCB and you want PCB for the project, then here is the PCB for you. The PCB Board for this project looks something like below.

PCB board for IoT Temperature & Humidity Monitoring & Control System using ESP32 & Blynk

The Gerber File for the PCB is given below. You can simply download the Gerber File and order the PCB from PCBWay.com.

Now you can visit the PCBWay official website by clicking here: PCBWay.com. So you will be directed to the PCBWay website. Currently, PCBWay is celebrating their 10th Anniversary with amazing offers and special events! If you’re into electronics and PCB projects like me, you definitely don’t want to miss out on this.

PCBWAY 10th Anniversary

PCBWay has been a trusted partner for PCB prototyping, manufacturing, and assembly for a decade now. To celebrate this milestone, they have a bunch of exciting deals and giveaways lined up. You can visit their special anniversary page at www.pcbway.com/activity/anniversary10th.html to participate.

I’ve been using PCBWay for my own projects, and their quality and customer service have always been top-notch. Whether you’re a hobbyist or a professional, PCBWay’s services are perfect for bringing your ideas to life.

And during this anniversary celebration, they are offering discounts, free trials, and even a chance to win some fantastic prizes!
So, what are you waiting for? Head over to PCBWay.com and join in the celebration. Let’s make some great projects together. Thanks again to PCBWay for sponsoring this project.

  • PCB Board for Temperature and Humidity Controlling System
  • PCB board for IoT Temperature & Humidity Monitoring & Control System using ESP32 & Blynk
  • Front PCB of IoT Temperature & Humidity Monitoring & Control System using ESP32

Now, you can assemble the components on the PCB Board.


Blynk 2.0 Web Dashboard Setup

Now, let’s set up the IoT part of this project. First, we’ll set up the Blynk dashboard. Sign up using your Blynk email and password, and then create a new template. Assign a name, hardware, and connection type to the template.

New Project on Blynk IoT Dashboard

From the web dashboard, create eight widgets:

  • 1 Label widget
  • 2 Gauge widgets
  • 2 Slider widgets and
  • 3 Button widgets
Blynk Web Dashboard setup

You can resize, drag, and drop the widgets to your desired location.

Configure Widgets with Datastream

For the Label widget, choose the virtual pin V0 and set the data type to string. This will be used to display custom text messages.

Label Widget Settings

For the current temperature display in the Gauge, select the virtual pin V2 and set the data type to double. Set the units to degree Celsius and the maximum value to 50.

Current Temperature Widget Settings

Similarly, for the current humidity, select the virtual pin V3 and set the data type to double. Set the units to percentage and the maximum value to 100.

Current Humidity Widget Settings

For the set temperature slider, assign the virtual pin V4 and set the data type to integer. This slider is used to set the temperature threshold value.

Set Temperature Widget Settings

Similarly, for the set humidity slider widget, assign the virtual pin V5, set the data type to an integer, and set the maximum value to 100%. It is used to set the humidity threshold value.

Set humidity Widget Settings

Now, configure the button for switching modes. Name the widget “Auto Mode” and assign the virtual pin V1. Set the data type to integer. If this button is in the “off” state, the device will be set to manual mode.

Auto mode Widget Settings

To turn the heater ON and OFF, assign the virtual pin V6 and set the data type to integer.

Heater Widget Settings

Finally, to control the humidifier, assign the virtual pin V7 and set the data type to integer. Click “save” to save the entire setup.

Humidifier Widget Settings

In addition to the web dashboard, you can also set up your mobile app dashboard. We will set up the Blynk Mobile dashboard after adding the device to the newly created template and uploading the program code.


Adding New Device to Blynk Dashboard

To add a new device to your Blynk dashboard, click on the search icon and then select “Add New Device.” From the options that appear, choose “From Template” and select the template you want to use. Give your device a name and click “Create.” A new device will be added to your dashboard.

Add a new device

You can find the code header file. You will need this in the program code. This will include the template ID, device name, and authentication token.


Source Code/Program

This is the program code for the IoT Temperature and Humidity Monitoring and control system with ESP32 and Blynk 2.0. This code is written in Arduino IDE. We need to install the following library first.

/* Fill-in your Template ID (only if using Blynk.Cloud) */
#define BLYNK_TEMPLATE_ID "xxxx-xxxx-xxxx"
#define BLYNK_DEVICE_NAME "xxxx-xxxx-xxxx"
#define BLYNK_AUTH_TOKEN "xxxx-xxxx-xxxx"

// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "xxxx-xxxx-xxxx";
char pass[] = "xxxx-xxxx-xxxx";


#include <WiFi.h>
#include <BlynkSimpleEsp32.h>
#include <DHT.h>
#include <Preferences.h>
#include <AceButton.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

using namespace ace_button;
Preferences pref;

#define DHTPIN            23 //D23  pin connected with DHT
// 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 64 // OLED display height, in pixels
#define OLED_RESET     -1 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

// Setpoint and setHumi values (in degrees Celsius)
float setTemp = 0;
float setHumi = 0;
float currentTemp = 0;
float currentHumi = 0;



// define the GPIO connected with Relays and Buttons
#define RelayPin1 18  //D18
#define RelayPin2 19  //D19

#define ButtonPin1 25  //D25
#define ButtonPin2 26  //D26 
#define ButtonPin3 27  //D27

#define wifiLed   2   //D2

//Change the virtual pins according the rooms
#define VPIN_Text           V0
#define VPIN_Mode           V1
#define VPIN_currentTemp    V2
#define VPIN_currentHumi    V3
#define VPIN_setTemp        V4
#define VPIN_setHumi        V5
#define VPIN_Heater         V6
#define VPIN_Humidifier     V7

// Relay and Mode State
bool heaterState = LOW; //Define integer to remember the toggle state for heater
bool humidifierState = LOW; //Define integer to remember the toggle state for Humidifier
bool modeState = LOW; //Define integer to remember the mode

int wifiFlag = 0;


char auth[] = BLYNK_AUTH_TOKEN;

ButtonConfig config1;
AceButton button1(&config1);
ButtonConfig config2;
AceButton button2(&config2);
ButtonConfig config3;
AceButton button3(&config3);

void handleEvent1(AceButton*, uint8_t, uint8_t);
void handleEvent2(AceButton*, uint8_t, uint8_t);
void handleEvent3(AceButton*, uint8_t, uint8_t);


BlynkTimer timer;
DHT dht(DHTPIN, DHTTYPE);

// When App button is pushed - switch the state

BLYNK_WRITE(VPIN_Heater) {
  heaterState = param.asInt();
  digitalWrite(RelayPin1, !heaterState);
  pref.putBool("Heater", heaterState);
}

BLYNK_WRITE(VPIN_Humidifier) {
  humidifierState = param.asInt();
  digitalWrite(RelayPin2, !humidifierState);
  pref.putBool("Humidifier", humidifierState);
}

BLYNK_WRITE(VPIN_Mode) {
  modeState = param.asInt();
  pref.putBool("Mode", modeState);
}

BLYNK_WRITE(VPIN_setTemp) {
  setTemp = param.asFloat();
  pref.putBool("setemp", setTemp);
}

BLYNK_WRITE(VPIN_setHumi) {
  setHumi = param.asFloat();
  pref.putBool("Humidity", setHumi);
}

void checkBlynkStatus() { // called every 2 seconds by SimpleTimer

  bool isconnected = Blynk.connected();
  if (isconnected == false) {
    wifiFlag = 1;
    Serial.println("Blynk Not Connected");
    display.setTextSize(1);
    display.setTextColor(SSD1306_WHITE);
    display.setCursor(0, 2);
    digitalWrite(wifiLed, LOW);
  }
  if (isconnected == true) {
    wifiFlag = 0;
    display.setTextSize(1);
    display.setTextColor(SSD1306_WHITE);
    display.setCursor(0, 2);
    display.println(" Blynk IoT Connected ");
    digitalWrite(wifiLed, HIGH);
    Blynk.virtualWrite(VPIN_Text, "IoT Temperature & Humidity Controller");
  }
  display.display();
  delay(1000);
}

BLYNK_CONNECTED() {
  // update the latest state to the server
  Blynk.virtualWrite(VPIN_Text, "IoT Temperature & Humidity Controller");
  Blynk.virtualWrite(VPIN_Mode, modeState);
  Blynk.syncVirtual(VPIN_currentTemp);
  Blynk.syncVirtual(VPIN_currentHumi);
  Blynk.syncVirtual(VPIN_setTemp);
  Blynk.syncVirtual(VPIN_setHumi);
  Blynk.virtualWrite(VPIN_Heater, heaterState);
  Blynk.virtualWrite(VPIN_Humidifier, humidifierState);

}

void setup()
{
  Serial.begin(115200);
  //Open namespace in read-write mode
  pref.begin("Relay_State", false);

  pinMode(RelayPin1, OUTPUT);
  pinMode(RelayPin2, OUTPUT);
  pinMode(wifiLed, OUTPUT);

  pinMode(ButtonPin1, INPUT_PULLUP);
  pinMode(ButtonPin2, INPUT_PULLUP);
  pinMode(ButtonPin3, INPUT_PULLUP);

  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
    Serial.println(F("SSD1306 allocation failed"));
    for (;;); // Don't proceed, loop forever
  }
  display.clearDisplay();
  display.setTextColor(SSD1306_WHITE);
  display.display();

  //During Starting all Relays should TURN OFF
  digitalWrite(RelayPin1, !heaterState);
  digitalWrite(RelayPin2, !humidifierState);

  dht.begin();    // Enabling DHT sensor
  digitalWrite(wifiLed, LOW);

  config1.setEventHandler(button1Handler);
  config2.setEventHandler(button2Handler);
  config3.setEventHandler(button3Handler);

  button1.init(ButtonPin1);
  button2.init(ButtonPin2);
  button3.init(ButtonPin3);

  //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);

  getRelayState(); // Get the last state of Relays and Set values of Temp & Humidity

  Blynk.virtualWrite(VPIN_Heater, heaterState);
  Blynk.virtualWrite(VPIN_Humidifier, humidifierState);
  Blynk.virtualWrite(VPIN_setTemp, setTemp);
  Blynk.virtualWrite(VPIN_setHumi, setHumi);
}


void readSensor() {

  currentTemp = dht.readTemperature();
  currentHumi = dht.readHumidity();
  if (isnan(currentHumi) || isnan(currentTemp)) {
    Serial.println("Failed to read from DHT sensor!");
    return;
  }
}

void sendSensor()
{
  readSensor();
  // You can send any value at any time.
  // Please don't send more that 10 values per second.
  Blynk.virtualWrite(VPIN_Text, "IoT Temperature & Humidity Controller");
  Blynk.virtualWrite(VPIN_currentTemp, currentTemp);
  Blynk.virtualWrite(VPIN_currentHumi, currentHumi);
}

void getRelayState()
{
  //Serial.println("reading data from NVS");
  modeState = pref.getBool("Mode", 0);
  Blynk.virtualWrite(VPIN_Mode, modeState);
  delay(200);
  heaterState = pref.getBool("Heater", 0);
  digitalWrite(RelayPin1, !heaterState);
  Blynk.virtualWrite(VPIN_Heater, heaterState);
  delay(200);
  humidifierState = pref.getBool("Humidifier", 0);
  digitalWrite(RelayPin2, !humidifierState);
  Blynk.virtualWrite(VPIN_Humidifier, humidifierState);
  delay(200);
  setTemp = pref.getBool("setemp", 0);
  Blynk.virtualWrite(VPIN_setTemp, setTemp);
  delay(200);
  setHumi = pref.getBool("Humidity", 0);
  Blynk.virtualWrite(VPIN_setHumi, setHumi);
  delay(200);
}


void DisplayData()  {
  display.clearDisplay();
  display.setTextSize(2);
  display.setCursor(0, 7);
  display.println("----------");
  display.setCursor(2, 20);
  display.print(int(currentTemp));
  display.print((char)247);
  display.println("C");
  display.setCursor(60, 20);
  display.print(": ");
  display.print(int(currentHumi));
  display.println("%");
  display.setCursor(0, 34);
  display.println("----------");

  display.setTextSize(1);
  display.setCursor(0, 57);
  display.print("sTemp:");
  display.print(int(setTemp));
  display.print((char)247);
  display.println("C");
  display.setTextSize(1);
  display.setCursor(67, 57);
  display.print("sHumi:");
  display.print(int(setHumi));
  display.println("%");


  if (modeState == 1) {
    display.setTextSize(1);
    display.setCursor(20, 45);
    display.print("Automatic Mode");
    if (currentTemp < setTemp) {
      heaterState = 1;
      digitalWrite(RelayPin1, !heaterState);
      pref.putBool("Heater", heaterState);
      Serial.println("Heater ON");
      Blynk.virtualWrite(VPIN_Heater, heaterState);
    } else {
      heaterState = 0;
      digitalWrite(RelayPin1, !heaterState);
      pref.putBool("Heater", heaterState);
      Serial.println("Heater OFF");
      Blynk.virtualWrite(VPIN_Heater, heaterState);
    } if (currentHumi < setHumi) {
      humidifierState = 1;
      digitalWrite(RelayPin2, !humidifierState);
      Serial.println("Humidifier ON");
      pref.putBool("Humidifier", humidifierState);
      Blynk.virtualWrite(VPIN_Humidifier, humidifierState);
    } else {
      humidifierState = 0;
      digitalWrite(RelayPin2, !humidifierState);
      Serial.println("Humidifier OFF");
      pref.putBool("Humidifier", humidifierState);
      Blynk.virtualWrite(VPIN_Humidifier, humidifierState);
    }
  } else {
    display.setTextSize(1);
    display.setCursor(32, 45);
    display.print("Manual Mode");
  }
  display.display();
}


void loop()
{
  Blynk.run();
  timer.run();
  DisplayData();
  button1.check();
  button2.check();
  button3.check();
}

void button1Handler(AceButton* button, uint8_t eventType, uint8_t buttonState) {
  Serial.println("Mode");
  switch (eventType) {
    case AceButton::kEventReleased:
      modeState = !modeState;
      pref.putBool("Mode", modeState);
      Blynk.virtualWrite(VPIN_Mode, modeState);
      break;
  }
}
void button2Handler(AceButton* button, uint8_t eventType, uint8_t buttonState) {
  Serial.println("Heater");
  switch (eventType) {
    case AceButton::kEventReleased:
      digitalWrite(RelayPin1, heaterState);
      heaterState = !heaterState;
      pref.putBool("Heater", heaterState);
      Blynk.virtualWrite(VPIN_Heater, heaterState);
      break;
  }
}
void button3Handler(AceButton* button, uint8_t eventType, uint8_t buttonState) {
  Serial.println("Humidifier");
  switch (eventType) {
    case AceButton::kEventReleased:
      digitalWrite(RelayPin2, humidifierState);
      humidifierState = !humidifierState;
      pref.putBool("VPIN_Humidifier", humidifierState);
      Blynk.virtualWrite(VPIN_Humidifier, humidifierState);
      break;
  }
}

Now you can paste the Template ID, Device Name, and Authentication token to the program code in the following lines.

/* Fill-in your Template ID (only if using Blynk.Cloud) */
#define BLYNK_TEMPLATE_ID "xxxx-xxxx-xxxx"
#define BLYNK_DEVICE_NAME "xxxx-xxxx-xxxx"
#define BLYNK_AUTH_TOKEN "xxxx-xxxx-xxxx"

Update your WiFi SSID and Password from this line of code.

// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "xxxx-xxxx-xxxx";
char pass[] = "xxxx-xxxx-xxxx";

To upload the program code: Select the ESP32 Devkit V1 board and the correct COM port from the Tools menu. Click the “upload” button to upload the code.

Upload code to ESP32 WiFi Module

The code will take some time to compile. After compilation is complete press the boot button on ESP32 for a few seconds. Then the upload process will be started.

Once the code is uploaded, the device is ready for testing. The ESP32 will try to connect to the WiFi network. Once it is connected, it will connect to the Blynk platform using the Blynk authentication token.
At the same time, the 0.96-inch OLED display will show the Blynk IoT connection status, the current temperature in degrees Celsius, the humidity in percentage, the device operating mode, the set temperature, and the set humidity.


Source Code/Program Explanation

Definitely, here is a more detailed explanation of the program code:

Connect to the Blynk platform with WiFi

The program begins by defining several constants and variables:

BLYNK_TEMPLATE_ID: This is the template ID for the project. BLYNK_DEVICE_NAME: This is the name of the device that the program is running on. BLYNK_AUTH_TOKEN: This is the authorization token that the device uses to authenticate with the Blynk server. ssid and pass: These are the WiFi network’s SSID and password.

/* Fill-in your Template ID (only if using Blynk.Cloud) */
#define BLYNK_TEMPLATE_ID "xxxx-xxxx-xxxx"
#define BLYNK_DEVICE_NAME "xxxx-xxxx-xxxx"
#define BLYNK_AUTH_TOKEN "xxxx-xxxx-xxxx"

// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "xxxx-xxxx-xxxx";
char pass[] = "xxxx-xxxx-xxxx";

Including Libraries

The program then includes several libraries:

  • WiFi.h: This library allows the program to connect to a WiFi network.
  • BlynkSimpleEsp32.h: This library allows the program to connect to the Blynk cloud service and communicate with the Blynk app.
  • DHT.h: This library allows the program to read data from a DHT11 temperature and humidity sensor.
  • Preferences.h: This library allows the program to store persistent data (i.e. data that will be retained even if the device is powered off).
  • AceButton.h: This library allows the program to use buttons and define button press events.
  • Wire.h: This library allows the program to communicate with the OLED screen.
  • Adafruit_GFX.h and Adafruit_SSD1306.h: These libraries allow the program to control the OLED screen.
#include <WiFi.h>
#include <BlynkSimpleEsp32.h>
#include <DHT.h>
#include <Preferences.h>
#include <AceButton.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

Constants and Variables

This program code defines several constants and variables related to the OLED screen:

  • SCREEN_WIDTH and SCREEN_HEIGHT: These constants define the width and height of the OLED screen in pixels.
  • OLED_RESET: This constant defines the reset pin for the OLED screen.
  • SCREEN_ADDRESS: This constant defines the I2C address of the OLED screen.
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET     -1 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

The program also defines several constants and variables related to the heating and humidifying system:

  • DHTPIN: This constant defines the pin that the DHT11 sensor is connected to.
  • DHTTYPE: This constant defines the type of DHT sensor being used (e.g. DHT11, DHT22).
  • RelayPin1 and RelayPin2: These constants define the pins that the heating and humidifying devices are connected to.
  • ButtonPin1, ButtonPin2, and ButtonPin3: These constants define the pins that the buttons are connected to.
  • wifiLed: This constant defines the pin that the WiFi status LED is connected to.
  • VPIN_Text, VPIN_Mode, VPIN_currentTemp, VPIN_currentHumi, VPIN_setTemp, VPIN_setHumi, VPIN_Heater, and VPIN_Humidifier: These constants define the virtual pins (i.e. pins that exist within the Blynk app) that are used to communicate with the Blynk app.
#define DHTPIN            23 //D23  pin connected with DHT
// 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 the GPIO connected with Relays and Buttons
#define RelayPin1 18  //D18
#define RelayPin2 19  //D19

#define ButtonPin1 25  //D25
#define ButtonPin2 26  //D26 
#define ButtonPin3 27  //D27

#define wifiLed   2   //D2

//Change the virtual pins according the rooms
#define VPIN_Text           V0
#define VPIN_Mode           V1
#define VPIN_currentTemp    V2
#define VPIN_currentHumi    V3
#define VPIN_setTemp        V4
#define VPIN_setHumi        V5
#define VPIN_Heater         V6
#define VPIN_Humidifier     V7

The program also defines several variables to store the current and target temperature and humidity levels, as well as the current states of the heating, humidifying, and mode.

  • setTemp and setHumi: These variables store the target temperature and humidity levels, respectively.
  • currentTemp and currentHumi: These variables store the current temperature and humidity levels, respectively.
  • heaterState and humidifierState: These variables store the current state of the heating and humidifying devices, respectively (i.e. whether they are on or off).
  • modeState: This variable stores the current mode of the system (i.e. heating, humidifying, or off).
float setTemp = 0;
float setHumi = 0;
float currentTemp = 0;
float currentHumi = 0;
ool heaterState = LOW;
bool humidifierState = LOW;
bool modeState = LOW;

Defining different Objects

The program then defines several objects:

  • pref: This object is an instance of the Preferences library, which allows the program to store persistent data.
  • display: This object is an instance of the Adafruit_SSD1306 class, which allows the program to control the OLED screen.
  • timer: This object is an instance of the BlynkTimer class, which allows the program to schedule tasks to run at specific intervals.
  • dht: This object is an instance of the DHT class, which allows the program to read data from the DHT11 sensor.

Callback Functions for Buttons

The program then defines three callback functions for the buttons:

  • handleEvent1: This function is called when the first button is pressed.
  • handleEvent2: This function is called when the second button is pressed.
  • handleEvent3: This function is called when the third button is pressed.
void handleEvent1(AceButton*, uint8_t, uint8_t);
void handleEvent2(AceButton*, uint8_t, uint8_t);
void handleEvent3(AceButton*, uint8_t, uint8_t);

void button1Handler(AceButton* button, uint8_t eventType, uint8_t buttonState) {
  Serial.println("Mode");
  switch (eventType) {
    case AceButton::kEventReleased:
      modeState = !modeState;
      pref.putBool("Mode", modeState);
      Blynk.virtualWrite(VPIN_Mode, modeState);
      break;
  }
}
void button2Handler(AceButton* button, uint8_t eventType, uint8_t buttonState) {
  Serial.println("Heater");
  switch (eventType) {
    case AceButton::kEventReleased:
      digitalWrite(RelayPin1, heaterState);
      heaterState = !heaterState;
      pref.putBool("Heater", heaterState);
      Blynk.virtualWrite(VPIN_Heater, heaterState);
      break;
  }
}
void button3Handler(AceButton* button, uint8_t eventType, uint8_t buttonState) {
  Serial.println("Humidifier");
  switch (eventType) {
    case AceButton::kEventReleased:
      digitalWrite(RelayPin2, humidifierState);
      humidifierState = !humidifierState;
      pref.putBool("VPIN_Humidifier", humidifierState);
      Blynk.virtualWrite(VPIN_Humidifier, humidifierState);
      break;
  }
}

BLYNK_WRITE Function

This program code then defines several Blynk write event handlers:

  • BLYNK_WRITE(VPIN_Heater): This function is called when the user toggles the heater on or off in the Blynk app. It updates the heater state and writes the new state to the relay pin. It also stores the new state in persistent storage.
  • BLYNK_WRITE(VPIN_Humidifier): This function is called when the user toggles the humidifier on or off in the Blynk app. It updates the humidifier state and writes the new state to the relay pin. It also stores the new state in persistent storage.
  • BLYNK_WRITE(VPIN_Mode): This function is called when the user toggles the mode in the Blynk app. It updates the mode state and stores the new state in persistent storage.
  • BLYNK_WRITE(VPIN_setTemp): This function is called when the user updates the target temperature in the Blynk app. It updates the target temperature and stores the new value in persistent storage.
  • BLYNK_WRITE(VPIN_setHumi): This function is called when the user updates the target humidity in the Blynk app. It updates the target humidity and stores the new value in persistent storage.
BLYNK_WRITE(VPIN_Heater) {
  heaterState = param.asInt();
  digitalWrite(RelayPin1, !heaterState);
  pref.putBool("Heater", heaterState);
}

BLYNK_WRITE(VPIN_Humidifier) {
  humidifierState = param.asInt();
  digitalWrite(RelayPin2, !humidifierState);
  pref.putBool("Humidifier", humidifierState);
}

BLYNK_WRITE(VPIN_Mode) {
  modeState = param.asInt();
  pref.putBool("Mode", modeState);
}

BLYNK_WRITE(VPIN_setTemp) {
  setTemp = param.asFloat();
  pref.putBool("setemp", setTemp);
}

BLYNK_WRITE(VPIN_setHumi) {
  setHumi = param.asFloat();
  pref.putBool("Humidity", setHumi);
}

Void DisplayData Function

The program then defines a function called displayData that displays the current and target temperature and humidity values on the OLED screen.

  • Basically, If the current temperature is less than the target temperature, it turns on the heater by setting the heaterState variable to high and writing the value to the relay pin.
  • Whenever the current temperature is greater than or equal to the target temperature, it turns off the heater by setting the heaterState variable to low and writing the value to the relay pin.
  • When the current humidity is less than the target humidity, it turns on the humidifier by setting the humidifierState variable to high and writing the value to the relay pin.
  • If the current humidity is greater than or equal to the target humidity, it turns off the humidifier by setting the humidifierState variable to low and writing the value to the relay pin.
  • Then finally, Calls the Blynk.virtualWrite function to send the current temperature, humidity, heater state, and humidifier state to the Blynk app.
void DisplayData()  {
  display.clearDisplay();
  display.setTextSize(2);
  display.setCursor(0, 7);
  display.println("----------");
  display.setCursor(2, 20);
  display.print(int(currentTemp));
  display.print((char)247);
  display.println("C");
  display.setCursor(60, 20);
  display.print(": ");
  display.print(int(currentHumi));
  display.println("%");
  display.setCursor(0, 34);
  display.println("----------");

  display.setTextSize(1);
  display.setCursor(0, 57);
  display.print("sTemp:");
  display.print(int(setTemp));
  display.print((char)247);
  display.println("C");
  display.setTextSize(1);
  display.setCursor(67, 57);
  display.print("sHumi:");
  display.print(int(setHumi));
  display.println("%");


  if (modeState == 1) {
    display.setTextSize(1);
    display.setCursor(20, 45);
    display.print("Automatic Mode");
    if (currentTemp < setTemp) {
      heaterState = 1;
      digitalWrite(RelayPin1, !heaterState);
      pref.putBool("Heater", heaterState);
      Serial.println("Heater ON");
      Blynk.virtualWrite(VPIN_Heater, heaterState);
    } else {
      heaterState = 0;
      digitalWrite(RelayPin1, !heaterState);
      pref.putBool("Heater", heaterState);
      Serial.println("Heater OFF");
      Blynk.virtualWrite(VPIN_Heater, heaterState);
    } if (currentHumi < setHumi) {
      humidifierState = 1;
      digitalWrite(RelayPin2, !humidifierState);
      Serial.println("Humidifier ON");
      pref.putBool("Humidifier", humidifierState);
      Blynk.virtualWrite(VPIN_Humidifier, humidifierState);
    } else {
      humidifierState = 0;
      digitalWrite(RelayPin2, !humidifierState);
      Serial.println("Humidifier OFF");
      pref.putBool("Humidifier", humidifierState);
      Blynk.virtualWrite(VPIN_Humidifier, humidifierState);
    }
  } else {
    display.setTextSize(1);
    display.setCursor(32, 45);
    display.print("Manual Mode");
  }
  display.display();
}

Void Setup Function

The program then defines the setup function, which runs once when the device is powered on or reset. The setup function does the following:

  • Initializes the OLED screen.
  • Initializes the buttons and assigns each button a callback function.
  • Initializes the DHT11 sensor.
  • Initializes the relay pins and sets them to low.
  • Initializes the WiFi LED pin and sets it to low.
  • Connects to the WiFi network using the WiFi.begin function.
  • Connects to the Blynk cloud service using the Blynk.begin function and the BLYNK_AUTH_TOKEN.
  • Reads the EEPROM storage to retrieve the previously saved values for the heater and humidifier states, mode state, and target temperature and humidity levels.
  • Sets the relay pins and WiFi LED pin to the values retrieved from EEPROM.
  • Schedules the displayData function to run every 1000 milliseconds (i.e. 1 second) using the timer.setInterval function.
void setup()
{
  Serial.begin(115200);
  //Open namespace in read-write mode
  pref.begin("Relay_State", false);

  pinMode(RelayPin1, OUTPUT);
  pinMode(RelayPin2, OUTPUT);
  pinMode(wifiLed, OUTPUT);

  pinMode(ButtonPin1, INPUT_PULLUP);
  pinMode(ButtonPin2, INPUT_PULLUP);
  pinMode(ButtonPin3, INPUT_PULLUP);

  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
    Serial.println(F("SSD1306 allocation failed"));
    for (;;); // Don't proceed, loop forever
  }
  display.clearDisplay();
  display.setTextColor(SSD1306_WHITE);
  display.display();

  //During Starting all Relays should TURN OFF
  digitalWrite(RelayPin1, !heaterState);
  digitalWrite(RelayPin2, !humidifierState);

  dht.begin();    // Enabling DHT sensor
  digitalWrite(wifiLed, LOW);

  config1.setEventHandler(button1Handler);
  config2.setEventHandler(button2Handler);
  config3.setEventHandler(button3Handler);

  button1.init(ButtonPin1);
  button2.init(ButtonPin2);
  button3.init(ButtonPin3);

  //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);

  getRelayState(); // Get the last state of Relays and Set values of Temp & Humidity

  Blynk.virtualWrite(VPIN_Heater, heaterState);
  Blynk.virtualWrite(VPIN_Humidifier, humidifierState);
  Blynk.virtualWrite(VPIN_setTemp, setTemp);
  Blynk.virtualWrite(VPIN_setHumi, setHumi);
}

Void Loop Function

The program then defines the loop function, which runs continuously after the setup function completes. The loop function does the following:

  • Calls the Blynk.run function to process any incoming Blynk messages.
  • Calls the dht.readTemperature and dht.readHumidity functions to read the current temperature and humidity levels from the DHT11 sensor.
  • Calls the displayData function to display the current and target temperature and humidity values on the OLED screen.
  • Calls the button1.check(), button2.check(), and button3.check() functions to process any button press events. It also calls the Blynk.virtualWrite function to send the current temperature, humidity, heater state, and humidifier state to the Blynk app.
void loop()
{
  Blynk.run();
  timer.run();
  DisplayData();
  button1.check();
  button2.check();
  button3.check();
}

Blynk IoT Mobile App Dashboard

Now let’s set up the blynk IoT dashboard for mobile phones. First, Download the blynk application into your mobile.

  1. New Blynk Mobile App (Android)
  2. New Blynk Mobile App (iOS)

After installing the application login into your account. You will see a new device “IoT Temperature & Humidity Controller” Click on it and start configuring the mobile dashboard. As done on the web dashboard I have used one Label widget, two gauge widgets, two slider widgets, and three button widgets.

IoT Temperature & Humidity Monitoring & Control System Mobile Setup

See this screenshot for the configuration and setup of each widget used in this project.
So, that’s all for the Mobile dashboard setup.

Mobile dashboard setup for IoT Temperature and Humidity Controller

Now you can see the data of your blynk device in your mobile app and in the web dashboard as well.


Testing: IoT Temperature & Humidity Monitoring & Control System with ESP32 & Blynk

Once the code is uploaded, the device is ready for testing. The ESP32 will try to connect to the WiFi network. Once it is connected, it will connect to the Blynk platform using the Blynk authentication token.
At the same time, the 0.96-inch OLED display will show the Blynk IoT connection status, the current temperature in degrees Celsius, the humidity in percentage, the device operating mode, the set temperature, and the set humidity.

IoT Temperature & Humidity Monitoring & Control System using ESP32
IoT Temperature & Humidity Monitoring & Control System using ESP32 & Blynk 2.0

Furthermore, the same data can also be viewed from the Blynk IoT app or the Blynk web dashboard from any location in the world.

IoT Temperature & Humidity Monitoring & Control System using ESP32 & Blynk IoT App
IoT Temperature & Humidity Monitoring & Control System using ESP32 & Blynk 2.0

I have already discussed the useful features of this device. Now let’s see how this system helps to grow mushrooms in low-temperature conditions.

Grow Mushroom with IoT projects Ideas

It is very important to maintain the optimal temperature and humidity levels for growing mushrooms, as these conditions can greatly affect the success of the cultivation process. By using this IoT-based temperature and humidity control system, you can easily monitor and regulate the conditions in your mushroom grow room, ensuring that your mushrooms have the best chance of growing and thriving. With the ability to remotely monitor and control the conditions in your grow room, you can fine-tune the temperature and humidity levels to meet the specific needs of your mushroom variety, even in low-temperature environments.

Mushroom Growing in extremly low temperature

Video tutorial & Guide


Conclusion

Certainly, By following the steps outlined in this tutorial, you can learn how to set up and use an IoT-based temperature and humidity control system to grow your own mushrooms at home. If you have any other questions, you can leave a comment in the comments section below.


Related Articles

6 Comments

  1. Dear Sir/Madam:

    This is an interesting and wonderful IoT Automation Project using ESP32 & Blynk 2.0. I wonder if you could send me the main program code such that I could physically facilitate on my Arduino IDE,
    Thank you so much & have a nice day.

    Truly,
    Kent Horng

  2. Hi
    Great project going to use it as a basis for my project
    Got it up and running but keeps disconnecting
    Any ideas?

    Many thanks

    Peter

  3. Hi,
    This was a great IoT project which i had seen. I was eager to work on this project base in my college project but am not able to process this out as you done. am stuck somewhere like my misting and display is not working as well am unable to see any progress in my Blynk IoT. can you please help me in this.

  4. what is the connection here…i mean can it be viewed from anywhere in the world and how did you accomplish that because i didn’t see any router to connect the esp8266 please i need more info

  5. the code is running fine and it show results on oled display but it is not getting connected to wifi and blynk IoT. please reply as soon as possible

Leave a Reply

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

Back to top button