Horloge avec afficheur 7 segments 4 digit.

Bonjour, nous sommes des terminales STI2D et nous avons beaucoup de problème pour notre projet.
Nous voulons faire une horloge.
Nous disposons d'un afficheur 7 segments 4 digits( http://fr.hobbytronics.co.uk/4digit-7segment-gr)
et une arduino UNO.
Les branchements sont bons, nous avons compris le système mais nous n'arrivons pas a faire le programme.
Notre programme ressemble a ça :

int digit1 = 11;
int digit2 = 10; 
int digit3 = 9; 
int digit4 = 6;


int segA = A1; 
int segB = 3; 
int segC = 4; 
int segD = 5; 
int segE = A0; 
int segF = 7; 
int segG = 8; 

void setup() {                
  pinMode(segA, OUTPUT);
  pinMode(segB, OUTPUT);
  pinMode(segC, OUTPUT);
  pinMode(segD, OUTPUT);
  pinMode(segE, OUTPUT);
  pinMode(segF, OUTPUT);
  pinMode(segG, OUTPUT);

  pinMode(digit1, OUTPUT);
  pinMode(digit2, OUTPUT);
  pinMode(digit3, OUTPUT);
  pinMode(digit4, OUTPUT);
  
  pinMode(13, OUTPUT);
}

void loop() {
  
#define DIGIT_ON  HIGH
#define DIGIT_OFF  LOW



 


#define SEGMENT_ON  LOW
#define SEGMENT_OFF HIGH

  switch (){

  case 0:
    digitalWrite(segA, SEGMENT_ON);
    digitalWrite(segB, SEGMENT_ON);
    digitalWrite(segC, SEGMENT_ON);
    digitalWrite(segD, SEGMENT_ON);
    digitalWrite(segE, SEGMENT_ON);
    digitalWrite(segF, SEGMENT_ON);
    digitalWrite(segG, SEGMENT_OFF);
    break;

  case 1:
    digitalWrite(segA, SEGMENT_OFF);
    digitalWrite(segB, SEGMENT_ON);
    digitalWrite(segC, SEGMENT_ON);
    digitalWrite(segD, SEGMENT_OFF);
    digitalWrite(segE, SEGMENT_OFF);
    digitalWrite(segF, SEGMENT_OFF);
    digitalWrite(segG, SEGMENT_OFF);
    break;

  case 2:
    digitalWrite(segA, SEGMENT_ON);
    digitalWrite(segB, SEGMENT_ON);
    digitalWrite(segC, SEGMENT_OFF);
    digitalWrite(segD, SEGMENT_ON);
    digitalWrite(segE, SEGMENT_ON);
    digitalWrite(segF, SEGMENT_OFF);
    digitalWrite(segG, SEGMENT_ON);
    break;

  case 3:
    digitalWrite(segA, SEGMENT_ON);
    digitalWrite(segB, SEGMENT_ON);
    digitalWrite(segC, SEGMENT_ON);
    digitalWrite(segD, SEGMENT_ON);
    digitalWrite(segE, SEGMENT_OFF);
    digitalWrite(segF, SEGMENT_OFF);
    digitalWrite(segG, SEGMENT_ON);
    break;

  case 4:
    digitalWrite(segA, SEGMENT_OFF);
    digitalWrite(segB, SEGMENT_ON);
    digitalWrite(segC, SEGMENT_ON);
    digitalWrite(segD, SEGMENT_OFF);
    digitalWrite(segE, SEGMENT_OFF);
    digitalWrite(segF, SEGMENT_ON);
    digitalWrite(segG, SEGMENT_ON);
    break;

  case 5:
    digitalWrite(segA, SEGMENT_ON);
    digitalWrite(segB, SEGMENT_OFF);
    digitalWrite(segC, SEGMENT_ON);
    digitalWrite(segD, SEGMENT_ON);
    digitalWrite(segE, SEGMENT_OFF);
    digitalWrite(segF, SEGMENT_ON);
    digitalWrite(segG, SEGMENT_ON);
    break;

  case 6:
    digitalWrite(segA, SEGMENT_ON);
    digitalWrite(segB, SEGMENT_OFF);
    digitalWrite(segC, SEGMENT_ON);
    digitalWrite(segD, SEGMENT_ON);
    digitalWrite(segE, SEGMENT_ON);
    digitalWrite(segF, SEGMENT_ON);
    digitalWrite(segG, SEGMENT_ON);
    break;

  case 7:
    digitalWrite(segA, SEGMENT_ON);
    digitalWrite(segB, SEGMENT_ON);
    digitalWrite(segC, SEGMENT_ON);
    digitalWrite(segD, SEGMENT_OFF);
    digitalWrite(segE, SEGMENT_OFF);
    digitalWrite(segF, SEGMENT_OFF);
    digitalWrite(segG, SEGMENT_OFF);
    break;

  case 8:
    digitalWrite(segA, SEGMENT_ON);
    digitalWrite(segB, SEGMENT_ON);
    digitalWrite(segC, SEGMENT_ON);
    digitalWrite(segD, SEGMENT_ON);
    digitalWrite(segE, SEGMENT_ON);
    digitalWrite(segF, SEGMENT_ON);
    digitalWrite(segG, SEGMENT_ON);
    break;

  case 9:
    digitalWrite(segA, SEGMENT_ON);
    digitalWrite(segB, SEGMENT_ON);
    digitalWrite(segC, SEGMENT_ON);
    digitalWrite(segD, SEGMENT_ON);
    digitalWrite(segE, SEGMENT_OFF);
    digitalWrite(segF, SEGMENT_ON);
    digitalWrite(segG, SEGMENT_ON);
    break;

  case 10:
    digitalWrite(segA, SEGMENT_OFF);
    digitalWrite(segB, SEGMENT_OFF);
    digitalWrite(segC, SEGMENT_OFF);
    digitalWrite(segD, SEGMENT_OFF);
    digitalWrite(segE, SEGMENT_OFF);
    digitalWrite(segF, SEGMENT_OFF);
    digitalWrite(segG, SEGMENT_OFF);
    break;
  }
}

Notre prof ne parviens pas a nous éclairer.
Nous avons besoin de votre aide :slight_smile:
Merci d'avance.

Salut,

Vous la prenez où l'heure ?

Sinon il vous faut construire les fonctions permettant de simplifier l'affichage d'un nombre, ce que vous avez presque fini. Pour vous aider ça devrait donner :

void AfficherChiffre(byte Chiffre, byte Digit)

switch(Digit) {
case 0 :
digitalWrite(digit1,DIGIT_ON);
digitalWrite(digit2,DIGIT_OFF);
digitalWrite(digit13,DIGIT_OFF);
digitalWrite(digit4,DIGIT_OFF);
break;
case 1 :
digitalWrite(digit1,DIGIT_OFF);
digitalWrite(digit2,DIGIT_ON);
digitalWrite(digit13,DIGIT_OFF);
digitalWrite(digit4,DIGIT_OFF);
break;
case 2 :
digitalWrite(digit1,DIGIT_OFF);
digitalWrite(digit2,DIGIT_OFF);
digitalWrite(digit13,DIGIT_ON);
digitalWrite(digit4,DIGIT_OFF);
break;
case 3 :
digitalWrite(digit1,DIGIT_OFF);
digitalWrite(digit2,DIGIT_OFF);
digitalWrite(digit13,DIGIT_OFF);
digitalWrite(digit4,DIGIT_ON);
break;
}

 switch (Chiffre){

 case 0:
    digitalWrite(segA, SEGMENT_ON);
    digitalWrite(segB, SEGMENT_ON);
    digitalWrite(segC, SEGMENT_ON);
    digitalWrite(segD, SEGMENT_ON);
    digitalWrite(segE, SEGMENT_ON);
    digitalWrite(segF, SEGMENT_ON);
    digitalWrite(segG, SEGMENT_OFF);
    break;

  case 1:
    digitalWrite(segA, SEGMENT_OFF);
    digitalWrite(segB, SEGMENT_ON);
    digitalWrite(segC, SEGMENT_ON);
    digitalWrite(segD, SEGMENT_OFF);
    digitalWrite(segE, SEGMENT_OFF);
    digitalWrite(segF, SEGMENT_OFF);
    digitalWrite(segG, SEGMENT_OFF);
    break;

  case 2:
    digitalWrite(segA, SEGMENT_ON);
    digitalWrite(segB, SEGMENT_ON);
    digitalWrite(segC, SEGMENT_OFF);
    digitalWrite(segD, SEGMENT_ON);
    digitalWrite(segE, SEGMENT_ON);
    digitalWrite(segF, SEGMENT_OFF);
    digitalWrite(segG, SEGMENT_ON);
    break;

  case 3:
    digitalWrite(segA, SEGMENT_ON);
    digitalWrite(segB, SEGMENT_ON);
    digitalWrite(segC, SEGMENT_ON);
    digitalWrite(segD, SEGMENT_ON);
    digitalWrite(segE, SEGMENT_OFF);
    digitalWrite(segF, SEGMENT_OFF);
    digitalWrite(segG, SEGMENT_ON);
    break;

  case 4:
    digitalWrite(segA, SEGMENT_OFF);
    digitalWrite(segB, SEGMENT_ON);
    digitalWrite(segC, SEGMENT_ON);
    digitalWrite(segD, SEGMENT_OFF);
    digitalWrite(segE, SEGMENT_OFF);
    digitalWrite(segF, SEGMENT_ON);
    digitalWrite(segG, SEGMENT_ON);
    break;

  case 5:
    digitalWrite(segA, SEGMENT_ON);
    digitalWrite(segB, SEGMENT_OFF);
    digitalWrite(segC, SEGMENT_ON);
    digitalWrite(segD, SEGMENT_ON);
    digitalWrite(segE, SEGMENT_OFF);
    digitalWrite(segF, SEGMENT_ON);
    digitalWrite(segG, SEGMENT_ON);
    break;

  case 6:
    digitalWrite(segA, SEGMENT_ON);
    digitalWrite(segB, SEGMENT_OFF);
    digitalWrite(segC, SEGMENT_ON);
    digitalWrite(segD, SEGMENT_ON);
    digitalWrite(segE, SEGMENT_ON);
    digitalWrite(segF, SEGMENT_ON);
    digitalWrite(segG, SEGMENT_ON);
    break;

  case 7:
    digitalWrite(segA, SEGMENT_ON);
    digitalWrite(segB, SEGMENT_ON);
    digitalWrite(segC, SEGMENT_ON);
    digitalWrite(segD, SEGMENT_OFF);
    digitalWrite(segE, SEGMENT_OFF);
    digitalWrite(segF, SEGMENT_OFF);
    digitalWrite(segG, SEGMENT_OFF);
    break;

  case 8:
    digitalWrite(segA, SEGMENT_ON);
    digitalWrite(segB, SEGMENT_ON);
    digitalWrite(segC, SEGMENT_ON);
    digitalWrite(segD, SEGMENT_ON);
    digitalWrite(segE, SEGMENT_ON);
    digitalWrite(segF, SEGMENT_ON);
    digitalWrite(segG, SEGMENT_ON);
    break;

  case 9:
    digitalWrite(segA, SEGMENT_ON);
    digitalWrite(segB, SEGMENT_ON);
    digitalWrite(segC, SEGMENT_ON);
    digitalWrite(segD, SEGMENT_ON);
    digitalWrite(segE, SEGMENT_OFF);
    digitalWrite(segF, SEGMENT_ON);
    digitalWrite(segG, SEGMENT_ON);
    break;

  case 10:
    digitalWrite(segA, SEGMENT_OFF);
    digitalWrite(segB, SEGMENT_OFF);
    digitalWrite(segC, SEGMENT_OFF);
    digitalWrite(segD, SEGMENT_OFF);
    digitalWrite(segE, SEGMENT_OFF);
    digitalWrite(segF, SEGMENT_OFF);
    digitalWrite(segG, SEGMENT_OFF);
    break;
  }
}

delay(Persistance); // pause pour que le chiffre soit visible

La il suffit de taper AfficherChiffre(8,1) pour que sur le premier digit s'affiche 8.

Ensuite comment ça marche : il faut, 24 fois par seconde, au moins afficher chaque digit pour que ça donne l'illusion que tout est allumé en même temps. Donc phase 1, j'affiche le premier digit, puis le second, puis le troisième puis le quatrième. Le tout c'est de bien ajuster les timing pour que ça ne tremble pas et que ça soit suffisamment lumineux (variable Persistance à ajuster entre autre).

Ce qu'il vous reste à programmer pour le moment : une fonction qui exploite AfficherChiffre() mais pour tous les digits. Par exemple :

int  MaVariable = 1234;
Afficher Nombre(MaVariable); // et hop sur le 7 seg on peut lire 1 2 3 4

Pour vous aider pour la gestion des 24 i/s : [Tutorial] Les interruptions temporelles avec Arduino | B@ttoMicro - Microcontrôleurs et compagnie !

Merci beaucoup ça marche nickel, trois séances dessus pour finalement avoir une réponse dans l'heure.
Encore merci on va se pencher sur l'heure qui n'est pas définit.
On vous tiens au courant pour la suite.
:slight_smile:

Nous revoilà, euuu... je comprend pas. =(
je n'arrive pas a synchroniser les secondes avec les dizaines (juste pour comprendre), et les "boolean Flag" je comprend pas a quoi ils servent ?
En faite pour faire défiler les secondes y'a pas de soucis mais dès qu'il y a les dizaines les secondes s'éteignent.

void loop() {
  
for(a=0;a<10;a++){
  AfficherChiffre(a,4);
  delay(1000);
}
}

Merci d'avance :wink:

B@tto:
Ce qu'il vous reste à programmer pour le moment : une fonction qui exploite AfficherChiffre() mais pour tous les digits.

C'est pas comme si je vous l'avez pas dit ...

C'est tellement simple à faire que mis à part vous balancer le code comme ça je vois pas trop ce que je peux rajouter ...

Il faut afficher chaque digit, mais tellement rapidement que c'est invisible pour l'oeil humain, ainsi on a l'impression que tout est allumé en même temps, mais en fait on a fait afficher digit1, on attend un certain temps, afficher digit3, on attend un certain temps ... et le balayage de l'ensemble des digits doit se faire au moins 24 fois / seconde

un flag permet d'indiquer qu'on "est passé quelque part". Par exemple :

if (analogRead(A0) > 100) Flag=1;

et ailleurs dans le programme ça change des choses

if(analogRead(A1) && Flag==1) digitalWrite(LED,HIGH);

Mais je vois pas comment il est possible de déclarer un entier, et que ça affiche cet entier sur le digit.
Et je pense pas que ça se fasse juste avec les deux lignes de code :zipper_mouth_face:
Désolé je suis un débutant en programmation, j'ai compris le fait que les digits ne peuvent pas être affichés en même temps donc j'ai mis en delay(3); entre et ça marche bien, cependant lorsque je veux faire défiler 2 chiffres ensemble j'y arrive pas.
Est-ce que c'est ça l'histoire des 24 images secondes ?

Par exemple tu veux afficher 25 : il faut donc afficher 2 et 5. Donc première étape, séparé ses deux nombres.

25/10 = 2 * 10 + 5

donc pour trouver 2 on fait 25/10, en c :

byte Dizaine = MaValeur / 10; // retounre l'entier inférieur

Pour le reste c'est modulo :

Byte Unite = MaValeur % 10; // retourne le reste de la division Euclidienne

Deux lignes de code :wink:

Maintenant si tu as suivi et compris l'article de mon blog sur les interruptions temporelles, il te suffit, dans ta loop() de lancer toutes les 40 ms (1s/24) l'affichage de tes deux digits. Donc 20 ms / digit si tu en as deux

Alors après y'a des optimisations à apporter mais on verra ça plus tard :wink:

tst-56:
Et je pense pas que ça se fasse juste avec les deux lignes de code :zipper_mouth_face:

La, je me sens un peu (beaucoup) bête ^^ Merci beaucoup je vais tester ça de suite ayant apporté le projet chez moi =)
Et je suis sur 4 digits donc 10ms/digits si j'ai bien compris ?
Oui l'article sur votre blog est très complet mais j'ai toujours du mal a comprendre ce que le booléen fait là mais je vais le relire attentivement ^^
Encore merci.

RE:
Effectivement ça marche nickel avec modulo etc =) La je regarde votre tutoriel ;D

B@tto:
Maintenant si tu as suivi et compris l'article de mon blog sur les interruptions temporelles, il te suffit, dans ta loop() de lancer toutes les 40 ms (1s/24) l'affichage de tes deux digits. Donc 20 ms / digit si tu en as deux

La volonté y est mais j'avoue ne pas comprendre ^^ cependant j'ai essayé et ça marche

unsigned long Depart;
boolean Flag;
int MonDelai=1000;
int digit1 = 11; 
int digit2 = 10; 
int digit3 = 9;
int digit4 = 6; 
int a = 0;
int b = 0;
int segA = A1; 
int segB = 3; 
int segC = 4; 
int segD = 5; 
int segE = A0; 
int segF = 7; 
int segG = 8; 
int MaValeur = 99;
void setup() {                
  pinMode(segA, OUTPUT);
  pinMode(segB, OUTPUT);
  pinMode(segC, OUTPUT);
  pinMode(segD, OUTPUT);
  pinMode(segE, OUTPUT);
  pinMode(segF, OUTPUT);
  pinMode(segG, OUTPUT);

  pinMode(digit1, OUTPUT);
  pinMode(digit2, OUTPUT);
  pinMode(digit3, OUTPUT);
  pinMode(digit4, OUTPUT);
   Depart = millis(); // calcul du temps
  pinMode(13, OUTPUT);
} 
#define DIGIT_ON  HIGH
#define DIGIT_OFF  LOW
#define SEGMENT_ON  LOW
#define SEGMENT_OFF HIGH
byte Dizaine = MaValeur / 10; // retourne l'entier inférieur
byte Unite = MaValeur % 10; // retourne le reste de la division Euclidienne

void loop() {
  
if((millis()-Depart)>=MonDelai){     // si 1000 ms se sont écoulées
 
         Flag=!Flag;    // j'inverse l'état de mon booléen
         
         digitalWrite(5,Flag);   //  je change l'état de ma sortie
         
         Depart=millis();  // nouvelle enregistrement du point de départ
 
        }
   
AfficherChiffre(Unite,4);
AfficherChiffre(Dizaine,3);
  
   
     
}

void AfficherChiffre(byte Chiffre, byte Digit)
{

switch(Digit) {
case 1 :
digitalWrite(digit1,DIGIT_ON);
digitalWrite(digit2,DIGIT_OFF);
digitalWrite(digit3,DIGIT_OFF);
digitalWrite(digit4,DIGIT_OFF);
break;
case 2 :
digitalWrite(digit1,DIGIT_OFF);
digitalWrite(digit2,DIGIT_ON);
digitalWrite(digit3,DIGIT_OFF);
digitalWrite(digit4,DIGIT_OFF);
break;
case 3 :
digitalWrite(digit1,DIGIT_OFF);
digitalWrite(digit2,DIGIT_OFF);
digitalWrite(digit3,DIGIT_ON);
digitalWrite(digit4,DIGIT_OFF);
break;
case 4 :
digitalWrite(digit1,DIGIT_OFF);
digitalWrite(digit2,DIGIT_OFF);
digitalWrite(digit3,DIGIT_OFF);
digitalWrite(digit4,DIGIT_ON);
break;
case 5 :
digitalWrite(digit1,DIGIT_ON);
digitalWrite(digit2,DIGIT_ON);
digitalWrite(digit3,DIGIT_ON);
digitalWrite(digit4,DIGIT_ON);
break;

}

MaValeur apparaît correctement, cependant je n'arrive toujours pas a faire défiler les secondes en laissant les dizaines allumés.
J'ai du louper quelque chose ^^"

Ahhh mais oublie le Flag ici :wink: c'est pas un flag en plus ... bref oublie !

Nan mais tu calcules des unités et tes dizaines en dehors de la loop(). Il faut toute les 40 ms calculer et afficher en conséquence, et dans le if de surcoit sinon ça arrive tout le temps

D'accord je crois avoir compris x) j'essaye ça demain et je réédite ce poste :wink:
Merci beaucoup . :slight_smile:

RE:
Petite question, la constante "MonDelai" elle doit-être égale a 1000 ou à 40 ?

int MonDelai=20;
Depart = millis();
void loop() {
  
if((millis()-Depart)>=MonDelai){     

         byte Dizaine = MaValeur / 10; 
byte Unite = MaValeur % 10; 
  AfficherChiffre(Unite,4);
  delay(10);
AfficherChiffre(Dizaine,3);

       
         Depart=millis();  
        }
   
       
  
   
}

Comme ça ? Là ça m'affiche correctement la valeur que je demande dans le int = MaValeur
Je commence a vous demandez pas mal de chose, j'éspère que ça ne vous dérange pas ? sinon je me débrouillerais bien :wink: