Introduction: Automatic Humidifier Control Using ESP328266

About: Do you like technology? Follow my channel on Youtube and my Blog. In them I put videos every week of microcontrollers, arduinos, networks, among other subjects.

Today, I decided to show a project that I actually made for use in my own home. I have an air humidifier, which often leaves the room too dry. And sometimes, it leaves water on the floor around it. So I thought to myself: I use both DHTs, so why not make an automatic moisture control?

Well, that's exactly what I did, and I'll discuss this further in the video, “How to make an ESP32 read the humidity and show it on an OLED display.” Also, based on humidity, the ESP32 will (via the ESP-NOW protocol) send the signal to an ESP8266 that’s on or off the relay.

One important tip is that in this same project, as I have shown in other videos, you can also read the temperature of the environment.

Step 1: Loop

In this flowchart, we explain each step of the project:

1º - ESP32 reads the humidity.

2º - Show the humidity display

3º - Check humidity:

- Below the lower limit: send signal to the ESP8266 switch on the relay

- Above the upper limit: send signal to the ESP8266 switch off the relay

Step 2: ESP32 Pinout

Step 3: Assembly

Step 4: Demonstration

In the demo on the video, the LED is on because the humidity is at 45%. However, when I blow on it, and humidity goes to 93%, this LED goes out. This is only to show that when the humidity stays above 60%, the LED is erased. We have the ESP8266 and the ESP32 mounted on a standard board. The ESP32 is connected to the DHT and the OLED display.

Step 5: SimpleDHT Library

In the Arduino IDE, go to Sketch-> Include Library-> Manage Libraries ...

Install SimpleDHT

Step 6: U8g2 Library

In the Arduino IDE, go to Sketch-> Include Library-> Manage Libraries ...

Install U8g2

Step 7: ESP32_EspNow_Master.ino

I suggest that before doing this project, you watch this video, “ESP32 WITH ESP-NOW PROTOCOL"

To start, we’ll include the libraries and define the pins. We instantiate the display object and the object performing humidity reading, and then we point the array that is waiting for the MacAddress. We then create the variable that stores the value of the humidity.

#include <esp_now.h>
#include <WiFi.h> #include <SimpleDHT.h> #include <U8x8lib.h>

#define DHTPIN 4 #define MAX_HUMIDITY 60 #define MIN_HUMIDITY 50 #define INTERVAL 10000 #define ESPNOW_CHANNEL 1 //SDA = 21 e SCL = 22 U8X8_SSD1306_128X64_NONAME_SW_I2C display(SCL, SDA, U8X8_PIN_NONE); uint8_t slaveMacAddress[] = {0x1A,0xFE,0x34,0xA5,0x90,0x69}; esp_now_peer_info_t slave; //Objeto que realiza a leitura da umidade SimpleDHT22 dht; //Variável para guardarmos o valor da umidade float humidity = 0;

Step 8: ESP32_EspNow_Master.ino – Setup

In the Setup, I have a warning: if you do not do a WiFi.disconnect, then the circuit becomes unstable. When you do this, it clears any previous information it had in memory.

void setup() {
Serial.begin(115200); WiFi.disconnect(); WiFi.mode(WIFI_STA); setupDisplay(); setupESPNow(); setupSlave(); }

Step 9: ESP32_EspNow_Master.ino – Loop

In the Loop, we read the sensor and display the data on the display.

void loop() {
readSensor(); showOnDisplay(); verifyHumidity(); delay(INTERVAL); }

Step 10: ESP32_EspNow_Master.ino – SetupDisplay

Here, we detail the functions: we initialize the display and configure some parameters. We start the powerSave mode and set the source for use in the display.

void setupDisplay(){
//inicializa o display e configura alguns parâmetros display.begin(); display.setPowerSave(0); //modo powerSave (0-Off ? 1-On) display.setFont(u8x8_font_torussansbold8_u); //fonte utilizada }

Step 11: ESP32_EspNow_Master.ino – SetupESPNow

We determine here what will be printed on the display in case of successful initialization or some kind of error. In the latter case, after reporting its status, it restarts the ESP.

void setupESPNow() {
//Se a inicialização foi bem sucedida if (esp_now_init() == ESP_OK) { Serial.println("ESPNow Init Success"); } //Se houve erro na inicialização else { Serial.println("ESPNow Init Failed"); ESP.restart(); } }

Step 12: ESP32_EspNow_Master.ino – SetupSlave

We define the channel here, and then we copy the address of the array to the slave structure and add the slave.

void setupSlave(){
slave.channel = ESPNOW_CHANNEL; //0 para não usar criptografia ou 1 para usar slave.encrypt = 0; //Copia o endereço do array para a estrutura do slave memcpy(slave.peer_addr, slaveMacAddress, 6); //Adiciona o slave esp_now_add_peer(&slave); }

Step 13: ESP32_EspNow_Master.ino – SendRelayStatus

Here is the status of the relay. In this case, specifically, mine was LED. It then displays whether the action was successful or had errors.

void sendRelayStatus(int relayStatus){
esp_err_t result = esp_now_send(slaveMacAddress, (uint8_t*)&relayStatus, 1); Serial.print("Send Status: "); if (result == ESP_OK) { Serial.println("Success"); } else { Serial.println("Error"); } }

Step 14: ESP32_EspNow_Master.ino - VerifyHumidity

At this stage, we confirm the range of the humidity and inform the ESP8266 if the relay should be switched on or off.

//Verifica se a umidade está fora dos limites e informa ao ESP8266
//se o relê deve ficar ligado ou desligado void verifyHumidity(){ if(humidity > MAX_HUMIDITY) { Serial.println("Umidade máxima atingida, enviando sinal para desligar o relê"); sendRelayStatus(LOW); } else if(humidity < MIN_HUMIDITY) { Serial.println("Umidade mínima atingida, enviando sinal para ligar o relê"); sendRelayStatus(HIGH); } }

Step 15: ESP32_EspNow_Master.ino – ReadSensor

This is the function responsible for reading the humidity.

//Função responsável por realizar a leitura
//da umidade void readSensor(){ float h; int status = dht.read2(DHTPIN, NULL, &h, NULL); if (status == SimpleDHTErrSuccess) { humidity = h; } }

Step 16: ESP32_EspNow_Master.ino – ShowOnDisplay

We show the humidity in the display.

//Mostra a umidade no display
void showOnDisplay(){ String strHumdity = "HUMIDITY: " + String(humidity); display.clearLine(0); display.drawString(0, 0, strHumdity.c_str()); }

Step 17: ESP8266_EspNow_Slave.ino

In the ESP8266 ESP-Now Setup, we have a new library to include. However, the function calls are the same. We also put in the ESP8266WiFI.h and set the 5 as a relay pin.

extern "C" {
#include <espnow.h>

} #include <ESP8266WiFi.h>

#define RELAY_PIN 5

Step 18: ESP8266_EspNow_Slave.ino - Setup

We put the pin of the relay as output and with low signal. We then reset the WiFi settings and put them into AP mode. We copy the address that appears, and we put it in the slaveMacAddress of the Master.

void setup() {
Serial.begin(115200); //Coloca o pino do relê como saída e coloca com sinal baixo pinMode(RELAY_PIN, OUTPUT); digitalWrite(RELAY_PIN, LOW); //Reseta as configurações da WiFi WiFi.disconnect(); //Coloca em modo AP WiFi.mode(WIFI_AP); setupESPNow(); //Copiar o endereço que aparece aqui e colocar //no slaveMacAddress do Master Serial.print("AP MAC: "); Serial.println(WiFi.softAPmacAddress()); }

Step 19: ESP8266_EspNow_Slave.ino – SetupESPNow

We start ESP-Now and record the function that will be executed when new data arrives.

void setupESPNow(){
//Inicializa o ESPNOW if (esp_now_init()!=0) { Serial.println("EspNow init failed"); ESP.restart(); } //0=IDLE, 1=MASTER, 2=SLAVE and 3=MASTER+SLAVE esp_now_set_self_role(ESP_NOW_ROLE_SLAVE); //Registra a função que será executada quando novos //dados chegarem esp_now_register_recv_cb(receiveCallback); }

Step 20: ESP8266_EspNow_Slave.ino – ReceiveCallback

Proceeding, in the Callback function, we define the relayStatus to receive the date [0].

//Função que será executada quando chegarem novos dados
void receiveCallback(uint8_t *mac, uint8_t *data, uint8_t len) { int relayStatus = data[0]; digitalWrite(RELAY_PIN, relayStatus); }

Step 21: ESP8266_EspNow_Slave.ino - Loop

We have nothing to do in the Loop, as information is received by receiveCallback automatically when new data arrives.

//Nada para fazer no loop já que as informações
//são recebidas pelo receiveCallback //automaticamente quando novos dados chegam void loop() { }

Step 22: Download the Files