// ==========================================================
// SYSTEME DE BLOCK AUTOMATIQUE - 5 CANTONS
// Gestion : 10 ILS, 15 LEDs, 10 Relais (Arrêt & Ralenti)
// ==========================================================
const int NB_CANTONS = 5;
// --- DEFINITION DES PINS ---
// Capteurs ILS
const int pinILS_Entree[NB_CANTONS] = {2, 3, 4, 5, 6}; // Pour passer au ROUGE
const int pinILS_Liberation[NB_CANTONS] = {7, 8, 9, 10, 11}; // Pour libérer le précédent
// Signaux LEDs
const int pinLedV[NB_CANTONS] = {22, 25, 28, 31, 34};
const int pinLedJ[NB_CANTONS] = {23, 26, 29, 32, 35};
const int pinLedR[NB_CANTONS] = {24, 27, 30, 33, 36};
// Relais de Traction
const int pinRelaisArret[NB_CANTONS] = {37, 38, 39, 40, 41}; // Coupure totale
const int pinRelaisRalenti[NB_CANTONS] = {42, 43, 44, 45, 46}; // Passage via résistance
// --- ETATS DU RESEAU ---
bool cantonOccupe[NB_CANTONS] = {false, false, false, false, false};
void setup() {
Serial.begin(9600);
for (int i = 0; i < NB_CANTONS; i++) {
// Entrées capteurs
pinMode(pinILS_Entree[i], INPUT_PULLUP);
pinMode(pinILS_Liberation[i], INPUT_PULLUP);
// Sorties LEDs
pinMode(pinLedV[i], OUTPUT);
pinMode(pinLedJ[i], OUTPUT);
pinMode(pinLedR[i], OUTPUT);
// Sorties Relais
pinMode(pinRelaisArret[i], OUTPUT);
pinMode(pinRelaisRalenti[i], OUTPUT);
// Initialisation : Tout au repos (Courant ON)
digitalWrite(pinRelaisArret[i], LOW);
digitalWrite(pinRelaisRalenti[i], LOW);
}
Serial.println("===========================================");
Serial.println(" BLOCK SYSTEME COMPLET PRET (RELAYS ON) ");
Serial.println("===========================================");
actualiserReseau(); // Allume les feux au vert au départ
}
void loop() {
bool changement = false;
for (int i = 0; i < NB_CANTONS; i++) {
// 1. DETECTION ENTREE : Un train arrive dans le canton i
if (digitalRead(pinILS_Entree[i]) == LOW) {
if (!cantonOccupe[i]) {
cantonOccupe[i] = true;
changement = true;
Serial.print("\n[MOUVEMENT] Train detecte en Canton "); Serial.println(i + 1);
}
delay(50); // Anti-rebond
}
// 2. DETECTION LIBERATION : Un train libère le canton PRECEDENT
if (digitalRead(pinILS_Liberation[i]) == LOW) {
int precedent = (i == 0) ? NB_CANTONS - 1 : i - 1;
if (cantonOccupe[precedent]) {
cantonOccupe[precedent] = false;
changement = true;
Serial.print("\n[MOUVEMENT] Canton "); Serial.print(precedent + 1); Serial.println(" LIBERE");
}
delay(50); // Anti-rebond
}
}
// Si un train a bougé, on met à jour tout le réseau
if (changement) {
actualiserReseau();
}
}
// --- LOGIQUE DE SIGNALISATION ET TRACTION ---
void actualiserReseau() {
Serial.println("--- ETAT DES SIGNAUX ET RELAIS ---");
for (int i = 0; i < NB_CANTONS; i++) {
int suivant = (i + 1) % NB_CANTONS;
Serial.print("Canton "); Serial.print(i + 1); Serial.print(" : ");
if (cantonOccupe[i]) {
// --- ROUGE (Train présent) ---
// Signal : Rouge | Relais : Arrêt ACTIF, Ralenti OFF
setEtatPhysique(i, LOW, LOW, HIGH, HIGH, LOW);
Serial.println("[ROUGE] - Zone ARRET Coupee");
}
else if (cantonOccupe[suivant]) {
// --- JAUNE (Train devant) ---
// Signal : Jaune | Relais : Arrêt OFF, Ralenti ACTIF
setEtatPhysique(i, LOW, HIGH, LOW, LOW, HIGH);
Serial.println("[JAUNE] - Zone RALENTISSEMENT Active");
}
else {
// --- VERT (Voie libre) ---
// Signal : Vert | Relais : Tout OFF (Courant direct)
setEtatPhysique(i, HIGH, LOW, LOW, LOW, LOW);
Serial.println("[VERT] - Pleine Vitesse");
}
}
}
// Fonction utilitaire pour commander toutes les sorties d'un canton d'un coup
void setEtatPhysique(int id, int v, int j, int r, int relA, int relR) {
digitalWrite(pinLedV[id], v);
digitalWrite(pinLedJ[id], j);
digitalWrite(pinLedR[id], r);
digitalWrite(pinRelaisArret[id], relA);
digitalWrite(pinRelaisRalenti[id], relR);
}