/*
Wokwi | questions
SmartBin using Esp32
D'KingArthur™ 🇵🇭 — 7/24/24 at 11:35 PM
Project Link: https://wokwi.com/projects/404096905736664065?gh=1
*/
#include <WiFi.h>
#include <LiquidCrystal_I2C.h>
#include <ESP32Servo.h>
#include <TinyGPS++.h>
// WiFi credentials, good for Wokwi
const char* SSID = "Wokwi-GUEST"; // Replace with your SSID
const char* PASSWORD = ""; // Replace with your WiFi PASSWORD
// Constants for distance calculation
//const long timeout = 30000; // timeout for ultrasonic sensor
const int MAX_DISTANCE = 30; // max distance in cm to consider the bin full
// pin constants
const int ECHO_PIN = 16;
const int TRIG_PIN = 17;
const int SERVO_PIN = 15;
LiquidCrystal_I2C lcd(0x27, 16, 2);
Servo binServo;
TinyGPSPlus gps;
HardwareSerial gpsSerial(1); // Using UART1 for GPS communication
void binLock(bool mode) {
if (mode) {
binServo.write(90); // Move servo to lock position
} else {
binServo.write(0); // Move servo to unlock position
}
}
void connectToWiFi() {
Serial.print("\nConnecting to WiFi");
WiFi.begin(SSID, PASSWORD, 6); // adding channel is faster
while (WiFi.status() != WL_CONNECTED) {
delay(100);
Serial.print(".");
}
Serial.println(" Connected!");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
Serial.println();
}
void displayStatus(int distance, bool isFull) {
char msgBuff[17];
lcd.setCursor(0, 0);
snprintf(msgBuff, 17, "Dist: %3d cm.", distance);
lcd.print(msgBuff);
lcd.setCursor(0, 1);
snprintf(msgBuff, 17, "Bin is %s", isFull ? "FULL! " : "not full.");
lcd.print(msgBuff);
if (isFull) {
Serial.println("Bin is full. Locking...");
} else {
Serial.println("Bin is not full. Unlocking...");
}
}
int measureDistance() {
// Clear the trigger pin
digitalWrite(TRIG_PIN, LOW);
delayMicroseconds(2);
// Set the trigger pin high
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
// Read the echo pin
double duration = pulseIn(ECHO_PIN, HIGH); //, timeout);
// Calculate the distance
int distance = duration * 0.034 / 2;
return distance;
}
void showSplash() {
lcd.setCursor(3, 0);
lcd.print("Smart Bin");
lcd.setCursor(6, 1);
lcd.print("V1.0");
delay(1000);
}
void setup() {
// Initialize Serial for debugging
Serial.begin(115200);
// Initialize GPS serial
gpsSerial.begin(9600, SERIAL_8N1, 19, 23); // GPIO 19 (RX), GPIO 23 (TX)
// Initialize LCD
lcd.init();
lcd.backlight();
// Initialize ultrasonic sensor pins
pinMode(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
// Attach the servo motor
binServo.attach(SERVO_PIN);
binServo.write(0); // Start with servo in unlocked position
showSplash();
// Connect to WiFi
connectToWiFi();
}
void loop() {
static int oldDistance = 0;
bool isBinFull = false;
// get distance
int distance = measureDistance();
if (distance > oldDistance + 1 || distance < oldDistance - 1) {
oldDistance = distance;
// Check if the bin is full
isBinFull = (distance < MAX_DISTANCE) ? true : false;
// Set bin lock
binLock(isBinFull);
// Display status on LCD
displayStatus(distance, isBinFull);
}
// Handle GPS data
while (gpsSerial.available() > 0) {
if (gps.encode(gpsSerial.read())) {
if (gps.location.isValid()) {
Serial.print("Latitude: ");
Serial.println(gps.location.lat(), 6);
Serial.print("Longitude: ");
Serial.println(gps.location.lng(), 6);
}
}
}
}