Dans ce tutoriel, nous allons voir comment gérer plusieurs capteurs avec un registre à décalage. Nous avons vu dans le dernier tutoriel sur le sujet, que le registre pouvait servir à piloter des LEDs. Nous allons voir ici, comment lire la valeur de 8 capteurs sur une seule entrée analogique. En électronique, le nombre d’entrées-sorties devient critique lorsqu’on utilise plusieurs capteurs. L’utilisation d’un registre à décalage est une bonne solution pour diminuer le nombre de broches utilisées.
Dans cet article, nous utilisons le registre à décalage 74HC595 mais il est possible d’utiliser un multiplexeur ou un 74HC165 (Parallèle vers série, plus adapter pour la lecture de capteur)
Matériel
- Ordinateur
- Arduino UNO
- Câble USB A Mâle/B Mâle
- Shift Register 74HC595
Principe de fonctionnement
Le registre à décalage (ou shift register) est un composant électronique contenant des bascules synchrones. Ce sont des circuits logiques qui gardent en mémoire un état haut ou bas (comme un bit) relié par une même horloge. Le principe de décalage vient du fait que l’on vient écrire ou lire dans chaque mémoire bit par bit.
Pour gérer des capteurs, nous allons utiliser la sortie du registre à décalage comme source de tension et toute les sorties capteurs seront reliées à une entrée analogique de l’Arduino. Les capteurs seront alimentés les uns après les autres ce qui nous permettra de récupérer, sur la broche analogique, la valeur du capteur alimenté.
Schéma
Le registre à décalage nécessite 3 broches de sortie d’un microcontrôleur. Il est possible de gérer plusieurs registres montés en série.
- GND masse du circuit intégré
- Vcc broche d’alimentation. Généralement connecté à 5V
- SH_CP ou RCLK shift register clock input. Le signal d’horloge du registre qui détermine si on écrit dans la mémoire
- ST_CP ou SRCLK storage register clock input. Le signal d’horloge de stockage qui définit dans quel mémoire on vient lire ou écrire.
- DS ou SER serial data input. Signal contenant la données à enregistrer (HAUT ou BAS)
- Q0-Q7 parallel data output. Broches de sorties du registre à décalage
- OE Output enable, active LOW. Broche connectée à GND pour activer les sorties
- MR Master reset, active LOW. Broche de remise à zéro. Connectée au 5V
- Q7′ serial data output (broche utilisée seulement si plusieurs registres sont montés en série)
Une fois le registre à décalage branché correctement, nous allons connecter chacun des boutons. Pour pouvoir détecter l’état de plusieurs boutons, il faut rajouter une diode à chaque sortie afin que le courant ne passe pas d’une sortie à l’autre du registre à décalage.
Code
Pour communiquer avec le registre à décalage, nous allons jongler avec ses broches d’entrée. Il faut mettre la broche RCLK à bas pour écrire dans un registre. Pour écrire dans les bascules, il faut passer l’horloge de stockage à bas. A chaque impulsion d’horloge, on passe à la bascule suivante. Pour simplifier notre code, nous allons définir cette procédure dans la fonction writeRegister().
Pour gérer le groupe de capteur à travers le registre, nous allons envoyer des impulsions sur chaque bascule et lire la valeur du bouton lorsque la bascule est à l’état haut, c’est-à-dire, qu’un courant passe dans le bouton.
//Constants #define number_of_74hc595s 1 #define numOfRegisterPins number_of_74hc595s * 8 #define SER_Pin 2 #define RCLK_Pin 3 #define SRCLK_Pin 4 //Parameters const int grpBtnPin = A0; //Variables boolean registers[numOfRegisterPins] = {0, 0, 0, 0, 0, 0, 0, 0}; boolean grpBtnState[numOfRegisterPins] = {0, 0, 0, 0, 0, 0, 0, 0}; boolean oldGrpBtnState[numOfRegisterPins] = {0, 0, 0, 0, 0, 0, 0, 0}; int grpBtnVal[numOfRegisterPins] = {0, 0, 0, 0, 0, 0, 0, 0}; void setup() { //Init Serial USB Serial.begin(9600); Serial.println(F("Initialize System")); //Init register pinMode(SER_Pin, OUTPUT); pinMode(RCLK_Pin, OUTPUT); pinMode(SRCLK_Pin, OUTPUT); pinMode(grpBtnPin, INPUT); } void loop() { readGrpBtn(); } void clearRegisters() { /* function clearRegisters */ //// Clear registers variables for (int i = numOfRegisterPins - 1; i >= 0; i--) { registers[i] = LOW; } } void writeRegisters() { /* function writeRegisters */ //// Write register after being set digitalWrite(RCLK_Pin, LOW); for (int i = numOfRegisterPins - 1; i >= 0; i--) { digitalWrite(SRCLK_Pin, LOW); int val = registers[i]; digitalWrite(SER_Pin, val); digitalWrite(SRCLK_Pin, HIGH); } digitalWrite(RCLK_Pin, HIGH); } void setRegisterPin(int index, int value) { /* function setRegisterPin */ ////Set register variable to HIGH or LOW registers[index] = value; } void readGrpBtn() { /* function readGrpBtn */ //// Read each btn for (int i = numOfRegisterPins - 1; i >= 0; i--) { grpBtnState[i] = false; setRegisterPin(i, HIGH); writeRegisters(); delay(20); grpBtnVal[i] = analogRead(grpBtnPin); setRegisterPin(i, LOW); writeRegisters(); if (grpBtnVal[i] > 500) { grpBtnState[i] = true; if (oldGrpBtnState[i] != grpBtnState[i]) { Serial.print(F("Btn ")); Serial.print(i); Serial.print(F(" detected -> State = ")); Serial.println(grpBtnVal[i]); } } } }
Résultats
L’état du bouton est actualisé à chaque passage par la mémoire du registre correspondante et il nous est possible de lire 8 boutons à l’aide d’une seule entrée analogique.
Applications
- Gérer jusqu’à 8 capteurs avec trois broches digitales et une broche analogique d’un microcontrôleur
- Créer un périphérique HID avec plusieurs touches
Retrouvez notre module d’extension à registre à décalage avec une connectique simplifiée, compatible avec tout type de microcontrôleurs (Arduino, ESP8266, ESP32, Raspberry Pi etc.)
-
AC SRx2 Module14,00€
Sources
- https://fr.wikipedia.org/wiki/Registre_%C3%A0_d%C3%A9calage
- https://fr.wikipedia.org/wiki/Bascule_(circuit_logique)
- Utilisation d’un registre à décalage
- Utilisation d’un Multiplexeur
Retrouvez nos tutoriels et d’autres exemples dans notre générateur automatique de code
La Programmerie
Petite erreur dans le schéma de câblage : le fil bleu du bouton de gauche n’est pas relié.
merci!