/**
ESP32 + DHT22 Example for Wokwi
https://wokwi.com/arduino/projects/322410731508073042
*/
#include "DHTesp.h"
#include <DallasTemperature.h>
#include <LiquidCrystal_I2C.h>
#include <WiFi.h>
#include <OneWire.h>
#include "ThingSpeak.h"
#define DHT_PIN 15
#define DALLAS_TEMP_PIN 4
#define SOIL_MOISTURE_PIN 5
#define PUSH_BUTTON 2
#define SOIL_MOIST_PIN 33
#define WATER_PUMP 12
#define BUZZER 13
OneWire oneWire(DALLAS_TEMP_PIN); // Setup a oneWire instance to communicate with dallas temperature sensor
DallasTemperature dallasTemp(&oneWire);
LiquidCrystal_I2C LCD = LiquidCrystal_I2C(0x27, 16, 2); // Set up I2C LCD
DHTesp dhtSensor; // set up DHT22 sensor
WiFiClient client;
// Sensor reading variables
float dht_temp;
float dht_humidity;
float soil_temp;
//ThingSpeak channelID and Write API key
unsigned long myChannelNumber = 1974516;
const char * myWriteAPIKey = "FPK1MESWX9ONBY8F";
//Time variables
unsigned long cloud_lastTime = 0;
unsigned long cloudDelay = 15000; //seconds intervals to update ThingSpeak cloud
unsigned long screen_lastTime = 0;
unsigned long screenDelay = 2000; //seconds intervals to update the serial monitor and LCD
int LCD_view = 0; // a variable to switch what's being displayed on the LCD
bool cloudUpdate = false; // A flag to track if the last cloud update was successful
// Variables to caliberate the soil Moisture sensor
const int dryValue = 590; //you need to replace this value with Value_1
const int wetValue = 300; //you need to replace this value with Value_2
int soil_moistValue; // The analogue reading of the sensor
int soil_moistPercent;
const int moistThreshold = 60; // Water pump is activated ones soil moisture falls bellow this level
bool soil_isDry = false;
String myStatus = "";
//WiFi Credentials
// const char* ssid = "Redmi Note 9S"; // your network SSID (name)
// const char* password = "yinkus4ever"; // your network password
void setup() {
Serial.begin(115200);
pinMode(PUSH_BUTTON, INPUT_PULLUP);
pinMode(WATER_PUMP, OUTPUT);
pinMode(BUZZER, OUTPUT);
LCD.init();
LCD.backlight();
dhtSensor.setup(DHT_PIN, DHTesp::DHT22);
dallasTemp.begin(); // Start the DS18B20 sensor
// WiFi.begin(ssid, password);
WiFi.begin("Wokwi-GUEST", "", 6);
while (WiFi.status() != WL_CONNECTED) {
delay(100);
Serial.print(".");
LCD.setCursor(0, 0);
LCD.print("Connecting WiFi");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
LCD.clear();
LCD.setCursor(0, 0);
LCD.print("Connected to:");
LCD.setCursor(0, 1);
//LCD.print(ssid);
delay(500);
ThingSpeak.begin(client); // Initialize ThingSpeak
}
void loop() {
// Reading from DHT22 Sensor
TempAndHumidity dht = dhtSensor.getTempAndHumidity();
dht_temp = dht.temperature;
dht_humidity = dht.humidity;
// Reading from Dallas Temperature sensor
dallasTemp.requestTemperatures();
soil_temp = dallasTemp.getTempCByIndex(0);
// Reading from the Soil moisture sensor
soil_moistValue = analogRead(SOIL_MOIST_PIN);
soil_moistPercent = map(soil_moistValue, dryValue, wetValue, 0, 100);
if (soil_moistPercent > 100)
soil_moistPercent = 100;
if (soil_moistPercent < 0)
soil_moistPercent = 0;
// Activate Water Pump and Alarm if moisture level falls below threshold
if (soil_moistPercent < moistThreshold) {
digitalWrite(WATER_PUMP, HIGH);
digitalWrite(BUZZER, HIGH);
soil_isDry = true;
}
else {
digitalWrite(WATER_PUMP, LOW);
digitalWrite(BUZZER, LOW);
soil_isDry = false;
}
// Update sensor readngs on displays every "screenDelay" seconds
if ((millis() - screen_lastTime) >= screenDelay) {
update_Display(LCD_view);
screen_lastTime = millis();
}
// Also update Screen if button is pushed
if (digitalRead(PUSH_BUTTON) == LOW) {
LCD_view++;
if (LCD_view > 3) {
LCD_view = 0;
}
update_Display(LCD_view);
}
// Update Sensor readings on cloud every "cloudDelay" seconds
if ((millis() - cloud_lastTime) >= cloudDelay) {
update_ThingSpeak();
cloud_lastTime = millis();
}
}
void update_Display(int viewOption) {
Serial.println("Air Temp: " + String(dht_temp, 2) + "°C");
Serial.println("Humidity: " + String(dht_humidity, 1) + "%");
Serial.println("Soil Temp: " + String(soil_temp, 2) + "°C");
Serial.println("soil Moisture: " + String(soil_moistPercent) + "%");
Serial.println("---");
switch (viewOption) {
case 0: //LCD screen zero also Notifies when Soil is dry
if (!soil_isDry) {
LCD.clear();
LCD.setCursor(0, 0);
LCD.print("Temp: " + String(dht_temp, 2) + char(223) + "C");
LCD.setCursor(0, 1);
LCD.print("Humidity: " + String(dht_humidity, 1) + "%");
}
else {
LCD.clear();
LCD.setCursor(5, 0);
LCD.print("ALERT!");
LCD.setCursor(0, 1);
LCD.print("Soil is Dry");
}
break;
case 1: //LCD Screen one also flashes if Soil moisture is too low
LCD.clear();
LCD.setCursor(0, 0);
LCD.print("Soil Temp: " + String(soil_temp, 2) + "C");
LCD.setCursor(0, 1);
LCD.print("Soil Moist: " + String(soil_moistPercent) + "%");
break;
case 2: //Gives the current status of the soil moisture and the water pump
LCD.clear();
LCD.setCursor(0, 0);
LCD.print("Moisture is ");
LCD.setCursor(0, 1);
LCD.print("Pump is ");
if (soil_isDry) {
LCD.setCursor(10, 0);
LCD.print("LOW");
LCD.setCursor(8, 1);
LCD.print("ON");
}
else {
LCD.setCursor(12, 0);
LCD.print("OKAY");
LCD.setCursor(8, 1);
LCD.print("OFF");
}
break;
// LCD Screen three
case 3:
LCD.clear();
LCD.setCursor(0, 0);
LCD.print("Last CloudUpdate");
LCD.setCursor(0, 1);
if (cloudUpdate)
LCD.print("Successful");
else
LCD.print("Failed !");
LCD.setCursor(13, 1);
LCD.print(String((millis() - cloud_lastTime)/1000) + "s");
break;
}
}
void update_ThingSpeak() {
// set the fields with the values on thingspeak
ThingSpeak.setField(1, dht_humidity);
ThingSpeak.setField(2, dht_temp);
// ThingSpeak.setField(3, soil_temp);
ThingSpeak.setField(4, soil_moistPercent);
if (soil_moistPercent < moistThreshold)
myStatus = String("Soil Moisture level is OKAY");
else
myStatus = String("Soil Moisture level TOO LOW !");
ThingSpeak.setStatus(myStatus);
int x = ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey);
if(x == 200){
Serial.println("Channel update successful.");
cloudUpdate = true;
}
else{
Serial.println("Problem updating channel. HTTP error code " + String(x));
cloudUpdate = false;
// Notify the Update error in LCD
LCD.clear();
LCD.setCursor(0, 0);
LCD.print("Cloud Update");
LCD.setCursor(0, 1);
LCD.print("Error " + String(x));
delay(1000);
LCD.clear();
}
}
esp:VIN
esp:GND.2
esp:D13
esp:D12
esp:D14
esp:D27
esp:D26
esp:D25
esp:D33
esp:D32
esp:D35
esp:D34
esp:VN
esp:VP
esp:EN
esp:3V3
esp:GND.1
esp:D15
esp:D2
esp:D4
esp:RX2
esp:TX2
esp:D5
esp:D18
esp:D19
esp:D21
esp:RX0
esp:TX0
esp:D22
esp:D23
dht1:VCC
dht1:SDA
dht1:NC
dht1:GND
lcd1:GND
lcd1:VCC
lcd1:SDA
lcd1:SCL
btn1:1.l
btn1:2.l
btn1:1.r
btn1:2.r
led1:A
led1:C
bz1:1
bz1:2
pot2:VCC
pot2:SIG
pot2:GND