/*#define BLYNK_TEMPLATE_ID "TMPL33PSswMW9"
#define BLYNK_TEMPLATE_NAME "Greenovative Bin"
#define BLYNK_AUTH_TOKEN "3aQytG-wW1ZqFYwbStB4PPfTJ76mJXcy"*/
#include <Arduino.h>
#include <ESP32Servo.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <HX711.h>
/*#include <WiFi.h>
#include <BlynkSimpleEsp32.h>*/
// -------- WiFi + Blynk --------
/*char auth[] = "3aQytG-wW1ZqFYwbStB4PPfTJ76mJXcy";
char ssid[] = "Wokwi-GUEST";
char pass[] = "";*/
// -------- Pin Definitions --------
const int trigPin = 5;
const int echoPin = 18;
const int moisturePin = 34;
const int gasPin = 32;
const int hxDtPin = 19;
const int hxSckPin = 23;
const int servoPin = 25;
const int servoPin1 = 26;
// -------- Thresholds --------
const int AIR_VALUE = 4095;
const int WATER_VALUE = 1200;
const int MOISTURE_THRESHOLD = 30;
const float WEIGHT_THRESHOLD = 100;
const int GAS_THRESHOLD = 300;
const int PERSON_DISTANCE = 100;
const float MAX_CAPACITY = 50000;
const int openAngle = 180;
const int closeAngle = 0;
// -------- Objects --------
LiquidCrystal_I2C lcd(0x27, 16, 2);
HX711 scale;
Servo sorterServo;
Servo lidServo;
// -------- Running Totals --------
float totalWeight = 0.0;
float lastWeight = 0.0;
unsigned long lidTimer = 0;
bool lidOpen = false;
// -------- Blynk Timer --------
/*BlynkTimer timer;
void sendWeightToBlynk() {
// Send total weight in KG
Blynk.virtualWrite(V2, totalWeight / 1000.0);
}
*/
void setup() {
Serial.begin(115200);
// Blynk + WiFi
Blynk.begin(auth, ssid, pass);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
// HX711
scale.begin(hxDtPin, hxSckPin);
scale.set_scale(0.379); // Calibration factor
scale.tare();
// LCD
lcd.init();
lcd.backlight();
lcd.print(" Smart Bin Ready ");
delay(1500);
lcd.clear();
// Servos
lidServo.attach(servoPin1);
lidServo.write(closeAngle);
sorterServo.attach(servoPin, 500, 2400);
sorterServo.write(90);
// Send weight every 2 seconds
timer.setInterval(2000L, sendWeightToBlynk);
}
void loop() {
/* Blynk.run();
timer.run();*/
// ---- Person detection ----
digitalWrite(trigPin, LOW); delayMicroseconds(2);
digitalWrite(trigPin, HIGH); delayMicroseconds(10);
digitalWrite(trigPin, LOW);
long duration = pulseIn(echoPin, HIGH, 30000);
float distance = duration * 0.034 / 2.0;
if (distance > 0 && distance < PERSON_DISTANCE && !lidOpen && totalWeight < MAX_CAPACITY) {
lidServo.write(openAngle);
lidOpen = true;
lidTimer = millis();
lcd.clear();
lcd.print("Person Detected");
}
if (lidOpen && millis() - lidTimer > 3000) {
lidServo.write(closeAngle);
lidOpen = false;
delay(500);
}
if (totalWeight >= MAX_CAPACITY) {
lcd.setCursor(0, 0);
lcd.print("SORRY: BIN FULL");
return;
}
// ---- Sensor readings ----
int rawMoisture = analogRead(moisturePin);
int moisturePercent = map(rawMoisture, WATER_VALUE, AIR_VALUE, 100, 0);
moisturePercent = constrain(moisturePercent, 0, 100);
int gasValue = analogRead(gasPin);
float currentWeight = 0;
if (scale.is_ready()) {
currentWeight = scale.get_units();
}
float weightDiff = currentWeight - lastWeight;
if (weightDiff >= WEIGHT_THRESHOLD) {
totalWeight += weightDiff;
lastWeight = currentWeight;
}
// ---- Material classification ----
String material = "Unknown";
int servoAngle = 90;
if ((moisturePercent >= MOISTURE_THRESHOLD) &&
(weightDiff >= WEIGHT_THRESHOLD) &&
(gasValue >= GAS_THRESHOLD)) {
material = "Organic"; servoAngle = 0;
}
else if (weightDiff > 0 && moisturePercent < MOISTURE_THRESHOLD) {
material = "Dry"; servoAngle = 180;
}
else if (weightDiff > 0 && gasValue < GAS_THRESHOLD) {
material = "Metal"; servoAngle = 45;
}
else {
material = "No Waste"; servoAngle = 90;
}
// ---- LCD & Serial ----
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(material + " Det");
lcd.setCursor(0, 1);
lcd.print("Total:");
lcd.print(totalWeight / 1000, 1);
lcd.print(" kg");
Serial.printf("Moist:%d%% | Gas:%d | ΔW:%.1f g | Total:%.1f g | %s\n",
moisturePercent, gasValue, weightDiff, totalWeight, material.c_str());
// ---- Servo sorting ----
sorterServo.write(servoAngle);
delay(1000);
sorterServo.write(90);
delay(300);
}