/*
* Smart Waste Management - IoT Sensor Simulation
* Wokwi ESP32 Integration with Ultrasonic Sensor
* Sends data to FastAPI backend via HTTP POST
*/
#include <WiFi.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
// WiFi credentials (Wokwi simulation)
const char* ssid = "Wokwi-GUEST";
const char* password = "";
// Backend API endpoint (will be replaced with ngrok URL)
String serverURL = "https://noncalculative-javion-unquoted.ngrok-free.dev/api/v1/iot/sensor-data";
http.begin(serverName);
http.addHeader("ngrok-skip-browser-warning", "true"); // Αυτό παρακάμπτει τη σελίδα της ngrok
int httpResponseCode = http.GET();
// Sensor pins
const int trigPin = 5;
const int echoPin = 18;
const int ledPin = 2;
// Bin configuration
const String BIN_ID = "WOKWI_BIN_001";
const String SENSOR_ID = "ULTRASONIC_HC_SR04";
const float BIN_HEIGHT_CM = 100.0; // Total bin height in cm
// Timing
unsigned long lastReading = 0;
const unsigned long READING_INTERVAL = 30000; // 30 seconds
void setup() {
Serial.begin(115200);
// Initialize pins
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
pinMode(ledPin, OUTPUT);
// Connect to WiFi
WiFi.begin(ssid, password);
Serial.print("Connecting to WiFi");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println();
Serial.println("✅ WiFi connected!");
Serial.print("📡 IP address: ");
Serial.println(WiFi.localIP());
Serial.println("🗑️ Smart Waste Sensor Ready");
Serial.println("📊 Sending data to: " + serverURL);
Serial.println("--------------------------------------------------");
// Initial LED blink
for(int i = 0; i < 3; i++) {
digitalWrite(ledPin, HIGH);
delay(200);
digitalWrite(ledPin, LOW);
delay(200);
}
}
void loop() {
unsigned long currentTime = millis();
if (currentTime - lastReading >= READING_INTERVAL) {
// Read ultrasonic sensor
float distance = readUltrasonicSensor();
if (distance > 0) {
// Calculate fill level percentage
float fillLevel = calculateFillLevel(distance);
// Read additional sensor data
float temperature = 20.0 + random(-5, 15); // Simulated temperature
float humidity = 45.0 + random(-10, 20); // Simulated humidity
float batteryLevel = 85.0 + random(-5, 15); // Simulated battery
float signalStrength = -45.0 + random(-15, 10); // Simulated RSSI
// Send data to backend
sendSensorData(distance, fillLevel, temperature, humidity, batteryLevel, signalStrength);
// Update LED based on fill level
updateStatusLED(fillLevel);
lastReading = currentTime;
}
}
delay(1000); // Small delay for stability
}
float readUltrasonicSensor() {
// Clear trigger pin
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
// Send 10us pulse
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
// Read echo pin
long duration = pulseIn(echoPin, HIGH, 30000); // 30ms timeout
if (duration == 0) {
Serial.println("⚠️ Sensor timeout");
return -1;
}
// Calculate distance in cm
float distance = (duration * 0.034) / 2;
Serial.print("📏 Distance: ");
Serial.print(distance);
Serial.println(" cm");
return distance;
}
float calculateFillLevel(float distance) {
// Fill level = (bin_height - distance) / bin_height * 100
float fillLevel = ((BIN_HEIGHT_CM - distance) / BIN_HEIGHT_CM) * 100.0;
// Constrain between 0-100%
fillLevel = constrain(fillLevel, 0.0, 100.0);
Serial.print("📊 Fill Level: ");
Serial.print(fillLevel);
Serial.println("%");
return fillLevel;
}
void sendSensorData(float distance, float fillLevel, float temperature, float humidity, float batteryLevel, float signalStrength) {
if (WiFi.status() == WL_CONNECTED) {
HTTPClient http;
http.begin(serverURL);
http.addHeader("Content-Type", "application/json");
// Create JSON payload
StaticJsonDocument<512> doc;
doc["bin_id"] = BIN_ID;
doc["sensor_id"] = SENSOR_ID;
doc["fill_level"] = fillLevel;
doc["distance_cm"] = distance;
doc["temperature"] = temperature;
doc["humidity"] = humidity;
doc["battery_level"] = batteryLevel;
doc["signal_strength"] = signalStrength;
doc["voltage"] = 3.3;
doc["device_type"] = "wokwi_esp32";
doc["firmware_version"] = "1.0.0";
String jsonString;
serializeJson(doc, jsonString);
Serial.println("📡 Sending data to backend...");
Serial.println("📦 Payload: " + jsonString);
int httpResponseCode = http.POST(jsonString);
if (httpResponseCode > 0) {
String response = http.getString();
Serial.print("✅ HTTP Response: ");
Serial.println(httpResponseCode);
Serial.println("📥 Response: " + response);
} else {
Serial.print("❌ HTTP Error: ");
Serial.println(httpResponseCode);
}
http.end();
} else {
Serial.println("❌ WiFi not connected");
}
}
void updateStatusLED(float fillLevel) {
if (fillLevel >= 90) {
// Critical - Fast blink
for(int i = 0; i < 5; i++) {
digitalWrite(ledPin, HIGH);
delay(100);
digitalWrite(ledPin, LOW);
delay(100);
}
} else if (fillLevel >= 70) {
// Warning - Slow blink
digitalWrite(ledPin, HIGH);
delay(500);
digitalWrite(ledPin, LOW);
delay(500);
} else {
// Normal - Solid on for 1 second
digitalWrite(ledPin, HIGH);
delay(1000);
digitalWrite(ledPin, LOW);
}
}