#include <ESP32Servo.h>
#include <WiFi.h>
#include <PubSubClient.h>
#include <DHTesp.h>
const char* ssid = "Wokwi-GUEST";
const char* password = "";
const char* hostname = "broker.hivemq.com";
WiFiClient espClient;
PubSubClient client(espClient);
const char* espClientName = "esp32Client_SmartBin";
int PORTNUM = 1883;
const int PirPin = 4; // PIR sensor pin
const int PirLEDPin = 5; // Motion indicator LED pin
const int fullLEDPin = 14; // Bin full indicator LED pin
const int triggerPin = 13; // Ultrasonic sensor trigger pin
const int echoPin = 12; // Ultrasonic sensor echo pin
const int lidSpeed = 30; // Lid servo speed
const int DHT_PIN = 15; // DHT22 sensor pin
const int servoPin = 2; // Servo motor pin
int lidState = LOW; // Lid state (open or closed)
int pirState = LOW; // PIR sensor state (motion detected or not)
int val = 0; // PIR sensor value
int lidPosition = 90; // Initial lid position
int threshold = 15; // Distance threshold for bin full
Servo servo;
DHTesp dhtSensor;
void setup_wifi() {
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
Serial.println();
Serial.print("Connected to ");
Serial.println(ssid);
Serial.print("Given IP by the router to the ESP32 is ");
Serial.println(WiFi.localIP());
}
void connectMQTT() {
while (!client.connected()) {
Serial.println("Connecting to MQTT ...");
if (client.connect(espClientName)) {
Serial.println("Connected");
// MQTTSubscribe(); // You may add MQTT subscriptions here if needed
} else {
Serial.print("Failed with state ");
Serial.print(client.state());
delay(1000);
}
}
}
void setup() {
Serial.begin(9600);
servo.attach(servoPin, 500, 2400);
pinMode(PirPin, INPUT);
pinMode(PirLEDPin, OUTPUT);
pinMode(fullLEDPin, OUTPUT);
pinMode(triggerPin, OUTPUT);
pinMode(echoPin, INPUT);
setup_wifi();
client.setServer(hostname, PORTNUM);
// Initialize DHT22 sensor
dhtSensor.setup(DHT_PIN, DHTesp::DHT22);
}
void loop() {
if (!client.connected()) {
connectMQTT();
}
client.loop();
val = digitalRead(PirPin);
// Ultrasonic sensor measurement
digitalWrite(triggerPin, HIGH);
delayMicroseconds(10);
digitalWrite(triggerPin, LOW);
int duration = pulseIn(echoPin, HIGH);
int distance = duration / 58; // Convert pulse duration to distance in cm
char dist[10];
sprintf(dist, "%d", distance);
client.publish("SmartBIN/Bin01/Distance", dist);
bool is_full = distance <= threshold; // Check if bin is full
if (val == HIGH) {
if (!is_full) {
digitalWrite(PirLEDPin, HIGH); // Turn on motion indicator LED
if (pirState == LOW) {
pirState = HIGH;
}
lidOpen(); // Open the lid
} else {
digitalWrite(fullLEDPin, HIGH); // Blink bin full indicator LED
delay(1000);
digitalWrite(fullLEDPin, LOW);
}
} else {
digitalWrite(PirLEDPin, LOW); // Turn off motion indicator LED
if (pirState == HIGH) {
pirState = LOW;
}
lidClose(); // Close the lid
}
// Read temperature and humidity
TempAndHumidity data = dhtSensor.getTempAndHumidity();
delay(2000); // Wait for next reading
// Publish temperature and humidity to MQTT topics
char tempStr[10];
char humStr[10];
sprintf(tempStr, "%.2f", data.temperature);
sprintf(humStr, "%.2f", data.humidity);
client.publish("SmartBIN/Bin01/Temperature", tempStr);
client.publish("SmartBIN/Bin01/Humidity", humStr);
Serial.println("---");
delay(2000); // Wait for next reading
}
void lidOpen() {
if (lidState == LOW) {
while (lidPosition > 0) { // Adjust to the minimum position
servo.write(lidPosition);
lidPosition -= 1;
delay(lidSpeed);
}
servo.write(0); // Ensure lid is fully open
lidPosition = 0;
lidState = HIGH;
client.publish("SmartBIN/Bin01/ServoStatus", "open"); // Publish open status
}
}
void lidClose() {
if (lidState == HIGH) {
while (lidPosition < 90) { // Adjust to the maximum position
servo.write(lidPosition);
lidPosition += 1;
delay(lidSpeed);
}
servo.write(90); // Ensure lid is fully closed
lidPosition = 90;
lidState = LOW;
client.publish("SmartBIN/Bin01/ServoStatus", "closed"); // Publish closed status
}
}