// Lycée PE MARTIN
// Le 6/12/2023
// Titre : Portes coulissantes
// Matériels : Arduino Uno, lcd 2x16 I2C, codeur
// Description : voir le sujet
// Ressources
// bibliothèque : https://www.arduino.cc/reference/en/libraries/liquidcrystal/

// Bibliothèque
#include <LiquidCrystal_I2C.h>

// Paramètres de l'objet lcd
#define I2C_ADDR    0x27
#define LCD_COLUMNS 16
#define LCD_LINES   2

// Codeur
#define CODEUR_CLK 2
#define CODEUR_DT  3
#define CODEUR_SW  4

// Création de l'objet lcd
LiquidCrystal_I2C lcd(I2C_ADDR, LCD_COLUMNS, LCD_LINES);

// Variables globales
... compteur = 0;
... sens = LOW; // LOW ou HIGH
... position_1 = 0.0, position = 1.0;

void setup() {
  // Configuration des broches du codeur
  pinMode(CODEUR_CLK, ...);
  pinMode(CODEUR_DT, ...);
  pinMode(CODEUR_SW, ...);

  // Déclaration du gestionnaire d'interruption
  attachInterrupt(digitalPinToInterrupt(CODEUR_CLK), lectureCodeur, FALLING);

  // Initialisation du LCD
  lcd.init(); // A placer en premier
  lcd.backlight(); // Commande du rétroéclairage
  lcd.print("Portes");
  lcd.setCursor(4, 1);
  lcd.print("Coulissantes");
  delay(3000);
  lcd.clear();
  lcd.print("Compteur:0");
}

// Sous-programme (service)d'interruption
// Déclenché par un front descendant du signal ???
// On incrémentera et décrémentera le compteur par 1000 pour avoir des
// résultats réalistes en cm
void lectureCodeur() {
  bool etatLogiqueCODEUR_DT = ...(CODEUR_DT); // Lecture du signal DT
  if (etatLogiqueCODEUR_DT == HIGH) { // si Rotation Horaire alors
    compteur = compteur ....; // Incrémentation de compteur
    sens = ...;
  }
  else { // si Rotation Anti-Horaire alors
    compteur = compteur ....; // Décrémentation de compteur
    sens = ...;
  }
}

// Sous-programmes et fonctions
//-----------------------------------------------------------
// Lecture de la variable compteur, désactivation des interruptions.
// Ainsi, on est sûr que la valeur contenue dans compteur
// ne changera pas pendant qu'on la lit.
int lireCompteur() {
  int valeurCompteur;
  noInterrupts(); // début protection de la variable compteur
  ...;
  interrupts(); // fin protection de la variable compteur
  return valeurCompteur;
}

int lireSens() {
  // A compléter
}

void razCompteur() {
  noInterrupts();
  ...;
  interrupts();
}

// Programme principal
void loop() {
  // Calcul de la position des portes en cm
  position = ... * lireCompteur(); // en cm

  // Affichage
  if (position != position_1) {
    // A compléter
    ...

    lcd.setCursor(13, 1);
    if (position == 0) {
      lcd.print("   ");
    }
    else {
      if (sens) {
        lcd.print("Ouv");
      }
      else {
        lcd.print("Frm");
      }
    }
    position_1 = position;
  }

  if (digitalRead(CODEUR_SW) == LOW) {
    razCompteur();
  }
}
Codeur incrémental
R1
R2
PORTES COULISSANTES