#include <WiFi.h>
#include <WiFiClient.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
// Pins
const int trigPin = 5;
const int echoPin = 4;
// Wi-Fi credentials
const char* SSID = "Wokwi-GUEST";
// const char* PASSWORD = "";
// Server
const String SERVER = "https://equipped-immense-parakeet.ngrok-free.app";
// last filled level
long lastInches = 0;
int lastCM = 0;
// max depth
long maxInches = 0;
long maxCM = 0;
const float maxPercentage = 75.0; // max percentage level
void setup() {
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
Serial.begin(9600);
delay(500);
Serial.print("Connecting to Wi-Fi");
WiFi.begin(SSID, "", 6);
delay(5000);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.print("\nConnected to Wi-Fi with IP ");
Serial.println(WiFi.localIP());
setMaximumDepth(trigPin, echoPin);
}
void loop() {
long t, inches;
int cm;
// pulse output
digitalWrite(trigPin, LOW);
delayMicroseconds(4);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
t = pulseIn(echoPin, HIGH);
inches = t / 74 / 2;
cm = t / 29 / 2;
Serial.print(inches);
Serial.print(" inches, ");
Serial.print(cm);
Serial.println(" cm");
float percentage = getPercentage(maxInches, maxCM, inches, cm);
Serial.print(percentage);
Serial.println("% filled");
// update fill level when bin is filled or emptied
if (lastInches > inches || lastInches < inches || lastCM > cm || lastCM < cm) {
Serial.println("Updating fill level ...");
sendReq(SERVER + "/update", percentage, inches, cm, maxInches, maxCM);
delay(1000);
}
// if greater or less than the last filled level, send a request to store or update
if (lastInches > inches && lastCM > cm && percentage >= maxPercentage && percentage <= 100.0f) {
Serial.println("Sending notification ...");
sendReq(SERVER + "/update?notification=true", percentage, inches, cm, maxInches, maxCM);
delay(1000);
}
lastInches = inches;
lastCM = cm;
delay(1000);
}
// set maximum depth
void setMaximumDepth(int trigPin, int echoPin) {
long inches, t;
int cm, counter = 10;
while (counter >= 0) {
digitalWrite(trigPin, LOW);
delayMicroseconds(4);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
t = pulseIn(echoPin, HIGH);
inches = t / 74 / 2;
cm = t / 29 / 2;
if (counter == 0) {
counter = -1;
maxInches = inches;
maxCM = cm;
Serial.print("Max depth: ");
Serial.print(maxInches);
Serial.print(" inch(es), ");
Serial.print(maxCM);
Serial.println(" cm");
}
--counter;
delay(200);
}
}
// check if level is filled or crossed
float getPercentage(long maxInches, int maxCM, long inches, int cm) {
float totalDepthCM = (maxInches * 2.54) + maxCM;
float totalCM = (inches * 2.54) + cm;
float filledCM = abs(totalDepthCM - totalCM);
float percentage = (filledCM / totalDepthCM) * 100.0;
return percentage;
}
void sendReq(String Server_URI, float percentage, long inches, int cm, long maxInches, int maxCM) {
if (WiFi.status() == WL_CONNECTED) {
WiFiClient client;
HTTPClient http;
String length_str, max_depth, json;
DynamicJsonDocument doc(1024);
length_str = String(inches) + "." + String(cm);
max_depth = String(maxInches) + "." + String(maxCM);
doc["bin_id"] = 101;
doc["percentage"] = percentage;
doc["max_depth"] = max_depth;
doc["level"] = length_str;
doc["location"] = "Oriental University";
serializeJson(doc, json);
http.begin(client, Server_URI);
http.addHeader("Content-Type", "application/json");
int httpResponseCode = http.POST(json);
String response = http.getString();
http.end();
Serial.println(httpResponseCode);
Serial.println(response);
}
}