#define BLYNK_TEMPLATE_ID "TMPL3OcbijxyT"
#define BLYNK_TEMPLATE_NAME "SMART CAMPUS WASTE MANAGEMENT SYSTEM"
#define BLYNK_AUTH_TOKEN "gGkuvjoylAeyhHdYo105ZrxYvdGmzCg5"
char auth[] = "gGkuvjoylAeyhHdYo105ZrxYvdGmzCg5"; // Blynk auth token
char ssid[] = "Wokwi-GUEST"; // Your WiFi SSID
char pass[] = ""; // Your WiFi password
#include <WiFi.h>
#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>
#include <HX711.h>
#include <ESP32Servo.h>
// Ultrasonic sensor pins
const int trigPin1 = 2;
const int echoPin1 = 13;
const int trigPin2 = 4;
const int echoPin2 = 12;
// Load cell pins
const int LOADCELL_DOUT_PIN = 26;
const int LOADCELL_SCK_PIN = 27;
// Servo motor pins
const int servoPin1 = 32;
const int servoPin2 = 33;
Servo servo1;
Servo servo2;
// NTC thermistor pin
const int NTC_PIN = 34; // Analog pin
// HX711 initialization
HX711 scale;
// Constants
const float BIN_HEIGHT = 150; // Height of the bin in centimeters
const int NUM_LEVELS = 5; // Number of levels to divide the bin
float SCALE_FACTOR = 420.0; // Replace with your calibration factor after calibration
BlynkTimer timer; // Declare the timer object here
void setup() {
Serial.begin(9600);
Blynk.begin(auth, ssid, pass);
pinMode(trigPin1, OUTPUT);
pinMode(echoPin1, INPUT);
pinMode(trigPin2, OUTPUT);
pinMode(echoPin2, INPUT);
pinMode(NTC_PIN, INPUT);
// Initialize load cell
scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN);
scale.set_scale(SCALE_FACTOR); // Set to the calibration factor
scale.tare(); // Reset the scale to 0
// Initialize servo motors
servo1.attach(servoPin1);
servo2.attach(servoPin2);
}
void loop() {
Blynk.run();
timer.run();
long duration1, distance1, duration2, distance2;
// Measure distance from sensor 1
digitalWrite(trigPin1, LOW);
delayMicroseconds(2);
digitalWrite(trigPin1, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin1, LOW);
duration1 = pulseIn(echoPin1, HIGH);
distance1 = duration1 * 0.034 / 2;
// Measure distance from sensor 2
digitalWrite(trigPin2, LOW);
delayMicroseconds(2);
digitalWrite(trigPin2, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin2, LOW);
duration2 = pulseIn(echoPin2, HIGH);
distance2 = duration2 * 0.034 / 2;
// Calculate fill level percentage for each sensor
float fillLevel1 = (BIN_HEIGHT - distance1) / BIN_HEIGHT * 100;
float fillLevel2 = (BIN_HEIGHT - distance2) / BIN_HEIGHT * 100;
// Map fill levels to 5 parts
int level1Part = map(fillLevel1, 0, 100, 0, NUM_LEVELS);
int level2Part = map(fillLevel2, 0, 100, 0, NUM_LEVELS);
// Print the fill levels
Serial.print("Sensor 1 Fill Level: ");
Serial.print(fillLevel1);
Serial.print("% - Level ");
Serial.println(level1Part);
Serial.print("Sensor 2 Fill Level: ");
Serial.print(fillLevel2);
Serial.print("% - Level ");
Serial.println(level2Part);
// Send data to Blynk
Blynk.virtualWrite(V0, fillLevel1);
Blynk.virtualWrite(V1, fillLevel2);
// Load cell measurement
float weight = scale.get_units(10); // Adjust for correct units (kilograms)
Serial.print("Weight: ");
Serial.print(weight, 2); // Print with 2 decimal places
Serial.println(" kg");
Blynk.virtualWrite(V2, weight);
temperature();
delay(500); // Delay between measurements
}
// Function to control the servo motors via Blynk
BLYNK_WRITE(V4) {
int switchState = param.asInt(); // Get the switch state from the Blynk app
// Set default positions for servos when turned off (switchState == 1)
int defaultPosition1 = 0;
int defaultPosition2 = 0;
servo1.detach();
servo2.detach();
if (switchState == 2) { // Switch is on (switchState should be 2)
int servoPosition = 90; // Desired servo position when switch is on
if (!servo1.attached()) servo1.attach(servoPin1); // Attach servos if not already attached
if (!servo2.attached()) servo2.attach(servoPin2);
servo1.write(servoPosition); // Set the servo position for servo1
servo2.write(servoPosition); // Set the servo position for servo2
} else { // Switch is off (switchState == 1)
// Ensure servos are attached before writing positions
if (!servo1.attached()) servo1.attach(servoPin1);
if (!servo2.attached()) servo2.attach(servoPin2);
servo1.write(defaultPosition1); // Set servo1 to default position
servo2.write(defaultPosition2); // Set servo2 to default position
delay(50); // Allow time for the servos to move to position (optional)
servo1.detach(); // Detach the servos (optional)
servo2.detach(); // Detach the servos (optional)
}
}
// Function to calculate temperature from NTC thermistor voltage
// Constants for the NTC thermistor and voltage divider circuit
void temperature() {
// Read the ADC value from the thermistor pin
int analogValue = analogRead(NTC_PIN);
const float BETA = 3950;
// Calculate the temperature in Celsius using the provided formula
float temperature = 1 / (log(1 / (4095.0 / analogValue - 1)) / BETA + 1.0 / 298.15) - 273.15;
// Print the ADC value and temperature to the Serial Monitor
Serial.print("ADC Value: ");
Serial.print(analogValue);
Serial.print(" - Temperature: ");
Serial.print(temperature);
Serial.println(" *C");
Blynk.virtualWrite(V3,temperature);
// Wait for a second before the next reading
}