/********************************************************************************
 * PN_TIB_Deux_voies.ino                                                        *
 ********************************************************************************
 * Ce programme est dans le domaine public. Il surveille la zone du PN          *
 * Dernière mise a jour : 19 avril 2025                                         *
 * pour deux voies (une verte et une bleue)                                     *
 * Les poussoirs sont les ILS : deux secondes entre chaque appui.               *
 * INITIALISATION VOIE 1 ET VOIE 2 OCCUPEES !!!                                 *
 *******************************************************************************/
 
const byte ILS=2; // Entree pour voie 1
const byte ILS2=3; // Entree pour voie 2
unsigned int compteur = 1;  // compteur d evenements (survol ILS)
unsigned int compteur2 = 1; // compteur d evenements survol ILS2

// Initialisation avec un train sur voie 1 ET voie 2
volatile static boolean etatZonePN = true; 
volatile static bool etatZoneZ1 = true;
volatile static bool etatZoneZ2 = true;
volatile static bool oldetatZoneZ1 = true;
volatile static bool oldetatZoneZ2 = true;

volatile static unsigned long old_top_debutISR;  // Date anterieure d appel ISR
unsigned long old_top = 0;  // variable pour afficher donnees utiles
volatile static unsigned long old_top_debutISR2;  // Date anterieure d appel ISR
unsigned long old_top2 = 0;  // variable pour afficher donnees utiles


void changeEtatZ1() { // routine d'interruption (ISR)
  unsigned long top_debutISR = millis();  // date appel ISR
  if((top_debutISR - old_top_debutISR) > 2000) {
    // 2 secondes au moins entre execution ISR
    etatZoneZ1 = !etatZoneZ1; // etat passe a etat oppose
    old_top_debutISR = top_debutISR;  // initialisation date anterieure d appel ISR
  }
} // fin de ISR

void changeEtatZ2() { // routine d'interruption (ISR)
  unsigned long top_debutISR2 = millis();  // date appel ISR
  if((top_debutISR2 - old_top_debutISR2) > 2000) {
    // 2 secondes au moins entre execution ISR
    etatZoneZ2 = !etatZoneZ2; // etat passe a etat oppose
    old_top_debutISR2 = top_debutISR2;  // initialisation date anterieure d appel ISR
  }
} // fin de ISR

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200); // Communication avec le moniteur
  Serial.println("Voie 1 occupée     Voie 2 occupée");
  pinMode (ILS, INPUT_PULLUP);
  pinMode (LED_BUILTIN, OUTPUT);
  // changeEtat est la routine d'interruption sur l'entree ILS ou ILS2
  // elle est declenchee par un front descendant
  attachInterrupt (digitalPinToInterrupt(ILS), changeEtatZ1, FALLING);
  attachInterrupt (digitalPinToInterrupt(ILS2), changeEtatZ2, FALLING);
  digitalWrite (LED_BUILTIN, LOW);
} // fin de setup

void loop() {
  // put your main code here, to run repeatedly:
  // Traitement des deux zones pour deduire etatZonePN
  if(etatZoneZ1 == false && etatZoneZ2 == false) {
    etatZonePN = false;
  }
  if(etatZoneZ1 == true || etatZoneZ2 == true) {
    etatZonePN = true;
  }
  // traitement de la zone PN
  if(etatZonePN == false) {digitalWrite (LED_BUILTIN, LOW);}
  if(etatZonePN == true) {digitalWrite (LED_BUILTIN, HIGH);}
  // Affichage
  if(etatZoneZ1 != oldetatZoneZ1) {
    if(etatZoneZ1 == true) {
      Serial.print("Voie 1 occupée     ");
    }
    if(etatZoneZ1 == false) {
      Serial.print("Voie 1 libre       ");
    }
    if(etatZoneZ2 == true) {
      Serial.println("Voie 2 occupée");
    }
    if(etatZoneZ2 == false) {
      Serial.println("Voie 2 libre");
    }
    oldetatZoneZ1 = etatZoneZ1;
  }
  if(etatZoneZ2 != oldetatZoneZ2) {
    if(etatZoneZ1 == true) {
      Serial.print("Voie 1 occupée     ");
    }
    if(etatZoneZ1 == false) {
      Serial.print("Voie 1 libre       ");
    }
    if(etatZoneZ2 == true) {
      Serial.println("Voie 2 occupée");
    }
    if(etatZoneZ2 == false) {
      Serial.println("Voie 2 libre");
    }
    oldetatZoneZ2 = etatZoneZ2;
  }
} // fin de loop