Site icon AranaCorp

Gestion de plusieurs capteurs avec un registre à décalage

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

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.

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

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

Sources

Retrouvez nos tutoriels et d’autres exemples dans notre générateur automatique de code
La Programmerie

Quitter la version mobile