// Problem with KY040 AND LCD Display
// https://forum.arduino.cc/t/problem-with-ky040-and-lcd-display/1353594
/*
minuterie exposition tubes uv pour procédés photographique
*/
// #include <Wire.h>
#include <LiquidCrystal_I2C.h>
#define pinArduinoRaccordementSignalSW 2 // La pin D2 de l'Arduino recevra la ligne SW du module KY-040
#define pinArduinoRaccordementSignalCLK 3 // La pin D3 de l'Arduino recevra la ligne CLK du module KY-040
#define pinArduinoRaccordementSignalDT 4 // La pin D4 de l'Arduino recevra la ligne D
#define MAX_Process 20 // nombre de procédés différents
int Program_index = 0 ;
char description [20][35] = {"Cyanotype", "Van Dijck Brown",
"Gomme bichromatée", "Puretch trame", "Puretch image", "Tok solar trame",
"Tok solar image", "Film ..... trame", "Film ...... image",
"Plaque verte trame", "Plaque verte image", "12", "13", "14", "15", "16", "17", "18", "19", "20"
}; // nom du procédé
int exposition6 [20] = {101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119}; //exposition led 625nm en secondes
int exposition8 [20] = {21, 22, 3, 14, 125, 16, 37, 18, 109, 10, 21, 32, 43, 74, 65, 26, 77, 48, 29}; //exposition led 815nm en secondes
// Variables
int etatPrecedentLigneSW; // Cette variable nous permettra de stocker le dernier état de la ligne SW, afin de le comparer à l'actuel
int compteur = 0; // Cette variable nous permettra de compter combien de crans ont été parcourus, sur l'encodeur
// (sachant que nous compterons dans le sens horaire, et décompterons dans le sens antihoraire)
LiquidCrystal_I2C lcd(0x27, 20, 4);
void setup ()
{
lcd.init();
lcd.backlight();
pinMode(pinArduinoRaccordementSignalSW, INPUT);
pinMode(pinArduinoRaccordementSignalDT, INPUT);
pinMode(pinArduinoRaccordementSignalCLK, INPUT);
Serial.begin(115200); // test à supprimer
Serial.println(F("==========================================================================")); //test à supprimer
Serial.println(F(" interruptions Arduino INT0 et INT1, avec affichage du nombre de")); //test à supprimer
Serial.println(F(" crans parcourus sur l'encodeur, ainsi que le sens de rotation)")); //test à supprimer
Serial.println(F("=========================================================================")); //test à supprimer
Serial.println(F("=========================================================================")); //test à supprimer
Serial.println(F("=========================================================================")); //test à supprimer
Serial.println(""); //test à supprimer
delay(200);
// Mémorisation de la valeur initiale de la ligne SW, au démarrage du programme
etatPrecedentLigneSW = digitalRead(pinArduinoRaccordementSignalSW);
// Affichage de la valeur initiale du compteur, sur le moniteur série
Serial.print(F("Valeur initiale du compteur = ")); //test à supprimer
Serial.println(compteur); //test à supprimer
attachInterrupt(digitalPinToInterrupt(pinArduinoRaccordementSignalCLK), changementDetecteSurLigneCLK, FALLING); // FALLING => détecte tout front descendant
attachInterrupt(digitalPinToInterrupt(pinArduinoRaccordementSignalSW), changementDetecteSurLigneSW, CHANGE); // CHANGE => détecte tout changement d'état
lcd.setCursor(0, 3);
lcd.print("test lcd");
}
void loop() {
// put your main code here, to run repeatedly:
// POUR PREMIERS TESTS
}
void eff_ligne (int ligne)
{
lcd.setCursor(0, ligne - 1);
lcd.print( " ");
}
void affiche_lcd(int index) {
eff_ligne(1);
eff_ligne(2);
eff_ligne(3);
lcd.setCursor(0, 0);
lcd.print(description[index]);
}
void changementDetecteSurLigneCLK() {
// Lecture de la ligne DT, issue du KY-040, et arrivant sur l'arduino
int etatActuelDeLaLigneDT = digitalRead(pinArduinoRaccordementSignalDT);
int etatActuelDeLaLigneCLK = LOW;
// Nota : ici, la ligne CLK est forcément au niveau bas (0V), du fait qu'on entre dans cette routine
// que sur front descendant de CLK (donc passage de 1 à 0)
// On compare ensuite l'état des lignes CLK et DT
// ----------------------------------------------
// Nota : - si CLK est différent de DT, alors cela signifie que nous avons tourné l'encodeur dans le sens horaire
// - si CLK est égal à DT, alors cela signifie que nous avons tourné l'encodeur dans le sens antihoraire
if (etatActuelDeLaLigneCLK != etatActuelDeLaLigneDT) {
// CLK différent de DT => cela veut dire que nous tournons dans le sens horaire
// Alors on incrémente le compteur
compteur++;
if (compteur > (MAX_Process - 1)) {
compteur = 0;
}
// Et on affiche ces infos sur le moniteur série
interrupts();
Serial.print(F("Sens = horaire | Valeur du compteur = "));
}
else {
// CLK est identique à DT => cela veut dire que nous tournons dans le sens antihoraire
// Alors on décrémente le compteur
compteur--;
if (compteur < 0 ) {
compteur = MAX_Process - 1;
}
// Et on affiche ces infos sur le moniteur série
interrupts();
Serial.print(F("Sens = antihoraire | Valeur du compteur = "));
}
Serial.println(compteur);
Serial.println(description[compteur]);
affiche_lcd(compteur);
}
// ====================================================
// Routine d'interruption : changementDetecteSurLigneSW
// ====================================================
void changementDetecteSurLigneSW() {
// On lit le nouvel état de la ligne SW
int etatActuelDeLaLigneSW = digitalRead(pinArduinoRaccordementSignalSW);
// On mémorise le nouvel état de la ligne SW, puisqu'il vient de changer (sans quoi nous ne serions pas dans cette routine d'interruption)
etatPrecedentLigneSW = etatActuelDeLaLigneSW;
// Puis on affiche le nouvel état de SW sur le moniteur série de l'IDE Arduino
interrupts();
if (etatActuelDeLaLigneSW == LOW)
Serial.println(F("Bouton SW appuyé"));
else
Serial.println(F("Bouton SW relâché"));
}
// Nota : en pratique, sans "filtre anti-rebond", vous noterez qu'il y a parfois pas mal de comptes/décomptes non souhaités, en l'état