#include <TinyGPS++.h>
#include <TinyGPSPlus.h>
#include <SoftwareSerial.h>
#include <LiquidCrystal_I2C.h>
#include "Ultrasonic.h"
#include <Servo.h>
// Pins for the SIM800L module
#define SIM800_RX 8
#define SIM800_TX 7
#define GPS_RX 6
#define GPS_TX 5
Servo myservo;
unsigned long metalDetectedAt = 0;
bool binOpen = false;
// --- Pin Definitions ---
#define TRIG_PIN 9
#define ECHO_PIN 10
#define NPN_SENSOR_PIN 2
#define SERVO_PIN 3
Ultrasonic ultrasonic(TRIG_PIN, ECHO_PIN);
int distance;
int max_height = 400;
long lastSentLevel = 0;
// Create instances
SoftwareSerial SIM800L(SIM800_RX, SIM800_TX);
SoftwareSerial gpsSerial(GPS_RX, GPS_TX);
TinyGPSPlus gps;
double latitude = 0.4600;double longitude= 32.5200;
String response;
int lastStringLength = 0; // Initialize to 0
LiquidCrystal_I2C lcd(0x27, 20, 4); // assigning the lcd screen with its address
String link;
String PhoneNumber; // Variable to store SIM card phone number
String PhoneNumbers[] = {
"+256787917973",
"+256780328639",
"+256784258975"
};
void setup() {
Serial.begin(9600);
Serial.println(" GPS ISBAT UNIVERISTY ");
pinMode(NPN_SENSOR_PIN, INPUT);
myservo.attach(SERVO_PIN);
gpsSerial.begin(9600);
SIM800L.begin(9600);
SIM800L.println("AT+CMGF=1");
// Serial.println("SIM800L started at 9600");
delay(1000);
// Serial.println("Setup Complete! SIM800L is Ready!");
delay(1000);
SIM800L.println("AT+CNMI=2,2,0,0,0");
// Initialize lastStringLength
lastStringLength = response.length();
// Request SIM card phone number
SIM800L.println("AT+CNUM");
//lcd
lcd.init(); //inilizing the lcd
lcd.backlight(); // enabling the backlight
lcd.setCursor(0, 0);
lcd.print("ELECTRONIC");
lcd.setCursor(0, 1);
lcd.print("WASTE");
lcd.setCursor(0, 2);
lcd.print("BIN");
lcd.setCursor(0, 3);
lcd.print("ISBAT UNIVERSITY");
delay(15000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("ELECTRONIC WASTE BIN");
}
void loop() {
if (SIM800L.available() > 0) {
response = SIM800L.readStringUntil('\n');
// Check if the response contains the SIM card phone number
if (response.indexOf("+CNUM") != -1) {
// Extract the phone number from the response
int startIdx = response.indexOf(",\"") + 2;
int endIdx = response.indexOf("\",", startIdx);
PhoneNumber = response.substring(startIdx, endIdx);
Serial.println("Detected SIM card phone number: " + PhoneNumber);
PhoneNumber.trim(); // Remove leading/trailing whitespace
link = "AT+CMGS=\"" + PhoneNumber + "\"\r"; // Update the SMS command
}
}
if (lastStringLength != response.length()) {
GPS();
// Perintah ON
if (response.indexOf("CEKLOKASI") != -1) { //ganti CEK dengan keyword yang diinginkan jangan gunakan spasi
SIM800L.println("AT+CMGF=1"); //Sets the GSM Module in Text Mode
delay(1000); // Delay of 1000 milliseconds or 1 second
SIM800L.println(link);// The SMS text you want to send
delay(100);
SIM800L.println((char)26);// ASCII code of CTRL+Z
delay(1000);
}
}
//inductive proximity logic
int state = digitalRead(NPN_SENSOR_PIN); // Read inductive sensor
if (state == LOW) {
myservo.write(90); // Move servo to 90 degrees (open)
delay(200);
}else
{
myservo.write(0);
}
// distance = ultrasonic.read(CM);
// Serial.print("Distance in CM: ");
// Serial.println(distance);
// distance = ultrasonic.read(INC);
// Serial.print("Distance in Inches: ");
// Serial.println(distance);
//delay(1000);
// Trigger the ultrasonic sensor
digitalWrite(TRIG_PIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
// Read the echo pin to get duration
int duration = pulseIn(ECHO_PIN, HIGH);
float distance = duration * 0.034 / 2; // Convert duration to distance IN CM
// invert distaces for the ultrasonic with an object reading
long invert_distance = max_height - distance;
//to avoid negative values
if (invert_distance < 0) invert_distance = 0;
if (invert_distance > max_height) invert_distance = max_height;
// converting to percentages
int level = (int)(((float)invert_distance / (float)max_height) * 100);
//avoid negative percentage
if (level < 0) level = 0;
if (level > 100) level = 100;
level = map(invert_distance, 5, max_height, 100, 0);
level =constrain(level, 0, 100);
String levelMessage = ""; // Create a string to store the message
if (level == 75 && lastSentLevel != 75) {
levelMessage = "75% full - Please prepare to empty";
Serial.println("****Notification: " + levelMessage +"************");
link = "www.google.com/maps/place/" + String(latitude, 3) + "," + String(longitude, 3);
Serial.println(link);
sendsms(levelMessage);
lastSentLevel = 75;
} else if (level == 95 && lastSentLevel != 95) {
levelMessage = "95% full - Action is recommended";
Serial.println("Notifcation: " + levelMessage);
sendsms(levelMessage);
link = "www.google.com/maps/place/" + String(latitude, 3) + "," + String(longitude, 3);
Serial.println(link);
lastSentLevel = 95;
} else if (level == 100 && lastSentLevel != 100) {
levelMessage = "100% full - Immediate action required!";
Serial.println("Emergency: " + levelMessage);
sendsms(levelMessage);
link = "www.google.com/maps/place/" + String(latitude, 3) + "," + String(longitude, 3);
Serial.println(link);
lastSentLevel = 100;
}
lcd.setCursor(0, 1);
lcd.print("BIN LEVEL IS: ");
lcd.print(level);
lcd.print("% ");
float latitude, longitude;
if (gpsSerial.available() > 0) {
gps.encode(gpsSerial.read());
}
// Default fallback coordinates (Ndejje University, Uganda)
const float DEFAULT_LAT = 0.4600;
const float DEFAULT_LON = 32.5200;
// Process GPS data
while (gpsSerial.available() > 0) {
gps.encode(gpsSerial.read());
}
// Use valid GPS data if available, otherwise use fallback
if (gps.location.isValid() && gps.location.age() < 2000) {
latitude = gps.location.lat();
longitude = gps.location.lng();
} else {
latitude = DEFAULT_LAT;
longitude = DEFAULT_LON;
}
// Print and show on LCD
//Serial.print("LAT="); Serial.println(latitude, 4);
//Serial.print("LONG="); Serial.println(longitude, 4);
lcd.setCursor(0, 2);
lcd.print("LAT:"); lcd.print(latitude, 2);
lcd.print(" LOG:"); lcd.print(longitude, 2);
}
void GPS() {
if (Serial.available()) {
gps.encode(Serial.read());
}
if (gps.location.isUpdated()) {
latitude = gps.location.lat();
longitude = gps.location.lng();
link = "www.google.com/maps/place/" + String(latitude, 3) + "," + String(longitude, 3);
Serial.println(link);
}
}
void sendsms(String statusMessage) {
// Get current or fallback GPS location
float lat = gps.location.isValid() ? gps.location.lat() : 0.4600;
float lon = gps.location.isValid() ? gps.location.lng() : 32.5200;
// Construct Google Maps lintrk
String googlelink = "https://maps.google.com/?q=" + String(lat, 6) + "," + String(lon, 6);
// Fake date/time for now
String timeStr = "12:00"; // Replace later with actual time
String dateStr = "22/04/2025"; // Replace later with RTC or NTP
// Compose message
String MESSAGE = "ELECTRONIC WASTE BIN ISBAT\n";
MESSAGE += "Bin Status: " + statusMessage + "\n";
MESSAGE += "Location: " + googlelink + "\n";
MESSAGE += "Date: " + dateStr + "\n";
MESSAGE += "Time: " + timeStr + "\n";
MESSAGE += "---------------------------------\n";
// Simulate SMS by printing to Serial
Serial.println(MESSAGE );
}