#include <Wire.
h>
#include <LiquidCrystal_I2C.h> // Correction du nom de la bibliothèque
// Configuration de l'écran LCD
LiquidCrystal_I2C lcd(0x27, 20, 4); // Adresse I2C standard 0x27
// Broches capteurs (potentiomètres)
const int capteurV1 = A0;
const int capteurV2 = A1;
const int capteurV3 = A2;
const int capteurV4 = A3;
// Broches électrovannes (UP / DOWN)
const int EV1_Up = 2; const int EV1_Down = 6;
const int EV2_Up = 3; const int EV2_Down = 7;
const int EV3_Up = 4; const int EV3_Down = 8;
const int EV4_Up = 5; const int EV4_Down = 9;
// Broches boutons de commande
const int BP_Monte = 10;
const int BP_Descend = 11;
const int BP_Stop = 12;
const int BP_Urgence = 13; // Bouton d'arrêt d'urgence
// Variables
float hV1, hV2, hV3, hV4;
float moyenneHauteur;
bool systemeActif = false;
volatile bool urgenceActive = false;
int mode = 0; // 0=Stop, 1=Monte, -1=Descend
// Constantes système
const float hauteurMax = 20.0;
const float tolerance = 0.2;
const float ecartMax = 1.0;
const float seuilSurcharge = 18.0;
// Variables pour anti-rebond manuel
unsigned long dernierChangementBouton = 0;
const unsigned long delaiAntiRebond = 50;
void setup() {
[Link](9600);
// Initialisation LCD
[Link]();
[Link]();
[Link](0,0); [Link]("SYSTEME LEVAGE CAMRAIL");
[Link](0,1); [Link](" INITIALISATION... ");
delay(2000);
[Link]();
// Déclaration sorties EV
pinMode(EV1_Up, OUTPUT); pinMode(EV1_Down, OUTPUT);
pinMode(EV2_Up, OUTPUT); pinMode(EV2_Down, OUTPUT);
pinMode(EV3_Up, OUTPUT); pinMode(EV3_Down, OUTPUT);
pinMode(EV4_Up, OUTPUT); pinMode(EV4_Down, OUTPUT);
arreterTousVerins();
// Déclaration boutons
pinMode(BP_Monte, INPUT_PULLUP);
pinMode(BP_Descend, INPUT_PULLUP);
pinMode(BP_Stop, INPUT_PULLUP);
pinMode(BP_Urgence, INPUT_PULLUP);
// Interruption pour arrêt d'urgence hardware
attachInterrupt(digitalPinToInterrupt(BP_Urgence), arretUrgence, FALLING);
// Séquence d'auto-test
autoTestSysteme();
void loop() {
if (urgenceActive) {
gestionUrgence();
return;
}
// Lecture boutons avec anti-rebond manuel
lireBoutons();
// Lecture capteurs
lireCapteurs();
// Calcul moyenne
moyenneHauteur = (hV1 + hV2 + hV3 + hV4) / 4.0;
// Affichage LCD
afficherDonnees();
// Vérification sécurité
if (verifierSecurite()) {
return;
// Commande des vérins selon mode
if (systemeActif) {
if (mode == 1) {
controleMontee();
} else if (mode == -1) {
controleDescente();
delay(100);
// Fonction d'interruption pour arrêt d'urgence
void arretUrgence() {
urgenceActive = true;
void gestionUrgence() {
arreterTousVerins();
[Link]();
[Link](0,0); [Link]("*** ARRET URGENCE ***");
[Link](0,1); [Link](" BP Urgence Active ");
[Link](0,2); [Link]("Appuyez sur STOP pour");
[Link](0,3); [Link](" réinitialiser ");
// Attente de réinitialisation
if (digitalRead(BP_Stop) == LOW) {
delay(50);
if (digitalRead(BP_Stop) == LOW) {
urgenceActive = false;
[Link]();
}
void lireBoutons() {
unsigned long tempsActuel = millis();
if (tempsActuel - dernierChangementBouton > delaiAntiRebond) {
if (digitalRead(BP_Monte) == LOW) {
mode = 1;
systemeActif = true;
[Link]();
dernierChangementBouton = tempsActuel;
if (digitalRead(BP_Descend) == LOW) {
mode = -1;
systemeActif = true;
[Link]();
dernierChangementBouton = tempsActuel;
}
if (digitalRead(BP_Stop) == LOW) {
mode = 0;
systemeActif = false;
arreterTousVerins();
[Link]();
dernierChangementBouton = tempsActuel;
void lireCapteurs() {
hV1 = analogRead(capteurV1) * (hauteurMax / 1023.0);
hV2 = analogRead(capteurV2) * (hauteurMax / 1023.0);
hV3 = analogRead(capteurV3) * (hauteurMax / 1023.0);
hV4 = analogRead(capteurV4) * (hauteurMax / 1023.0);
}
void afficherDonnees() {
// Ligne 1: Vérins 1 et 2
[Link](0,0); [Link]("V1:"); [Link](hV1,1); [Link]("m ");
[Link](10,0); [Link]("V2:"); [Link](hV2,1); [Link]("m ");
// Ligne 2: Vérins 3 et 4
[Link](0,1); [Link]("V3:"); [Link](hV3,1); [Link]("m ");
[Link](10,1); [Link]("V4:"); [Link](hV4,1); [Link]("m ");
// Ligne 3: Moyenne et Mode
[Link](0,2); [Link]("Moy:"); [Link](moyenneHauteur,1); [Link]("m ");
[Link](12,2);
if (mode == 1) [Link]("MONT");
else if (mode == -1) [Link]("DESC");
else [Link]("STOP");
// Ligne 4: Statut système
[Link](0,3);
if (urgenceActive) {
[Link]("URGENCE ACTIVE!");
} else if (systemeActif) {
[Link]("SYSTEME ACTIF ");
} else {
[Link]("SYSTEME ARRETE");
bool verifierSecurite() {
float hMax = max(max(hV1, hV2), max(hV3, hV4));
float hMin = min(min(hV1, hV2), min(hV3, hV4));
// Détection désynchronisation
if ((hMax - hMin) > ecartMax) {
arreterTousVerins();
systemeActif = false;
[Link](0,3); [Link]("ALARME: DESYNCHRO!");
delay(2000);
[Link]();
return true;
// Détection surcharge
if (hMax > seuilSurcharge) {
arreterTousVerins();
systemeActif = false;
[Link](0,3); [Link]("ALARME: SURCHARGE!");
delay(2000);
[Link]();
return true;
return false;
void controleMontee() {
reglerVerin(EV1_Up, EV1_Down, hV1, moyenneHauteur);
reglerVerin(EV2_Up, EV2_Down, hV2, moyenneHauteur);
reglerVerin(EV3_Up, EV3_Down, hV3, moyenneHauteur);
reglerVerin(EV4_Up, EV4_Down, hV4, moyenneHauteur);
void controleDescente() {
reglerVerinDescente(EV1_Up, EV1_Down, hV1, moyenneHauteur);
reglerVerinDescente(EV2_Up, EV2_Down, hV2, moyenneHauteur);
reglerVerinDescente(EV3_Up, EV3_Down, hV3, moyenneHauteur);
reglerVerinDescente(EV4_Up, EV4_Down, hV4, moyenneHauteur);
void reglerVerin(int EV_Up, int EV_Down, float h, float ref) {
if (h < (ref - tolerance)) {
digitalWrite(EV_Up, HIGH);
digitalWrite(EV_Down, LOW);
} else {
digitalWrite(EV_Up, LOW);
digitalWrite(EV_Down, LOW);
void reglerVerinDescente(int EV_Up, int EV_Down, float h, float ref) {
if (h > (ref + tolerance)) {
digitalWrite(EV_Down, HIGH);
digitalWrite(EV_Up, LOW);
} else {
digitalWrite(EV_Down, LOW);
digitalWrite(EV_Up, LOW);
void arreterTousVerins() {
digitalWrite(EV1_Up, LOW); digitalWrite(EV1_Down, LOW);
digitalWrite(EV2_Up, LOW); digitalWrite(EV2_Down, LOW);
digitalWrite(EV3_Up, LOW); digitalWrite(EV3_Down, LOW);
digitalWrite(EV4_Up, LOW); digitalWrite(EV4_Down, LOW);
void autoTestSysteme() {
[Link]();
[Link](0,0); [Link]("AUTO-TEST EN COURS");
// Test affichage
[Link](0,1); [Link]("Test capteurs...");
delay(1000);
// Test brief des LEDs
[Link](0,2); [Link]("Test moteurs...");
testElectrovannes();
[Link](0,3); [Link]("Auto-test OK! ");
delay(1000);
[Link]();
void testElectrovannes() {
// Test brief de chaque électrovanne
digitalWrite(EV1_Up, HIGH); delay(200);
digitalWrite(EV1_Up, LOW); delay(200);
digitalWrite(EV2_Up, HIGH); delay(200);
digitalWrite(EV2_Up, LOW); delay(200);
digitalWrite(EV3_Up, HIGH); delay(200);
digitalWrite(EV3_Up, LOW); delay(200);
digitalWrite(EV4_Up, HIGH); delay(200);
digitalWrite(EV4_Up, LOW);