#define pinArduinoRaccordementSignalSW  2       // La pin PB2 attiny85 recevra la ligne SW de KY-040
#define pinArduinoRaccordementSignalCLK 3       // La pin PB3 attiny85  recevra la ligne CLK de KY-040
#define pinArduinoRaccordementSignalDT  4       // La pin PB4 attiny85  recevra la ligne DT de KY-040

// 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)


void setup() {

    // Initialisation de la liaison série (arduino nano <-> PC)
    Serial.begin(9600);
    Serial.println(F("=============================================================================="));
    Serial.println(F("Exemple   (programme de test Arduino attiny85 <-> module KY-040, utilisant les"));
    Serial.println(F("           interruptions Arduino INT0 et INT1, avec affichage du nombre de"))   ;
    Serial.println(F("           crans parcourus sur l'encodeur, ainsi que le sens de rotation)"))    ;
    Serial.println(F("========================================================================="))    ;
    Serial.println("");

    // Configuration de certaines pins de notre Attiny85 en "entrées" (celles qui recevront les signaux du KY-040)
    pinMode(pinArduinoRaccordementSignalSW, INPUT);         // à remplacer par : pinMode(pinArduinoRaccordementSignalSW, INPUT_PULLUP);
                                                            // si jamais votre module KY-040 n'est pas doté de résistance pull-up, au niveau de SW
    pinMode(pinArduinoRaccordementSignalDT, INPUT);
    pinMode(pinArduinoRaccordementSignalCLK, INPUT);

    // Petite pause pour laisser le temps aux signaux de se stabiliser
    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 = "));
    Serial.println(compteur);

    // Activation d'interruptions sur les lignes CLK et SW
    attachInterrupt(digitalPinToInterrupt(pinArduinoRaccordementSignalCLK), changementDetecteSurLigneCLK, FALLING); // FALLING => détecte tout front descendant
    attachInterrupt(digitalPinToInterrupt(pinArduinoRaccordementSignalSW), changementDetecteSurLigneSW, CHANGE);    // CHANGE => détecte tout changement d'état

}

// =================
// Boucle principale
// =================
void loop() {

    // Boucle infinie ici, qui sera interrompue à chaque nouvelle interruption, et reprise juste après la fin d'exécution de la routine d'interruption

}

// =====================================================
// Routine d'interruption : changementDetecteSurLigneCLK
// =====================================================
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++;

        // Et on affiche ces infos sur le moniteur série
        Serial.print(F("Sens = horaire | Valeur du compteur = "));
        Serial.println(compteur);
    }
    else {
        // CLK est identique à DT => cela veut dire que nous tournons dans le sens antihoraire
        // Alors on décrémente le compteur
        compteur--;

        // Et on affiche ces infos sur le moniteur série
        Serial.print(F("Sens = antihoraire | Valeur du compteur = "));
        Serial.println(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
    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
ATTINY8520PU