#define BLYNK_TEMPLATE_ID "TMPL65eCvvgb6" //Blynk template ID
#define BLYNK_TEMPLATE_NAME "Plant monitoring system" //name of Blynk template
#define BLYNK_AUTH_TOKEN "lpYfQuUFSK4i-JknGddaENfFKM2xx-Vj" //Blynk authentication token
#define BLYNK_PRINT Serial //Blynk debugging output
#define I2C_ADDR 0x27 //12C address of the LCD module
#define LCD_COLUMNS 16 //define 16 columns in a line on LCD
#define LCD_LINES 4 //define 4 lines on LCD
#include <WiFi.h> //WiFi communication library
#include <BlynkSimpleEsp32.h> //Blynk library
#include <LiquidCrystal_I2C.h> //12C LCD control library
#include <DHTesp.h> //DHT sensor library
#include <DHT.h> //DHT sensor library
#include "ESP32Servo.h" //Serco motor control library
char auth[] = BLYNK_AUTH_TOKEN ; //set up Blynk token to connect server
char ssid[] = "Wokwi-GUEST"; //WiFi network SSID
char pass[] = ""; //Password
const int DHT_PIN = 15; //define 15 as DHT pin
const int buttonPin = 33;
const int buttonPin1 = 25;
LiquidCrystal_I2C lcd(I2C_ADDR, LCD_COLUMNS, LCD_LINES); //initializes the LCD address, num of colm and lines
int value0, value1, value2, value3, value6; //LEDs' value
//define pin of LED
byte LED_R = 26;
byte LED_Y = 27;
byte LED_G = 14;
byte LED_B = 12;
//define DHT sensor
DHTesp dht;
DHTesp dhtSensor;
//define pin of Servo motor and reading value
Servo myservo;
int potpin = 34;
int val;
//Lux calculation
const float GAMMA = 0.7;
const float RL10 = 50;
BlynkTimer timer; //creates class
bool manualControl = false; //declare manualControl as false(auto)/true(manual)
void sendSensor()
{
//Measure temperature and humidity using the DHT sensor
TempAndHumidity data = dht.getTempAndHumidity();
int analogValue = analogRead(35); //Read an analog value from pin 35
//Convert analog value to voltage and calculate resistance
float voltage = analogValue / 1024. * 5;
float resistance = 2000 * voltage / (1 - voltage / 5);
//Calculate lux using the resistance value and constants
float lux = pow(RL10 * 1e3 * pow(10, GAMMA) / resistance, (1 / GAMMA));
//Print temperature, humidity and lux readings to Serial monitor
Serial.print("Temperature: ");
Serial.println(data.temperature);
Serial.println("C ");
Serial.print("Humidity: ");
Serial.println(data.humidity);
Serial.println("% ");
Serial.print("Lux: ");
Serial.println(lux);
Serial.println("---------");
//Update LCD display with temperature, humidity, and lux readings
lcd.setCursor(0, 1);
lcd.print(" Temp: " + String(data.temperature, 1) + "\xDF"+"C ");
lcd.setCursor(0, 2);
lcd.print(" Humidity: " + String(data.humidity, 1) + "% ");
lcd.setCursor(0, 3);
lcd.print(" Lux: " + String(lux, 1));
//Assign temperature and humidity values to variables
float H = data.humidity; //Humidity value
float T = data.temperature; //Temperature value
int val = analogRead(potpin); //Read analog value from potentiometer connected to potpin
//if loop, if manualControl is !(true)= automatic
if (!manualControl) {
//first if, if temperature equal to 25
if (T == 25.0) {
//second if, temperature=25 and humidity <= 20
//turn on Red LED, move servo, and display lcd message
if (H <= 20.0){
digitalWrite(LED_R, HIGH);
digitalWrite(LED_Y, LOW);
digitalWrite(LED_G, LOW);
digitalWrite(LED_B, LOW);
val = map(val, 0, 4095, 0, 180);
myservo.write(val);
lcd.setCursor(0, 0);
lcd.print(" Give me some water!");
}
//second if, temperature=25 and humidity > 21
//turn on Yellow LED and display lcd message
else if (H > 21.0){
digitalWrite(LED_R, LOW);
digitalWrite(LED_Y, HIGH);
digitalWrite(LED_G, LOW);
digitalWrite(LED_B, LOW);
lcd.setCursor(0, 0);
lcd.print(" Feed me some snacks!");
}
//if humidity between 20.1 - 21.0
//turn off all the LEDs and display message
else {
digitalWrite(LED_R, LOW);
digitalWrite(LED_Y, LOW);
digitalWrite(LED_G, LOW);
digitalWrite(LED_B, LOW);
lcd.setCursor(0, 0);
lcd.print(" ---^V^---");
}
}
//first if, if temperature lower than 25
else if (T < 25.0) {
//second if, temperature<25 and humidity>30
//turn on Blue LED and display message
if (H > 30.0) {
digitalWrite(LED_R, LOW);
digitalWrite(LED_Y, LOW);
digitalWrite(LED_G, LOW);
digitalWrite(LED_B, HIGH);
lcd.setCursor(0, 0);
lcd.print(" I need sunshine!");
}
//second if, temperature<25 and humidity<=30
//turn off all LEDs and display message
else {
digitalWrite(LED_R, LOW);
digitalWrite(LED_Y, LOW);
digitalWrite(LED_G, LOW);
digitalWrite(LED_B, LOW);
lcd.setCursor(0, 0);
lcd.print(" ---^V^---");
}
}
//first if, if temperature higher than 25
else if (T > 25.0){
//second if, temperature>25 and humidity < 30
//turn on Red and Green LED, move servo and display message
if (H < 30.0) {
digitalWrite(LED_R, HIGH);
digitalWrite(LED_Y, LOW);
digitalWrite(LED_G, HIGH);
digitalWrite(LED_B, LOW);
val = map(val, 0, 4095, 0, 180);
myservo.write(val);
lcd.setCursor(0, 0);
lcd.print(" Hot and Dry!");
}
//second if, temperature>25 and humidity>=30
//turn off all LEDs and display message
else {
digitalWrite(LED_R, LOW);
digitalWrite(LED_Y, LOW);
digitalWrite(LED_G, LOW);
digitalWrite(LED_B, LOW);
lcd.setCursor(0, 0);
lcd.print(" ---^V^---");
}
}
}
//send value of temperature, humidity and lux to Blynk server
Blynk.virtualWrite(V4, data.temperature); //V4 as virtual pin of temperature
Blynk.virtualWrite(V5, data.humidity); //V5 as virtual pin of humidity
Blynk.virtualWrite(V7, lux); //v7 as virtual pin of lux
}
BLYNK_CONNECTED() {
Blynk.syncVirtual(V0);
Blynk.syncVirtual(V1);
Blynk.syncVirtual(V2);
Blynk.syncVirtual(V3);
Blynk.syncVirtual(V6);
}
//V0 = virtual pin of Red LED
BLYNK_WRITE(V0)
{
value0 = param.asInt(); //assigns V0 to value0
digitalWrite(LED_R, value0); //set LED_R on value0
Blynk.virtualWrite(V7, value0); //updates the value of V7 to value0
manualControl = value0 == HIGH; //set manualControl as true if value0 = 1
cekAllLed(); //function of automaticlly turn on/off all LEDs
}
//V1 = virtual pin of Yellow LED
BLYNK_WRITE(V1)
{
value1 = param.asInt(); //assigns V1 to value1
digitalWrite(LED_Y, value1); //set LED_Y on value1
Blynk.virtualWrite(V8, value1); //updates the value of V8 to value1
manualControl = value1 == HIGH; //set manualControl as true if value1 = 1
cekAllLed(); //function of automaticlly turn on/off all LEDs
}
//V2 = virtual pin of Green LED
BLYNK_WRITE(V2)
{
value2 = param.asInt(); //assigns V2 to value2
digitalWrite(LED_G, value2); //set LED_G on value2
Blynk.virtualWrite(V9, value2); //updates the value of V9 to value2
manualControl = value2 == HIGH; //set manualControl as true if value2 = 1
cekAllLed(); //function of automaticlly turn on/off all LEDs
}
//V3 = virtual pin of Blue LED
BLYNK_WRITE(V3)
{
value3 = param.asInt(); //assigns V3 to value3
digitalWrite(LED_B, value3); //set LED_B on value3
Blynk.virtualWrite(V10, value3); //updates the value of V10 to value3
manualControl = value3 == HIGH; //set manualControl as true if value3 = 1
cekAllLed(); //function of automaticlly turn on/off all LEDs
}
//V6 = virtual pin of auto turn on/off all LEDs
BLYNK_WRITE(V6)
{
value6 = param.asInt(); //assigns V6 to value6
digitalWrite(LED_R, value6);
Blynk.virtualWrite(V7, value6);
Blynk.virtualWrite(V0, value6);
digitalWrite(LED_Y, value6);
Blynk.virtualWrite(V8, value6);
Blynk.virtualWrite(V1, value6);
digitalWrite(LED_G, value6);
Blynk.virtualWrite(V9, value6);
Blynk.virtualWrite(V2, value6);
digitalWrite(LED_B, value6);
Blynk.virtualWrite(V10, value6);
Blynk.virtualWrite(V3, value6);
manualControl = value6 == HIGH;
}
//V8 = virtual pin of display value of lux in Blynk
BLYNK_WRITE(V8)
{
val = param.asInt();
Blynk.virtualWrite(V8, val);
}
//if function for turn on/off all LEDs
void cekAllLed(){
if(value0 == 1 && value1 == 1 && value2 == 1 && value3 == 1){
Blynk.virtualWrite(V6, 1);
}
else{
Blynk.virtualWrite(V6, 0);
}
}
void setup()
{
Serial.begin(115200); //Initialize the Serial console for debugging
dht.setup(DHT_PIN, DHTesp::DHT22); //Initialize DHT sensors
//Initialize LCD display and backlight
lcd.init();
lcd.backlight();
dhtSensor.setup(DHT_PIN, DHTesp::DHT22); //Initialize another DHT sensor
//Set LED pins as output for different plant care activiies
pinMode(LED_R, OUTPUT); // consider as waterind
pinMode(LED_Y, OUTPUT); // consider as fertilize
pinMode(LED_G, OUTPUT); // consider as shade net
pinMode(LED_B, OUTPUT); // consider as light up
pinMode(5, INPUT); //set a pin as input
pinMode(buttonPin, INPUT_PULLUP);
pinMode(buttonPin1, INPUT);
Blynk.begin(auth, ssid, pass); //Initialize Blynk communication with provided credentials
timer.setInterval(6000, sendSensor); //set up a timer interval to call sendSensor function every 6 seconds
myservo.attach(19); //attach a servo motor to pin 19
}
//set up loop()
void loop()
{
//Execute Blynk communication and timer tasks
Blynk.run();
timer.run();
// buttonState = digitalRead(buttonPin);
// if (buttonState == HIGH) {
// digitalWrite(LED_R, HIGH);
// }
// else {
// digitalWrite(LED_R, LOW);
// }
delay(1000); //add a delat of 1 second for loop iteration
listen_push_buttons();
}
void listen_push_buttons(){
if(digitalRead(buttonPin) == LOW){
Blynk.virtualWrite(V0, 0); //update button state
digitalWrite(LED_R, LOW);
}
else {
Blynk.virtualWrite(V0, 1); //update button state
}
if(digitalRead(buttonPin1) == LOW){
Blynk.virtualWrite(V1, 1); //update button state
digitalWrite(LED_Y, LOW);
}
else {
Blynk.virtualWrite(V1, 1); //update button state
}
}