Go Down

Topic: double afficheur à ségments et une 74HC595 (Read 795 times) previous topic - next topic

vj_dobermann

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 :

Code: [Select]
/*
 *  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... :smiley-confuse:

Auriez-vous une idée ?

Un grand merci d'avance

al1fch

#1
Mar 17, 2018, 06:00 pm Last Edit: Mar 17, 2018, 07:16 pm by al1fch
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.....

Aegnor1975

Bonsoir,

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

vj_dobermann

Quote
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() ?

68tjs

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
Code: [Select]
// 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().



vj_dobermann

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

lesept

#6
Mar 18, 2018, 09:48 am Last Edit: Mar 18, 2018, 09:48 am by lesept
Il suffit de déplacer les lignes
Code: [Select]
  //countDown();  // <--- Comment countUp and uncomment countDown
  //Blink 4 times all on and all off.
  blink();

dans la loop en décommentant le countDown();
A force d'essayer on finit par réussir... Donc, plus ça rate, plus on a de chances que ça marche (proverbe Sharduinok).

vj_dobermann

Salut Lesept,

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

Code: [Select]

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 ?? :smiley-eek:

68tjs

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.

lesept

Dit autrement, la valeur de number que tu déclares en début de programme
Code: [Select]
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
Code: [Select]
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...
A force d'essayer on finit par réussir... Donc, plus ça rate, plus on a de chances que ça marche (proverbe Sharduinok).

lesept

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/

Code: [Select]
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 :

Code: [Select]
#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...
A force d'essayer on finit par réussir... Donc, plus ça rate, plus on a de chances que ça marche (proverbe Sharduinok).

Go Up