#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <ESP32Servo.h>
#include <WiFi.h>
#include <ThingSpeak.h>
// Adresse I2C du LCD
LiquidCrystal_I2C lcd(0x27, 16, 2);
// Configuration des broches
const int ledGreenPin = 2;
const int ledRedPin = 4;
const int buttonPin = 34;
const int irSensorPin = 15; // Capteur IR pour l'entrée des véhicules
const int irExitSensorPin = 32; // Capteur IR pour la sortie des véhicules
const int servoPin = 13; // Broche du moteur de la barrière
// Variables pour le parking
const int totalPlaces = 5; // Nombre total de places
int placesLibres = totalPlaces;
int totalVehicules = 0;
// Servo moteur
Servo barrierServo;
const int servoClosed = 0;
const int servoOpen = 90;
// Wi-Fi
const char* ssid = "Wokwi-GUEST"; // Remplacez par votre réseau Wi-Fi
const char* password = ""; // Remplacez par votre mot de passe Wi-Fi
// ThingSpeak
unsigned long myChannelNumber = 2758637; // Remplacez par l'ID de votre canal
const char* myWriteAPIKey = "O606AMYTBG0NSJI8"; // Remplacez par votre clé API d'écriture
WiFiClient client;
// Données GPS simulées
float latitude = 34.020882; // Exemple de latitude (position fictive)
float longitude = -6.841650; // Exemple de longitude (position fictive)
// Coordonnées des parkings disponibles
float parkingLatitudes[] = {34.021000, 34.022000, 34.023000}; // Latitudes des parkings
float parkingLongitudes[] = {-6.840500, -6.841500, -6.842500}; // Longitudes des parkings
int numParkings = 3; // Nombre de parkings disponibles
// Fonction pour calculer la distance entre deux points GPS
float calculateDistance(float lat1, float lon1, float lat2, float lon2) {
const float R = 6371; // Rayon de la Terre en kilomètres
float dLat = (lat2 - lat1) * (PI / 180.0);
float dLon = (lon2 - lon1) * (PI / 180.0);
float a = sin(dLat / 2) * sin(dLat / 2) +
cos(lat1 * (PI / 180.0)) * cos(lat2 * (PI / 180.0)) *
sin(dLon / 2) * sin(dLon / 2);
float c = 2 * atan2(sqrt(a), sqrt(1 - a));
float distance = R * c; // Distance en kilomètres
return distance;
}
// État du système
bool vehicleDetected = false;
bool barrierOpen = false;
void setup() {
// Configuration des broches
pinMode(ledGreenPin, OUTPUT);
pinMode(ledRedPin, OUTPUT);
pinMode(buttonPin, INPUT_PULLDOWN);
pinMode(irSensorPin, INPUT);
pinMode(irExitSensorPin, INPUT);
// Servo moteur
barrierServo.attach(servoPin);
barrierServo.write(servoClosed);
// LCD
lcd.init();
lcd.backlight();
lcd.print("Parking System");
delay(500);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Places libres:");
lcd.setCursor(0, 1);
lcd.print(placesLibres);
// Série
Serial.begin(15200);
Serial.println("Systeme initialise. Connexion au WiFi...");
// Connexion Wi-Fi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nWiFi connecte.");
// ThingSpeak
ThingSpeak.begin(client);
// Affichage des coordonnées GPS simulées
Serial.println("Coordonnees GPS :");
Serial.print("Latitude : ");
Serial.println(latitude);
Serial.print("Longitude : ");
Serial.println(longitude);
}
void loop() {
// Lecture des capteurs
int irState = digitalRead(irSensorPin); // Détection d'entrée du véhicule
int irExitState = digitalRead(irExitSensorPin); // Détection de sortie du véhicule
// Débogage : Afficher les valeurs des capteurs dans la console
Serial.print("IR Avant: ");
Serial.print(irState);
Serial.print(" | IR Apres: ");
Serial.println(irExitState);
// Calculer la distance vers chaque parking et afficher le plus proche
float closestDistance = 1000000; // Une valeur très grande pour commencer
int closestParkingIndex = -1;
for (int i = 0; i < numParkings; i++) {
float distance = calculateDistance(latitude, longitude, parkingLatitudes[i], parkingLongitudes[i]);
if (distance < closestDistance) {
closestDistance = distance;
closestParkingIndex = i;
}
}
// Afficher le parking le plus proche
Serial.print("Parking le plus proche : ");
Serial.print("Latitude: ");
Serial.print(parkingLatitudes[closestParkingIndex]);
Serial.print(" Longitude: ");
Serial.println(parkingLongitudes[closestParkingIndex]);
// LCD - Afficher le parking le plus proche
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Parking le plus");
lcd.setCursor(0, 1);
lcd.print("proche: " + String(closestParkingIndex + 1));
// Détection d'un véhicule
if (irState == HIGH && placesLibres > 0 && !vehicleDetected && !barrierOpen) {
vehicleDetected = true;
barrierOpen = true;
barrierServo.write(servoOpen); // Ouvre la barrière
Serial.println("Vehicule detecte. Barriere ouverte.");
delay(500); // Temps pour ouvrir la barrière
// Affichage du message "Photo prise!" sur le LCD
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Vehicule arrive");
lcd.setCursor(0, 1);
lcd.print("Photo prise!");
delay(100); // Afficher le message pendant 2 secondes
}
// Passage d'un véhicule
if (barrierOpen && irExitState == HIGH) {
barrierServo.write(servoClosed); // Ferme la barrière
delay(500); // Temps pour fermer la barrière
barrierOpen = false;
vehicleDetected = false;
placesLibres--;
totalVehicules++;
Serial.println("Vehicule passe. Barriere fermee. Places disponibles : " + String(placesLibres));
}
// LEDs
if (placesLibres == 0) {
digitalWrite(ledRedPin, HIGH); // Allumer la LED rouge
digitalWrite(ledGreenPin, LOW); // Éteindre la LED verte
} else {
digitalWrite(ledRedPin, LOW); // Éteindre la LED rouge
digitalWrite(ledGreenPin, HIGH); // Allumer la LED verte
}
// LCD - Affichage des informations sur le parking
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Places libres:");
lcd.print(placesLibres);
lcd.setCursor(0, 1);
lcd.print("Vehicules:");
lcd.print(totalVehicules);
// Ajouter un message si le parking est plein
if (placesLibres == 0) {
lcd.setCursor(0, 0);
lcd.print("Parking PLEIN ");
}
// Affichage des coordonnées GPS sur le moniteur série
Serial.println("Coordonnees GPS actuelles :");
Serial.print("Latitude : ");
Serial.println(latitude);
Serial.print("Longitude : ");
Serial.println(longitude);
// Envoyer des données à ThingSpeak
ThingSpeak.setField(1, placesLibres); // Champ 1 : Places disponibles
ThingSpeak.setField(2, totalVehicules); // Champ 2 : Nombre de véhicules
ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey);
}