#include <ESP32Servo.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// LCD I2C : adresse 0x27, écran 16 colonnes, 2 lignes
LiquidCrystal_I2C lcd(0x27, 16, 2);
// Capteurs PIR pour les places
const int pirPins[4] = {23, 32, 33, 19};
bool placeOccupee[4];
unsigned long derniereDetection[4] = {0, 0, 0, 0};
const unsigned long dureeOccupation = 10000; // 10 secondes
// Capteurs ultrason entrée/sortie
const int trigPinEntree = 16;
const int echoPinEntree = 17;
const int trigPinSortie = 15;
const int echoPinSortie = 2;
// Servo barrière
Servo barriere;
const int servoPin = 13;
// LEDs état barrière
const int ledGreenPin = 4;
const int ledRedPin = 0;
// Fonction de détection fiable PIR
bool detecteMouvementStable(int pin) {
int detections = 0;
for (int i = 0; i < 5; i++) {
if (digitalRead(pin)) detections++;
delay(50);
}
return detections >= 3;
}
// Fonction de mesure de distance ultrason
float mesurerDistance(int trig, int echo) {
digitalWrite(trig, LOW); delayMicroseconds(2);
digitalWrite(trig, HIGH); delayMicroseconds(10);
digitalWrite(trig, LOW);
long duree = pulseIn(echo, HIGH);
return duree * 0.034 / 2;
}
// Ouvrir barrière et gérer LEDs
void ouvrirBarriere() {
barriere.write(90);
digitalWrite(ledGreenPin, HIGH);
digitalWrite(ledRedPin, LOW);
delay(4000);
barriere.write(0);
digitalWrite(ledGreenPin, LOW);
digitalWrite(ledRedPin, HIGH);
}
void setup() {
Serial.begin(115200);
for (int i = 0; i < 4; i++) pinMode(pirPins[i], INPUT);
pinMode(trigPinEntree, OUTPUT); pinMode(echoPinEntree, INPUT);
pinMode(trigPinSortie, OUTPUT); pinMode(echoPinSortie, INPUT);
pinMode(ledGreenPin, OUTPUT); pinMode(ledRedPin, OUTPUT);
barriere.setPeriodHertz(50);
barriere.attach(servoPin, 500, 2400);
barriere.write(0); // Barrière fermée
digitalWrite(ledRedPin, HIGH); // LED rouge allumée (barrière fermée)
digitalWrite(ledGreenPin, LOW);
lcd.init(); lcd.backlight(); lcd.clear();
lcd.setCursor(0, 0); lcd.print("Smart Parking");
delay(2000);
}
void loop() {
int placesLibres = 0;
unsigned long tempsActuel = millis();
for (int i = 0; i < 4; i++) {
if (detecteMouvementStable(pirPins[i])) {
derniereDetection[i] = tempsActuel;
placeOccupee[i] = true;
} else if (tempsActuel - derniereDetection[i] > dureeOccupation) {
placeOccupee[i] = false;
}
if (!placeOccupee[i]) placesLibres++;
}
lcd.clear();
lcd.setCursor(0, 0);
if (placesLibres == 0) {
lcd.print("Parking is full");
} else {
lcd.print("Places libres:");
lcd.setCursor(0, 1);
lcd.print(placesLibres);
lcd.print(" / 4");
}
float distanceEntree = mesurerDistance(trigPinEntree, echoPinEntree);
if (distanceEntree > 0 && distanceEntree < 20 && placesLibres > 0) {
ouvrirBarriere();
}
float distanceSortie = mesurerDistance(trigPinSortie, echoPinSortie);
if (distanceSortie > 0 && distanceSortie < 20) {
ouvrirBarriere();
}
delay(1000);
}