double afficheur à ségments et une 74HC595

Bonjour à toutes et à tous,

je suis en train de tester un petit module avec un double afficheur à segments pour faire un compte à rebours.

voici mon montage :


donc une arduino UNO et un module.

le code que j’utilise est le suivant :

/* 
 *  2 Digitl 7 segment display PCB board with (2) 74HC595 shift register ICs
 *  Arduino Tutorial - www.Ardumotive.com
 *  Dev: Michalis Vasilakis // Date: 31/1/2018 // Ver:1.0
 */
#include <ShiftRegister74HC595.h>
// create shift register object (number of shift registers, data pin, clock pin, latch pin)
ShiftRegister74HC595 sr (2, 2, 3, 4); 

int number=99; // <--- Change it from 0 to 99

int value,digit1,digit2,digit3,digit4; 
uint8_t  numberB[] = {B11000000, //0
                      B11111001, //1 
                      B10100100, //2
                      B10110000, //3 
                      B10011001, //4
                      B10010010, //5
                      B10000011, //6
                      B11111000, //7
                      B10000000, //8
                      B10011000 //9
                     };
                        
void setup() {
  //Count from 0 to 'number' 
  countUp();
  //Count from 'number' to 0
  //countDown();  // <--- Comment countUp and uncomment countDown
  //Blink 4 times all on and all off.
  blink();  
}

void loop() {

}

void countUp(){
  for (int i = 0; i<=number; i++){
    //Split number to digits:
    digit2=i % 10 ;
    digit1=(i / 10) % 10 ;
    //Send them to 7 segment displays
    uint8_t numberToPrint[]= {numberB[digit2],numberB[digit1]};
    sr.setAll(numberToPrint); 
    //Reset them for next time
    digit1=0;
    digit2=0;
    delay(1000); // Repeat every 1 sec
  }
}

void countDown(){
  for (number; number>=0; number--){
    //Split number to digits:
    digit2=number % 10 ;
    digit1=(number / 10) % 10 ;
    //Send them to 7 segment displays
    uint8_t numberToPrint[]= {numberB[digit2],numberB[digit1]};
    sr.setAll(numberToPrint); 
    //Reset them for next time
    digit1=0;
    digit2=0;
    delay(1000); // Repeat every 1 sec
  }
}

//Blink
void blink(){
  for(int i = 0; i<4; i++){
    sr.setAllLow(); // set all pins Low (off)
    delay(1000);
    sr.setAllHigh(); // set all pins High (on)
    delay(1000);
  }
}

je l’ai trouvé sur ce site : http://www.ardumotive.com/2-digit-7seg-display-en.html

D’après le code normalement une fois arrivé à la fin, il y a 4 clignotements et on repart en arrière, mais là après le clignotement l’afficheur reste éteint… :confused:

Auriez-vous une idée ?

Un grand merci d’avance

Bonjour
regardes bien son setup() :

Tu enchaines un countUp() et un blink(), c'est tout (pas de countDown(), il est en commentaires !)

Ton montage fait ce que tu lui demandes dans le code.....

Bonsoir,

Si tu veux une répétition de ton code, n'oublies pas le loop...
le setup se lance une seule fois.

Si tu veux une répétition de ton code, n'oublies pas le loop...

en effet j'ai remarqué qu'une fois arrivé à 00, il clignote et reste éteint. Donc pour qu'il puisse tourner en boucle à l'infini je déplace tout se qui se trouve dans le void setup() dans le void loop() ?

Ce qu’il faut savoir :
Tu écrit au minimum une fonction setup et une fonction loop
L’IDE les assemble dans un vrai fichier C
Structure du fichier réellement transmis au compilateur

// lignes de déclarations de variables globales et instanciation d'objets
// lignes d'includes dont Arduino.h
// lignes de define

void setup();  // prédéclaration des fonctions nécessaire pour que le compilateur ne génère pas d'erreur
void loop() ;  // idem

int main()
{
   init();  // configuration du microcontroleur à la sauce arduino
   setup() ;
   while(true)  
   {           
     loop() ;
  }
}

En réalité la ligne while(true) est une boucle for( ; ; ) pour des raisons de rapidité.
Le résultat est identique mais plus compliqué à expliquer qu’avec la boucle while(true)
Dans une boucle while ce qui se trouve entre les parenthèse est un test dont le résultat est un booléen qui vaut true ou false.
while (variable <= réference)
Si variable est inférieur ou égal à référence le résultat du test est un booléen qui vaut true
Sinon le résultat du test est un booléen qui vaut false.

Donc en forçant ce qui est entre parenthèse à true on ne peut jamais sortir de la boucle while.

Ce n’est donc pas loop() qui tourne sur elle-même.
le programme entre dans loop(), le programme sort de loop(), mais y ré-entre aussitôt.

Cela a des conséquences sur les variables locales créées dans loop() → elles sont créés à chaque entrée dans loop() et tuées à chaque sortie de loop().

ok merci de ces explications mais comment faire alors pour que le compte à rebours soit infini ?

Il suffit de déplacer les lignes

  //countDown();  // <--- Comment countUp and uncomment countDown
  //Blink 4 times all on and all off.
  blink();

dans la loop en décommentant le countDown();

Salut Lesept,

je l'ai fait alors le compte à rebours fonctionne mais une fois arrivé à 00 il clignote à l'infinie

void loop(){
countDown();
blink();
}

en enlevant le blink(); il reste à 00.

je pige plus rien... quand on mets du code dans void loop() le code est sensé se répéter en boucle ?? :astonished:

C'est ce je t'ai expliqué :
La fonction loop() est placé dans une boucle dont il est impossible de sortir.

Après l'exécution de la fonction setup() le programme entre dans la boucle while(true) qui joue le rôle de boucle infinie.
Le programme entre dans la fonction loop()
Le code de la fonction loop() est éxécuté.
Le programme sort de la fonction loop()
Du fait de la boucle while(true) le programme re-entre instantanément dans la fonction loop().

Mais dès qu'on sort d'une fonction les variables qui y ont été déclarées localement sont tuées.
Si le programme re-entre dans la fonction elles sont recrées mais les valeurs précédentes sont définitivement perdues.
La solution est soit de les déclarer globales soit de les déclarer locales mais en ajoutant le mot clé "static".

Voir un tuto de C.

Dit autrement, la valeur de number que tu déclares en début de programme
int number=99; // <--- Change it from 0 to 99descend à 0 dans le countDown et y reste une fois pour toutes. Pour t’en convaincre, ajoute
Serial.println(number);avant l’appel de blink (et bien sûr déclare ta liaison série dans le setup, tu sais faire ?).
Si elle reste à 0 à chaque fois, il faut la réinitialiser en début de loop. Tu peux faire ça plus ou moins élégamment, par exemple en définissant une constante en début de programme (en lui donnant la valeur 99) et affectant cette valeur à number dans la loop et dans countUp… ou en dur dans le programme…

Je pense que ton code est inutilement compliqué, il faut le diviser en fonctions unitaires simples et faciles à tester et débuguer en cas de besoin.
Par exemple, tu pourrais créer une fonction d’affichage avec en argument le nombre à afficher et appeler cette fonction dans les boucles de countUp et countDown/

void Affiche (int N) {
    //Split number to digits:
    digit2=number % 10 ;
    digit1=(number / 10) % 10 ;
    //Send them to 7 segment displays
    uint8_t numberToPrint[]= {numberB[digit2],numberB[digit1]};
    sr.setAll(numberToPrint); 
    delay(1000);
}

Ensuite tu pourrais définir la valeur 99 comme une constante qui servirait à la fois dans le setup et dans la loop, et que tu pourrais facilement modifier en cas de besoin :

#include <ShiftRegister74HC595.h>
// create shift register object (number of shift registers, data pin, clock pin, latch pin)
ShiftRegister74HC595 sr (2, 2, 3, 4); 
int value,digit1,digit2,digit3,digit4; 
uint8_t  numberB[] = {B11000000, //0
                      B11111001, //1 
                      B10100100, //2
                      B10110000, //3 
                      B10011001, //4
                      B10010010, //5
                      B10000011, //6
                      B11111000, //7
                      B10000000, //8
                      B10011000 //9
                     };
const int number = 99;

void countUp()
{
  for (int i=0;i<=number;i++) Affiche(i);
}

void countDown()
{
  for (int i=number;i>=0;i--) Affiche(i);
}


void setup() {
  countUp();
}

void loop() {
  countDown();
  blink();
}

Je ne sais pas si ça marche, mais c’est un début et ça doit être plus facile à comprendre et à débuguer…