#include <WiFi.h>
#include <HTTPClient.h>
#include <DHT.h>
#include <time.h>
// ============ CONFIGURATION WiFi ============
#define WIFI_SSID "Wokwi-GUEST"
#define WIFI_PASSWORD ""
// ============ CONFIGURATION Firebase ============
#define databaseURL "projetiot-bdc80-default-rtdb.europe-west1.firebasedatabase.app"
#define apiKey "AIzaSyD1iS5HvDYLlZ0O4jzqJD0Hc5xOdyrSXLo"
// ============ CONFIGURATION Capteur DHT22 ============
#define DHTPIN 15
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
// ============ CONFIGURATION LEDs ============
#define LED_RED 12
#define LED_ORANGE 27
#define LED_BLUE 26
// ============ VARIABLES GPS (Simulation) ============
float latitude = 36.806389; // Tunis
float longitude = 10.181667;
float altitude = 100.0;
int gpsIndex = 0;
// Parcours GPS simulé (circuit autour de Tunis)
float gpsRoute[][3] = {
{36.806389, 10.181667, 100}, // Point de départ
{36.820000, 10.190000, 105},
{36.835000, 10.195000, 110},
{36.850000, 10.185000, 95}, // Zone dangereuse (simulée)
{36.840000, 10.175000, 90},
{36.825000, 10.170000, 98},
{36.810000, 10.180000, 102}
};
int routeSize = 7;
// ============ VARIABLES ============
float temperature = 0;
float humidity = 0;
unsigned long lastSend = 0;
const long sendInterval = 5000; // 5 secondes
// Variables pour statistiques
float tempMin = 999;
float tempMax = -999;
float humMin = 999;
float humMax = -999;
float tempSum = 0;
float humSum = 0;
int readCount = 0;
// Compteur d'incidents par zone
int dangerZoneCount = 0;
void setup() {
Serial.begin(115200);
// Configuration des LEDs
pinMode(LED_RED, OUTPUT);
pinMode(LED_ORANGE, OUTPUT);
pinMode(LED_BLUE, OUTPUT);
// Test des LEDs
testLEDs();
// Initialisation DHT22
Serial.println("Initialisation DHT22...");
dht.begin();
// Connexion WiFi
connectWiFi();
// Configuration du temps (NTP)
configTime(3600, 0, "pool.ntp.org");
Serial.println("\n========================================");
Serial.println(" SYSTEME DE SUPERVISION VEHICULE");
Serial.println("========================================\n");
}
void loop() {
unsigned long currentMillis = millis();
if (currentMillis - lastSend >= sendInterval) {
lastSend = currentMillis;
// Lecture capteurs
temperature = dht.readTemperature();
humidity = dht.readHumidity();
if (isnan(temperature) || isnan(humidity)) {
Serial.println("✗ Erreur lecture DHT22");
return;
}
// Mise à jour GPS (simulation)
updateGPS();
// Statistiques
updateStatistics(temperature, humidity);
// Affichage
displayData();
// Gestion LEDs
String status = updateLEDs(temperature, humidity);
// Envoi Firebase
if (WiFi.status() == WL_CONNECTED) {
sendToFirebase(temperature, humidity, status);
sendStatisticsToFirebase();
}
}
}
void testLEDs() {
Serial.println("Test des LEDs...");
digitalWrite(LED_RED, HIGH);
delay(300);
digitalWrite(LED_RED, LOW);
digitalWrite(LED_ORANGE, HIGH);
delay(300);
digitalWrite(LED_ORANGE, LOW);
digitalWrite(LED_BLUE, HIGH);
delay(300);
digitalWrite(LED_BLUE, LOW);
Serial.println("✓ LEDs OK\n");
}
void connectWiFi() {
Serial.println("=== Connexion WiFi ===");
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
int attempts = 0;
while (WiFi.status() != WL_CONNECTED && attempts < 20) {
delay(500);
Serial.print(".");
attempts++;
}
if (WiFi.status() == WL_CONNECTED) {
Serial.println("\n✓ WiFi connecté !");
Serial.print("IP : ");
Serial.println(WiFi.localIP());
} else {
Serial.println("\n✗ Échec WiFi");
}
}
void updateGPS() {
// Simulation : parcourir le circuit GPS
latitude = gpsRoute[gpsIndex][0];
longitude = gpsRoute[gpsIndex][1];
altitude = gpsRoute[gpsIndex][2];
gpsIndex = (gpsIndex + 1) % routeSize;
// Zone dangereuse : index 3
if (gpsIndex == 3) {
dangerZoneCount++;
}
}
void updateStatistics(float temp, float hum) {
readCount++;
if (temp < tempMin) tempMin = temp;
if (temp > tempMax) tempMax = temp;
if (hum < humMin) humMin = hum;
if (hum > humMax) humMax = hum;
tempSum += temp;
humSum += hum;
}
void displayData() {
Serial.println("\n╔════════════════════════════════════════╗");
Serial.println("║ DONNÉES EN TEMPS RÉEL ║");
Serial.println("╠════════════════════════════════════════╣");
Serial.printf("║ Température : %6.2f °C ║\n", temperature);
Serial.printf("║ Humidité : %6.2f %% ║\n", humidity);
Serial.printf("║ Latitude : %10.6f ║\n", latitude);
Serial.printf("║ Longitude : %10.6f ║\n", longitude);
Serial.printf("║ Altitude : %6.1f m ║\n", altitude);
Serial.println("╠════════════════════════════════════════╣");
Serial.printf("║ Lectures : %6d ║\n", readCount);
Serial.printf("║ Temp Moy : %6.2f °C ║\n", tempSum / readCount);
Serial.printf("║ Hum Moy : %6.2f %% ║\n", humSum / readCount);
Serial.printf("║ Zone Danger : %6d fois ║\n", dangerZoneCount);
Serial.println("╚════════════════════════════════════════╝");
}
String updateLEDs(float temp, float hum) {
digitalWrite(LED_RED, LOW);
digitalWrite(LED_ORANGE, LOW);
digitalWrite(LED_BLUE, LOW);
String status;
// Zone dangereuse GPS (index 3)
bool inDangerZone = (gpsIndex == 3);
if (temp > 60 || hum > 80 || inDangerZone) {
digitalWrite(LED_RED, HIGH);
status = "DANGER";
Serial.println("🔴 LED ROUGE : DANGER !");
} else if (temp > 40 || hum > 70) {
digitalWrite(LED_ORANGE, HIGH);
status = "ATTENTION";
Serial.println("🟠 LED ORANGE : ATTENTION");
} else {
digitalWrite(LED_BLUE, HIGH);
status = "NORMAL";
Serial.println("🔵 LED BLEUE : NORMAL");
}
return status;
}
String getTimestamp() {
time_t now;
struct tm timeinfo;
if (!getLocalTime(&timeinfo)) {
return String(millis());
}
char buffer[30];
strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", &timeinfo);
return String(buffer);
}
void sendToFirebase(float temp, float hum, String status) {
HTTPClient http;
String timestamp = getTimestamp();
String jsonData = "{";
jsonData += "\"latitude\":\"" + String(latitude, 6) + "\",";
jsonData += "\"longitude\":\"" + String(longitude, 6) + "\",";
jsonData += "\"altitude\":" + String(altitude, 1) + ",";
jsonData += "\"temperature\":" + String(temp, 2) + ",";
jsonData += "\"humidity\":" + String(hum, 2) + ",";
jsonData += "\"timestamp\":\"" + timestamp + "\",";
jsonData += "\"status\":\"" + status + "\",";
if (status == "DANGER") {
jsonData += "\"led\":\"RED\"";
} else if (status == "ATTENTION") {
jsonData += "\"led\":\"ORANGE\"";
} else {
jsonData += "\"led\":\"BLUE\"";
}
jsonData += "}";
// Envoi données actuelles
String url = "https://" + String(databaseURL) + "/vehicules/vehicule1/current.json?auth=" + String(apiKey);
http.begin(url);
http.addHeader("Content-Type", "application/json");
int code = http.PUT(jsonData);
if (code > 0) {
Serial.println("✓ Données envoyées à Firebase (current)");
} else {
Serial.println("✗ Échec envoi current");
}
http.end();
// Ajout à l'historique
url = "https://" + String(databaseURL) + "/vehicules/vehicule1/historique.json?auth=" + String(apiKey);
http.begin(url);
http.addHeader("Content-Type", "application/json");
code = http.POST(jsonData);
if (code > 0) {
Serial.println("✓ Historique mis à jour");
}
http.end();
}
void sendStatisticsToFirebase() {
HTTPClient http;
String jsonStats = "{";
jsonStats += "\"temperature\":{";
jsonStats += "\"min\":" + String(tempMin, 2) + ",";
jsonStats += "\"max\":" + String(tempMax, 2) + ",";
jsonStats += "\"moyenne\":" + String(tempSum / readCount, 2);
jsonStats += "},";
jsonStats += "\"humidity\":{";
jsonStats += "\"min\":" + String(humMin, 2) + ",";
jsonStats += "\"max\":" + String(humMax, 2) + ",";
jsonStats += "\"moyenne\":" + String(humSum / readCount, 2);
jsonStats += "},";
jsonStats += "\"gps\":{";
jsonStats += "\"derniere_latitude\":\"" + String(latitude, 6) + "\",";
jsonStats += "\"derniere_longitude\":\"" + String(longitude, 6) + "\",";
jsonStats += "\"passages_zone_danger\":" + String(dangerZoneCount);
jsonStats += "},";
jsonStats += "\"nbLectures\":" + String(readCount);
jsonStats += "}";
String url = "https://" + String(databaseURL) + "/vehicules/vehicule1/statistiques.json?auth=" + String(apiKey);
http.begin(url);
http.addHeader("Content-Type", "application/json");
int code = http.PUT(jsonStats);
if (code > 0) {
Serial.println("✓ Statistiques envoyées");
}
http.end();
}