// 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
int compteur = 0;
bool sens = LOW;  // LOW ou HIGH
float position_1 = 0.0, position = 1.0;

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

  // 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 A
void lectureCodeur() {
  bool etatLogiqueCODEUR_DT = digitalRead(CODEUR_DT); // Lecture du signal DT
  if (etatLogiqueCODEUR_DT == HIGH) { // si Rotation Horaire alors
    compteur = compteur + 1000; // Incrémentation compteur
    sens = HIGH;
  }
  else { // si Rotation Anti-Horaire alors
    compteur = compteur - 1000; // Décrémentation compteur
    sens = LOW;
  }
}

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

int lireSens() {
  int valeurSens;
  noInterrupts(); // début protection du compteur
  valeurSens = sens;
  interrupts(); // fin protection du compteur
  return valeurSens;
}

void razCompteur() {
  noInterrupts();
  compteur = 0;
  interrupts();
}

void loop() {
  // Calcul de la position en cm
  position = 0.00248 * lireCompteur(); // en cm

  // Affichage
  if (position != position_1) {
    lcd.clear();
    lcd.print("Compteur:");
    lcd.setCursor(9, 0);
    lcd.print(lireCompteur());
    lcd.setCursor(0, 1);
    lcd.print("Pos:"); lcd.print(position); lcd.print("cm");
    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();
  }
}
uno:A5.2
uno:A4.2
uno:AREF
uno:GND.1
uno:13
uno:12
uno:11
uno:10
uno:9
uno:8
uno:7
uno:6
uno:5
uno:4
uno:3
uno:2
uno:1
uno:0
uno:IOREF
uno:RESET
uno:3.3V
uno:5V
uno:GND.2
uno:GND.3
uno:VIN
uno:A0
uno:A1
uno:A2
uno:A3
uno:A4
uno:A5
lcd1:GND
lcd1:VCC
lcd1:SDA
lcd1:SCL
encoder1:CLK
encoder1:DT
encoder1:SW
encoder1:VCC
encoder1:GND
gnd1:GND
gnd2:GND
vcc1:VCC
vcc2:VCC
vcc3:VCC
gnd3:GND
Codeur incrémental
R1
R2
PORTES COULISSANTES
r1:1
r1:2
r2:1
r2:2
vcc4:VCC