Code pour shift register 74h595 en série

Bonsoir,

je suis nouveau sur ce forum et très désireux d'appendre l'arduino pour faire des projets comme : robot mobile, objet connectés, ... . J'utilise une arduino UNO
Pour commencer, j'arrive à jouer avec des LED et des boutons.

J'ai pour projet de créer une matrice de 30 leds pour y afficher des smileys (d'où l'utilisation d'un tableau dans mon code pour pouvoir gérer quelle led afficher ou non, ... .

J'ai vu que pour jouer avec plus de 13 pins il fallait utiliser des shift register 74hc595.

==> mon premier montage avec 1 seul shift register qui gère 8 led fonctionne

// on défini les pins 
#define SHIFT 5
#define LATCH 6
#define DATA 7


// Table led à allumer
const byte chars[8] = {
    B10000001,
    B00000010,
    B01000100,
    B00001000,
    B00010000,
    B00100000,
    B01000010,
    B10000000};

int time_delay = 500; // Delay 

void setup()
{
    // On déclare les pins vers le 74HC595 en sortie
    pinMode(SHIFT, OUTPUT);
    pinMode(LATCH, OUTPUT);
    pinMode(DATA, OUTPUT);
}

void loop()
{
    int i;
    // On boucle sur le tableau char
    for (i = 0; i < 8; i++) {
        digitalWrite(LATCH, LOW);  
        shiftOut(DATA, SHIFT, MSBFIRST, chars[i]);
        digitalWrite(LATCH, HIGH);
        delay(time_delay);
    }
}

==> par contre quand je veux passer à 16 leds, avec 2 shift register donc, cela ne fonctionne pas. Faut-il déclarer le nombre de shift register utilisé ?

// on défini les pins 
#define SHIFT 5
#define LATCH 6
#define DATA 7


// Table led à allumer
const byte chars[16] = {
    B1000000100000000,
    B0000001000000000,
    B0100010000000100,
    B0000100000000000,
    B0001000000000000,
    B0010000000000000,
    B0100001000000000,
    B1000000000000000,
B1000000100000000,
    B0000001000000000,
    B0100010000000000,
    B0000100000000010,
    B0001000000000000,
    B0010000000000000,
    B0100001000001000,
    B1000000000000000}

int time_delay = 500; // Delay 

void setup()
{
    // On déclare les pins vers le 74HC595 en sortie
    pinMode(SHIFT, OUTPUT);
    pinMode(LATCH, OUTPUT);
    pinMode(DATA, OUTPUT);
}

void loop()
{
    int i;
    // On boucle sur le tableau char
    for (i = 0; i < 16; i++) {
        digitalWrite(LATCH, LOW);  
        shiftOut(DATA, SHIFT, MSBFIRST, chars[i]);
        digitalWrite(LATCH, HIGH);
        delay(time_delay);
    }
}

Merci pour votre aide.

J

Bonjour,

Je n'arrive pas à comprendre comment tu peux compiler ton 2eme programme. Les constantes Bxxxxxxxx sont limitées à 8 bits.

  • déclares ton tableau en word
  • utilises 0bxxxxxx à la place de Bxxxxxxx
  • transmets l'octet de poids fort puis l'octet de poids faible

Bonsoir,

merci pour la réponse mais j'avoue ne pas tout comprendre.
Qu'entends tu par "déclarer ton tableau en word" ?

J'ai complété le code comme ceci :

// on défini les pins 
#define SHIFT 5
#define LATCH 6
#define DATA 7

// déclaration des 74HC595
char HC595_0,HC595_1;

// Table led à allumer
const char sequence[]={
    0b10000001, 0b00010000,
    0b00000100, 0b10001000,
    0b10001000, 0b00010000,
    0b00010000, 0b10000100,
    0b00100000, 0b10001000,
    0b01000000, 0b00010000,
    0b10000100, 0b00010000,
    0b00100010, 0b00000000};

int time_delay = 500; 

void setup()
{
    // On déclare les pins vers le 74HC595 en sortie
    pinMode(SHIFT, OUTPUT);
    pinMode(LATCH, OUTPUT);
    pinMode(DATA, OUTPUT);
}

void loop()
{
    int i;
    //  boucle sur le tableau char
    for (i = 0; i < 8; i++) {
        digitalWrite(LATCH, LOW); 
        shiftOut(DATA, SHIFT, MSBFIRST, char [i]);
        digitalWrite(LATCH, HIGH);
        delay(time_delay);
    }
}

mais j'obtiens cette erreur !
error: expected primary-expression before 'char'

Je n'arrive pas à savoir quel est le problème ? Qq'un aurait une idée svp.

A+

Déclarer le tableau en word c'est ça:

const word sequence[16] = {
    0b1000000100000000,
    0b0000001000000000,
...

Ensuite tu transmets les deux octets de chaque mot:

    for (i = 0; i < 16; i++) {
        digitalWrite(LATCH, LOW);  
        shiftOut(DATA, SHIFT, MSBFIRST, sequence[i]>>8);  // transmet l'octet fort
        shiftOut(DATA, SHIFT, MSBFIRST, sequence[i] & 0xff);  // transmet l'octet faible
        digitalWrite(LATCH, HIGH);
        delay(time_delay);
    }

Et l'erreur de compilation dans ton programme est ici

        shiftOut(DATA, SHIFT, MSBFIRST, char [i]);

ce n'est pas char*, mais sequence*
*_ <em>*        shiftOut(DATA, SHIFT, MSBFIRST, sequence[i]);*</em> _*
mais ton programme ne transmet pas le bon nombre d'octets

Pour info voici le code de la fonction shiftout de la dernière version de Wiring:

void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint16_t val, uint8_t count, uint8_t delayTime)
{
  int i;

  for (i = 0; i < count; ++i)
  {
    if (bitOrder == LSBFIRST)
      digitalWrite(dataPin, !!(val & (1 << i)));
    else
      digitalWrite(dataPin, !!(val & (1 << ((count - 1) - i))));

    digitalWrite(clockPin, HIGH);
    delayMicroseconds(delayTime);
    digitalWrite(clockPin, LOW);
    delayMicroseconds(delayTime);
  }
}

Par rapport à la version qu'arduino a copié il y a deux ajouts :

  1. "delaytime" : un delai pour créer un créneau d'horloge plus large pour les composants peu rapides (vu la lenteur des fonctions digitalWrite c'est plus pour satisfaire l'esprit qu'utile).
  2. "count" : pour envoyer le nombre de bit que l'on veux et non plus 8.
    la variable val est maintenant un entier sur 2 octets.

La fonction peut être modifiée pour l'adapter à ton besoin.

Merci pour votre réponse rapide.

J'arrive à contrôler 2 74HC595.

Mais comme je suis joueur, j'ai voulu aller plus loin et en contrôler 3 en cascade (pour le montage je me suis inspiré de ce site :

Les 2 premiers 74hc595 sont bien contrôlés mais le 3eme (et dernier) shift register ne fait pas s'allumer mes leds ! Quelle est l'astuce svp ?

Voici mon code :

#define SHIFT 5
#define LATCH 6
#define DATA 7

char HC595_0,HC595_1, HC595_2;

int time_delay = 10000; 

void setup()
{
    // On déclare les pins vers le 74HC595 en sortie
    pinMode(SHIFT, OUTPUT);
    pinMode(LATCH, OUTPUT);
    pinMode(DATA, OUTPUT);
}

void loop()
{
    int i = 15;
    // On boucle sur le tableau char
    if (i = 15)
    { 
        digitalWrite(LATCH, LOW); 
      shiftOut(DATA, SHIFT, MSBFIRST, 0b111111010000000000000000 >> 16);  
      shiftOut(DATA, SHIFT, MSBFIRST, 0b1100000100000000 >> 8);  // contrôle le second 74hc595  
        shiftOut(DATA, SHIFT, MSBFIRST, 0b11001101 & 0xff);  // contrôle le premier 74hc595
         
        digitalWrite(LATCH, HIGH);
        delay(time_delay);
}
}

PS : Je sais que le code binaire n'est pas très propre mais ca me permet de m'y retrouver plus facilement pour le moment.

Merci

J.

Bonjour,

Il faut peut être indiquer que tu veux décaler des valeurs sur 32 bits

    shiftOut(DATA, SHIFT, MSBFIRST, 0b111111010000000000000000UL >> 16);

Autrement par défaut les décalages se font sur des entiers (16 bits)

Bonsoir,

désolé pour le moment de silence, mais j'ai fait qq tests de mon côté.

Voici mon nouveau code simplifié avec 3 composants 74hc595:

#define SHIFT 5
#define LATCH 6
#define DATA 7
 

// CODE décimal      
char premier = 254;
char second = 254;
char trois = 85;




void setup()
{
    // On déclare les pins vers le 74HC595 en sortie
    pinMode(SHIFT, OUTPUT);
    pinMode(LATCH, OUTPUT);
    pinMode(DATA, OUTPUT);
}

void loop()
{
    int i = 15;

    if (i = 15)
    { 
        digitalWrite(LATCH, LOW); 
    
     shiftOut(DATA, SHIFT, MSBFIRST, ~trois); 
     shiftOut(DATA, SHIFT, MSBFIRST, ~second); 
     shiftOut(DATA, SHIFT, MSBFIRST, ~premier); 
      
       
        digitalWrite(LATCH, HIGH);
     

      
    }
}

Mes 2 premiers jeux de led s'allument mais pas le troisème : smiley-cry:

Voilà mon montage :

D'où vient mon problème ?

Merci pour votre aide

J

Bonjour,

Vu que ton programme fait 3 fois exactement la même chose, je ne vois qu'un problème de cablage.

Bonsoir,

j'ai beau chercher depuis qq jours, je ne trouve pas le problème au niveau des branchements en tout cas. Et oui le code est simple. Du coup est-ce que cela peut-être dû à des resistances mal dimensionnées ?

J.

J'ai beau chercher depuis qq jours, je ne trouve pas le problème au niveau des branchements en tout cas.

Conseil d'un vieux singe qui a bien donné dans les conne*ries :
Si tu ne trouve pas au bout d'une heure : décâble tout et recâble.