Augmenter le nbre de sorties avec 74HC595N - Part I

Description 74HC595
C'est un petit circuit intégré à 16 pins dont l'appellation barbare est "8-bit serial-in/serial or parallel-out shift register with output latches; 3-state".

Cela a peut être l'air compliqué comme cela mais en fait, ce circuit permet de recevoir des données sur une connexion série et de les transformer en sortir parallèle.
Il est donc possible de commander indépendamment 8 sorties digitales à partir de 3 pins Arduino.
Il faudra qu'Arduino s'adresse au 74HC595 via son entrée série.

Encore mieux, il est possible d'assembler les 74HC595 en série (à la queue-leu-leu). Cela permet de commander 16 sorties et toujours à partir de 3 pins Arduino :-)

Comment cela fonctionne
Le diagramme fonctionnelle du 74HC595N est le suivant.
Le Registre a Décalage
Cette première partie tout en haut est celle qui reçoit les information série.
Les informations sont envoyées bit à bit (voir "représentation binaire" plus loin).
L'entrée DS (pin 14)
C'est l'entrée DATA. C'est la pin sur laquelle Arduino va envoyer les différents bits correspondant à Q0 puis Q1 puis Q2 puis Q3, etc jusqu'à Q7.

L'entrée SHcp (pin 11)
C'est celle de l'horloge. Elle est aussi commandée par Arduino.
A chaque fois qu'Arduino à placé un bit sur l'entrée DATA, il doit ensuite activer le clock (haut puis bas) pour que le registre à décalage enregistre le bit data.
Le registre a décalage décale tout son contenu d'un bit (vers la droite par exemple) et se prépare à recevoir le bit suivant.
En gros, c'est un accumulateur de bits. 


L'entrée MR (pin 10)
Est le Master Reset qui n'est pas utilisé.
Puisque c'est une entrée inversée, elle est placée sur VCC (donc équivalent à "NO RESET")


A ce stade, Arduino devrait être capable d'envoyer les informations nécessaires à circuit intégré pour commander les différentes sorties Q0 à Q7.
Pour le moment, nous utilisons 2 fils.

Le latch
Cette deuxième partie nommée "storage register" sur le diagramme à un rôle vraiment important.
C'est lui qui mémorise les données Q0 à Q7 (mais surtout les maintient) pendant que l'on envoie de nouvelles données.
S'il n'y avait pas de latch, toutes les sorties Q0 à Q7 se mettraient à clignoter (changer d'état) au fur et à mesure que les bits seraient envoyés sur la pin DATA.
En effet, chaque envoi décale de registre de la première partie (Oups!).
Mais heureusement, nous avons un latch.

L'entrée STcp (pin 12)
C'est la commande de stockage du Latch.
Quand elle est à LOW, le latch est Bloquant.
En gros, il mémorise l'état Q0 à Q7 au moment du passage HIGH to LOW et persiste à appliquer ces valeurs sur la 3ième partie du diagramme (les sorties) tant que l'entrée est a LOW.

Cela laisse tout le loisir d'envoyer un nouvel état via les pin DATA et CLOCK commandée par Arduino.

Quand l'entrée passe à HIGH, le latch devient passant et applique toutes les valeurs Q0 à Q7 reçue dans le registre à décalage (1iere partie) sur les sorties (le 3ieme partie).

Vous l'aurez devinez, la commande du latch (pin 12) est aussi entre les mains d'Arduino :-)

3-State Outputs 
Cette dernière partie permet de commander l'activation/désactivation de toutes sorties en une seule opération.
Dans certaines situations, il peut être nécessaire de désactiver les sorties pour laisser le contrôle des pins Q0 à Q7 à un autre circuit.
C'est, par exemple, le cas d'une bus de communication.
Cette fonctionnalité n'est pas nécessaire dans le cas présent.

Output Enable (pin 13)
Dans le cas qui concerne cet article, la commande de sorties digitales supplémentaires, il n'est pas nécessaire de commander Output Enabled.
Comme il s'agit d'une sortie inversée, elle est raccordée sur GND (enabled).


Le fonctionnement avec Arduino
Principe de base
Et bien, c'est assez simple.
Arduino place le latch sur Low.
Ensuite, il utilise les pins DATA et CLOCK du 74HC595 pour envoyer un chiffre entre 0 et 255 sur l'interface série (voir "représentation binaire" ci-dessous).
Finalement, il provoque l'affichage des 8 bits en re-activant le latch (en le rendant passant).

En recevant ses bits, le 74HC595 attends d'abord le bit de poids le plus fort (celui correspondant à la valeur 128, 2^7) et ensuite le bit de poids le plus fort suivant (correspondant à 64, 2^6), et ainsi de suite pour les bits 2^5, 2^4, 2^3, 2^2, 2^1 en terminant la séquence par le bit de poids le plus faible (correspondant à 1, 2^0).

Représentation Binaire
Dans le paragraphe ci-dessus, il est expliqué qu'Arduino envoie une valeur de 0 à 255 pour activé les sortie de Q0 à Q7.
Cela est possible car un nombre stocké dans un byte (qui varie de 0 à 255) est justement composé de 8 bits à la queue -leu-leu.
Dans sa représentation binaire, chaque bit d'un nombre à un poids particulier.
Source: Tronixstuff

En sommant les poids (en base-10) des différent bits à 1, il est alors possible de reconstitué la valeur numérique.

Dans l'exemple suivant, si l'on examine le nombre binaire 10101010 correspondant à l'activation des sortie Q0, Q2, Q4, Q6.
Source: Tronixstuff
Cela donne 1+4+16+64 = 85.

Pour plus d'information sur l'arithmétique binaire, vous pouvez consulter l'article "système binaire" sur wikipedia

L'instruction ShiftOut d'Arduino
Pour nous simplifier la vie (et nous éviter de manipuler les sortie DATA et CLOCK), Arduino propose l'instruction ShiftOut.
Cette instruction décompose un nombre en bits et manipule les pins DATA et CLOCK pour envoyer les bits sur une connexion série.

Ainsi chaque bit d'un byte/octet est écrit sur la dataPin du registre à décalage. Après chaque écriture de bit, la fonction fait osciller la clockPin pour que le registre à décalage enregistre la valeur et effectue un décalage du registre (vers la droite) pour recevoir le bit suivant.

Ainsi, les instructions suivante:
int pinData = 2;
int pinClock = 3;
ShiftOut( pinData, pinClock, MSBFIRST, 85) 
Manipulerons les pins 2 et 3 d'Arduino pour envoyer la séquence binaire 01010101 à son destinataire (a savoir les pins 14 et 11 du 74HC595).
Il ne reste plus qu'à manipuler le latch :-)

Note:
La constante MSBFIRST veut dire Most Significant Bit First (le bit le plus significatif en premier... donc celui qui à le plus de poids d'abord).
C'est pour cela que la séquence envoyée est 01010101 et non 10101010 car le bit de poids le plus fort correspond à Q7.

Le montage
Basé sur le montage Ardx, voici le plan de montage.
Ce plan pêche par quelques imprécisions qui vont être réglées immédiatement:
Configuration de brochage
du 74HC595
  • Les sorties 0 à 9 correspondent à Q0 (broche 15) ensuite de Q1 (broche 1) à Q7 (broche 7)
  • La pin "Data" se trouve à la broche 14 nommé "DS / Serial Data Input".
  • La pin "Latch" se trouve à la broche 12 nommée "STcp / Storage Register Clock Input"
  • La pin "Clock" se trouve à la broche 11 nommée "SHcp / Shift Register clock input"
  • La broche 10 nommeé "MR/Master reset" doit être raccordée à VCC (ne pas faire de master reset)
  • La broche 14 nommée "OE/Output Enabled" doit être raccordée à GND (sortir toujours activées)
Le code

Amélioration 1
Cet exemple est assez rudimentaire, le plus intéressant serait de pouvoir commander chaque sortie du 74HC595 séparément à l'aide d'une fonction.
Voir article "Augmenter le nbre de sorties avec 74HC595N - Part II".

Amélioration 2
Monter deux 74HC595 pour commander 16 sorties digitales.

Source: ShiftRegister.pde

/*
   Démontre l'usage d'un Registre a Décalage 74HC595N
   
   Ce circuit intégré permet de démontrer qu'il est possible de configurer
   8 bits sur le 74HC595N à partir d'une simple communication série (3 fils).
   
   Cela permet d'augmenter le nombre de sortie d'Arduino en utilisant un 
   minimum de PINs.
      
Notes:
   Attention, par défaut, toutes les sortie Q0 à Q7 sont LOW!
   
Montage 74HC595N
  pin 16 - VCC
  Pin 8  - GND
  Pin 10 - (Reset) VCC -> no reset
  Pin 13 - (Output Enable) GND -> Enabled
  
  Pin 11 - Clock (Shift Register Clock / SHcp) to Arduino Pin 3
  Pin 14 - Data  (Serial Data Input / DS) to Arduino Pin 2
  Pin 12 - Latch (Storage Register Clock Input / STcp ) to Arduino Pin 4 
  
  Pin 15 - Q0 to Led 0 (avec un résistance de 330 Ohms pour chaque Led).
  Pin 1  - Q1 to Led 1
  Pin 2  - Q2 to Led 2
  ...
  Pin 7  - Q7 to Led 7 
 */

// Communication série avec le 74HC595N 
int dataPin  = 2;
int clockPin = 3;
int latchPin = 4;

void setup(){
  pinMode( dataPin, OUTPUT );
  pinMode( clockPin, OUTPUT );
  pinMode( latchPin, OUTPUT );  
}

void loop(){
  // Ecrire la valeur 102 Allume les sorties Q1,Q2,Q5,Q6
  updateLeds( 102 );
  delay( 2000 ); // 2 sec
  
  int delaiMs = 100; // ms
  for( int i = 0; i<=255; i++ ){
     updateLeds( i );
     delay( delaiMs );
  }
}

//Description:
//  converti la valeur entière en binaire
//  et l'affiche sur le 74HC595N
void updateLeds( int iValeur ){
  
  // --- Bloque le latch ---
  // Le latch devient non passant. Il memorise la valeur actuelle 
  //    des entrée du latch (du registre à décalage) et maintient
  //   les valeurs des sorties Q0 à Q7.
  // Peut importe les modifications du registre a décalage, le 
  //   latch n'en tient pas compte.  
  digitalWrite( latchPin, LOW );

  // Cette instruction écrit chaque bit d'un byte/octet sur la 
  //   dataPin du registre à décalage. Après chaque bit écrit,
  //   la fonction fait osciller la clockPin pour que le registre
  //   a décalage enregistre la valeur et effectue un décalage
  //   du registre (vers la droite) pour recevoir la valeur suivante.
  // La constante MSBFIRST (Most Significant Bit First) indique que
  //   l'on commence l'écriture par le bit le plus important (de gauche
  //   a droite)  
  shiftOut( dataPin, clockPin, MSBFIRST,iValeur );
 
  // --- Active le latch ---
  // Devient passant et applique les valeurs du registre à décalage
  // sur les sorties
   digitalWrite( latchPin, HIGH ); 
}

Résultat
Le résultat est comparable à de nombreuses vidéos publiées sur le Net.
En voici un exemple parmi d'autres.


Source:YouTube

Références

2 commentaires: