#include <WiFi.h>
#include <WiFiClient.h>
#include <ESP32Servo.h>
#include "ThingSpeak.h"
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4);
#define Second 1000
#define Dry_Echo 18
#define Dry_Trig 19
#define Wet_Echo 4
#define Wet_Trig 23
#define SoilMoisture 33
#define ServoMotor 21
const char* WIFI_NAME = "Wokwi-GUEST"; // WiFi SSID
const char* WIFI_PASSWORD = ""; // WiFI Password
const int myChannelNumber = 2520070; // ThingSpeak channel number
const char* myApiKey = "6EZGVRB1XQV3261X"; // ThingSpeak API key
const char* server = "api.thingspeak.com"; // ThingSpeak server address
WiFiClient client;
// functions
float calculate_distance(int Trig, int Echo, char can);
bool is_full(int Trig, int Echo, char can);
float calibrate(int moisture);
// global variables
char ssid[] = "Wokwi-GUEST";
char pass[] = "";
bool dry_full = 0;
bool wet_full = 0;
int servo_pos = 90;
int max_moisture = 4095;
int min_moisture = 1095;
float threshold = calibrate(4000);
Servo servo;
void setup() {
// Wifi setup
Serial.begin(115200);
WiFi.begin(WIFI_NAME, WIFI_PASSWORD);
while (WiFi.status() != WL_CONNECTED){
delay(1000);
Serial.println("Wifi not connected");
}
Serial.println("Wifi connected !");
Serial.println("Local IP: " + String(WiFi.localIP()));
WiFi.mode(WIFI_STA);
ThingSpeak.begin(client);
// LCD initialization
lcd.init();
lcd.backlight();
lcd.clear();
lcd.setCursor(5,0);
lcd.print("Welcome to waste management system");
Serial.begin(115200);
pinMode(Dry_Trig, OUTPUT);
pinMode(Dry_Echo, INPUT);
pinMode(Wet_Trig, OUTPUT);
pinMode(Wet_Echo, INPUT);
pinMode(SoilMoisture, INPUT);
servo.attach(ServoMotor, 500, 2400);
}
void loop() {
Serial.println("______________________");
// manage trash
int moisture_value = analogRead(SoilMoisture);
float moisture = calibrate(moisture_value);
Serial.print("Moisture : ");
Serial.print(moisture_value);
Serial.print(" ----> calibrated : ");
Serial.print(moisture);
Serial.println("%");
bool wet_trash = moisture > threshold;
ThingSpeak.setField(3, moisture_value);
if(wet_trash){
Serial.print("The trash is wet! (threshold = ");
Serial.print(threshold);
Serial.println("%)");
ThingSpeak.setField(3, 1);
// open gate
for (servo_pos = 90; servo_pos >= 0; servo_pos -= 1) {
servo.write(servo_pos);
delay(15);
}
delay(5 * Second);
// close gate
for (servo_pos = 0; servo_pos <= 90; servo_pos += 1) {
servo.write(servo_pos);
delay(15);
}
int status = ThingSpeak.writeFields(myChannelNumber, myApiKey);
}
else{
ThingSpeak.setField(3, 0);
}
lcd.clear();
// manage can
dry_full = is_full(Dry_Trig, Dry_Echo, 'D');
wet_full = is_full(Wet_Trig, Wet_Echo, 'W');
if (dry_full && wet_full){
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Dry can and wet can is full");
}
else if (dry_full){
Serial.println("The dry can is full.");
lcd.clear();
lcd.setCursor(5, 1);
lcd.print("Dry can is full");
}
else if (wet_full){
Serial.println("The wet can is full.");
lcd.clear();
lcd.setCursor(5, 1);
lcd.print("Wet can is full");
}
else{
lcd.clear();
lcd.setCursor(5, 1);
lcd.print("Cans are empty");
}
delay(10 * Second);
}
float calculate_distance(int Trig, int Echo, char can){
digitalWrite(Trig, LOW);
delay(2);
digitalWrite(Trig, HIGH);
delay(10);
digitalWrite(Trig, LOW);
int duration = pulseIn(Echo, HIGH);
float distance = duration * 0.034 /2;
Serial.print(can);
if(can=='D'){
ThingSpeak.setField(1, distance);
}else{
ThingSpeak.setField(2, distance);
}
Serial.print(" free space : ");
Serial.print(distance);
Serial.println(" CM");
return distance;
}
bool is_full(int Trig, int Echo, char can){
float distance = calculate_distance(Trig, Echo, can);
return distance < 4;
}
float calibrate(int moisture){
int x = (max_moisture - min_moisture)/100;
return (max_moisture - moisture)/x;
}