Table des matiéres
Do not index
Do not index
Hide CTA
Hide CTA
Objectif
Dans cet épisode je vous explique les mécaniques de fonctionnement d’un codeur rotatif.
Première partie : fondamentaux
Dans la première partie de la vidéo sont exposés les fondamentaux du fonctionnement du codeur rotatif avec l’appui d’illustrations vidéo. Sachant que les codeurs rotatifs varie selon la marque et le fabricant, le premier code source vous aidera à comprendre correctement comment VOTRE codeur rotatif fonctionne afin de pouvoir l’exploiter correctement.
//Déclaration des pins du codeur rotatif
#define pinDT 2
#define pinCLK 3
//Déclaration des pins des 2 LED
#define redLED 9
#define greenLED 10
byte readStateCLK = 0;
byte readStateDT = 0;
byte oldStateCLK = 0;
byte oldStateDT = 0;
int amountCLKHigh = 0;
int amountDTHigh = 0;
char message[50];
void setup() {
//Initialisation de la communication Serie
Serial.begin (9600);
//On declare les Pins du codeur rotatif en ENTREE (INPUT)
pinMode (pinDT, INPUT);
pinMode (pinCLK, INPUT);
//On déclare les 2 LED en SORTIE (OUTPUT)
pinMode (redLED, OUTPUT);
pinMode (greenLED, OUTPUT);
}
void loop() {
//Lecture de l'état de CLK
readStateCLK = digitalRead(pinCLK);
readStateDT = digitalRead(pinDT);
//On allume la LED verte quand CLK est à HIGH
digitalWrite(greenLED, readStateCLK);
//On allume la LED rouge quand DT est à HIGH
digitalWrite(redLED, readStateDT);
//Si CLK ou DT sont constatés differents de leurs états précédents
if(readStateCLK != oldStateCLK || readStateDT != oldStateDT){
//On met a jour les compteurs d'etat de CLK et DT
amountCLKHigh += readStateCLK;
amountDTHigh += readStateDT;
//On compose un message que l'on envoie sur le port serie contenant les differents états de CLK et DT ainsi que leurs compteurs respectifs
sprintf(message, "CLK: %i - DT: %i [TOTAL] CLK: %i - DT: %i", readStateCLK, readStateDT, amountCLKHigh, amountDTHigh);
Serial.println(message);
}
//On remplace les anciens etats de oldStateCLK et oldStateDT par leur derniers états respectifs
oldStateCLK = readStateCLK;
oldStateDT = readStateDT;
}
Seconde partie : Ouverture du coffre virtuel
Dans la seconde partie je simule l’ouverture d’un verrou afin de pleinement exploiter les fonctionnalités du codeur rotatif et passe en revue le code source permettant de simuler une combinaison de coffre-fort.
/*
* Dans ce code source, nous simulons l'ouverture d'un verou à l'aide d'un mot de passe saisi à l'aide d'un codeur rotatif.
* Les mentions de porte ouverte/fermée ou de verou, font réference a une simulation où nous utilisons une LED rouge et verte afin
* de remplacer une porte/verou fermé ou ouvert.
*/
//Déclaration des signatures des fonctions que l'on va utiliser
void handleRotaryEvent(int limitCounterHigh=20, int limitCounterLow=0);
bool checkPushButton();
void checkDoorLocked();
//Déclaration des pins du codeur rotatif
#define pinDT 2
#define pinCLK 3
//Déclaration du pin du boutton poussoir
#define pinPush 4
//Déclaration des 2 LED
#define redLED 9
#define greenLED 10
//Compteur génerale qui évolue en fonction de la position du codeur rotatif
int currentCounter = 0;
//Variable pour la lecture des états du codeur rotatif
byte readStateCLK;
byte readStateDT;
byte oldStateCLK;
int integrity = 0;
int integrityCheck = 1;
//Variable pour la gestion du mot de passe a saisir à l'aide du codeur rotatif
bool attemptInProgress = false;
bool doorLocked = true;
byte currentDigit = 0;
byte numbersLock[] = {4, 13, 10, 5};
byte numbersAttempted[] = {0, 0, 0, 0};
char message[50];
bool eventPushButton = false;
void setup() {
//Initialisation de la communication Serie
Serial.begin (9600);
//On declare les Pins du codeur rotatif en ENTREE (INPUT)
pinMode (pinDT, INPUT);
pinMode (pinCLK, INPUT);
digitalWrite(pinCLK, HIGH);
digitalWrite(pinDT, HIGH);
//On declare le Pin du bouton poussoir en ENTREE (INPUT)
pinMode (pinPush, INPUT);
//On déclare les 2 LED en SORTIE (OUTPUT)
pinMode (redLED, OUTPUT);
pinMode (greenLED, OUTPUT);
//On récupere la situation initiale du codeur rotatif
oldStateCLK = digitalRead(pinCLK);
//On appel la fonction permettant la mise a jour des LED
checkDoorLocked();
}
void loop() {
//Si l'utilisateur n'a pas encore activer le process de saisi du mot de passe et que le verou est toujours fermé
if(!attemptInProgress && doorLocked){
if(checkPushButton()){
attemptInProgress = true;
Serial.println("Listening to user entry...");
}
}
//Si l'utilisateur a commencer la phase de saisi du mot de passe et que le verou est toujours fermé
if(attemptInProgress && doorLocked){
//Appel de la fonction qui permet la gestion des evenements sur le codeur rotatif
handleRotaryEvent();
//Si le boutton poussoir à été appuyé
if(checkPushButton()){
//On indique a l'utilisateur le nombre qui à été saisi et enregistré
sprintf(message, "Digit %i recorded with %i", currentDigit+1, currentCounter);
Serial.println(message);
//On stocke la valeur actuelle du compteur pour ue comparaison future
numbersAttempted[currentDigit] = currentCounter;
//On incremente l'index de stockage
currentDigit++;
//Si l'index de stockage est arrivé à 4 cela indique que la procedure de saisi est terminé
if(currentDigit > 3){
//Boucle qui va permettre la comparaison des 4 nombres saisis par l'utilisateur avec les 4 nombres du mot de passe.
doorLocked = false;
for(byte i = 0; i < 4; i++){
if(numbersLock[i] != numbersAttempted[i]){
doorLocked = true;
}
}
//Si une erreur a été constaté dans la routine précédente, alors on indique l'echec aupres de l'utilisateur
if(doorLocked){
Serial.println("Failed to open the lock");
}
//Dans le cas contraire on indique le succes de l'opération
else{
Serial.println("Succes");
}
//Mise à jour de la LED de couleur
checkDoorLocked();
//Remise a zero des variables servant a l'enregistrement du mot de passe.
attemptInProgress = false;
currentDigit = 0;
currentCounter = 0;
}
}
}
//Si l'utilisateur a ouvert le verou et qu'il rappui sur le bouton poussoir cela va refermer le verou
if(!doorLocked){
if(checkPushButton()){
Serial.println("Closing door");
doorLocked = true;
checkDoorLocked();
}
}
}
//Fonction permettant de capter la pression sur un bouton poussoir
//Mais uniquement lors du relachement du bouton.
//Cela permet un appuie long sur le bouton poussoir sans craindre la répétition d'une detection multiple
bool checkPushButton(){
if(eventPushButton){
if(!digitalRead(pinPush)){
return false;
}
else{
eventPushButton = false;
return true;
}
}
else if(!digitalRead(pinPush)){
eventPushButton = true;
return false;
}
return false;
}
//Fonction qui sert a controller et comprendre les actions qui surviennent sur le codeur rotatif.
void handleRotaryEvent(int limitCounterHigh=20, int limitCounterLow=0){
//Lecture de l'état de CLK
readStateCLK = digitalRead(pinCLK);
//Si CLK est different de son état précédent
if(readStateCLK != oldStateCLK){
//On ajoute a integrity la valeur de integrityCheck (qui est soit égal à 1 ou -1)
integrity += integrityCheck;
//On inverse integrityCheck. 1 devient -1 et vice versa
integrityCheck *= (-1);
//Si integrity est égal à 1
if(integrity){
//On lis cette fois le pin DT
readStateDT = digitalRead(pinDT);
//Si DT est à 1
if(readStateDT){
//On est dans le cas de tourner dans le sens des aiguilles d'une montre
//On incremente le compteur générale
currentCounter ++;
//Parti qui permet de limiter le compteur sur une limite haute indepassable
if(currentCounter > limitCounterHigh){
currentCounter = limitCounterHigh;
}
}
else{
//On est dans le cas de tourner dans le sens contraire des aiguilles d'une montre
//On décrémente le compteur générale
currentCounter --;
//Parti qui permet de limiter le compteur sur une limite basse indepassable
if(currentCounter < limitCounterLow){
currentCounter = limitCounterLow;
}
}
//On affiche le compteur
Serial.println(currentCounter);
}
}
//On remplace l'ancien etat de oldStateCLK par le dernier état de CLK
oldStateCLK = readStateCLK;
}
//Fonction qui permet en fonction de l'etat de la variable doorLocked de mettre a jour l'etat des LED rouge et verte.
void checkDoorLocked(){
if(doorLocked){
digitalWrite(redLED, HIGH);
digitalWrite(greenLED, LOW);
}
else{
digitalWrite(redLED, LOW);
digitalWrite(greenLED, HIGH);
}
}