Horloge 7 segments DS3231 - besoin de conseils

Bonjour,

Je vous écris car je débute en Arduino et je souhaite réaliser une horloge à l'aide d'un module DS3231. Le but final étant une horloge à Nixie (comme c'est original ^^) mais pour le moment je m'entraine avec des 7-segments et des sn7447.

Cependant je rencontre un problème, lorsque je récupère l'heure à l'aide du DS3231 le 7 segment devient fou.

Je pense que c'est un problème de type ou ma méthode de bouclage avec le while qui n'est peut-être pas très propre mais je suis dans une impasse malgré tout mes essais.

Voilà le code:

#include <Wire.h>
#include "RTClib.h"

RTC_DS3231 rtc;

int tab[10][4] = {
    {0,0,0,0},     //0
    {1,0,0,0},    //1
    {0,1,0,0},    //2
    {1,1,0,0},   //3
    {0,0,1,0},    //4
    {1,0,1,0},   //5
    {0,1,1,0},   //6
    {1,1,1,0},  //7
    {0,0,0,1},    //8
    {1,0,0,1}    //9
};

void setup () {

    pinMode(0, OUTPUT);
    pinMode(1, OUTPUT);
    pinMode(2, OUTPUT);
    pinMode(3, OUTPUT);
    pinMode(10, OUTPUT);
    pinMode(11, OUTPUT);

  Serial.begin(9600);
}

void loop () {
    DateTime now = rtc.now();

    int seconde = now.second();
    int seconde1 = seconde;

      int dec = seconde/10;
      int uni = seconde%10;

    while(seconde==seconde1){
    
      digitalWrite(0, tab[dec][0]);
      digitalWrite(1, tab[dec][1]);
      digitalWrite(2, tab[dec][2]);
      digitalWrite(3, tab[dec][3]);
        
      digitalWrite(11, HIGH);
      delay (10);
      digitalWrite(11, LOW);
      delay(1);

      digitalWrite(0, tab[uni][0]);
      digitalWrite(1, tab[uni][1]);
      digitalWrite(2, tab[uni][2]);
      digitalWrite(3, tab[uni][3]);
    
      digitalWrite(10, HIGH);
      delay (10);
      digitalWrite(10, LOW);
      delay(1);
      DateTime now = rtc.now();

      int seconde1 = now.second();
    }   
}

Je vous explique un peu le code, 'tab' est une matrice de commande du BCD, je n'utilise pas les deux 7-segments en même temps (je ferais ça sur les nixies pour limiter la consommation).

Si quelqu'un a une idée pour résoudre mon problème et aussi une méthode plus propre pour la boucle je suis preneur.

PS: Je suis un arduino UNO.

Merci,
Dimitri

Est ce que tu as essayé de séparer les difficultées ?

  1. SANS DECODEUR BCD as tu vérifié que l'info que tu reçois du DS3231 est correcte ?

  2. SANS DS3231 quand tu envoie une séquence connue et bien déterminée au décodeur est-ce que le résultat est conforme à ce que tu attends ?

Tant que ces deux tests ne donnent pas des résultats corrects ce n'est pas la peine d'assembler le tout.
Faire des tests unitaires est le minimum à faire quand on développe (quelque soit le domaine) : pour n'avoir qu'un seul problème a régler à la fois.

Oui, pardon je ne l'ai pas précisé mais n'ayant reçu le module que très récemment j'avais déjà un montage fonctionnel avec les 7segments.

Le code de ce dernier est le suivant :

int tab[10][4] = {
    {0,0,0,0},     //0
    {1,0,0,0},    //1
    {0,1,0,0},    //2
    {1,1,0,0},   //3
    {0,0,1,0},    //4
    {1,0,1,0},   //5
    {0,1,1,0},   //6
    {1,1,1,0},  //7
    {0,0,0,1},    //8
    {1,0,0,1}    //9
};

//int decminute = 0;
//int uniminute = 0;
//int decheure = 0;
//int uniheure = 0;

static unsigned long t=0;
int compteur =0;

void setup() {
  //RTC.adjust(DateTime(__DATE__, __TIME__)); 
  //initialisation du RTC à laisser commenter en utilisation normale
    pinMode(0, OUTPUT);
    pinMode(1, OUTPUT);
    pinMode(2, OUTPUT);
    pinMode(3, OUTPUT);
    pinMode(10, OUTPUT);
    pinMode(11, OUTPUT);

    t=millis();
}

void loop() {
   int dec = (compteur%100)/10;
   int uni = compteur%10;
   
   while(millis()-t < 1000){
    
      digitalWrite(0, tab[dec][0]);
      digitalWrite(1, tab[dec][1]);
      digitalWrite(2, tab[dec][2]);
      digitalWrite(3, tab[dec][3]);
    
      digitalWrite(11, HIGH);
      delay (10);
      digitalWrite(11, LOW);
      delay(1);

      digitalWrite(0, tab[uni][0]);
      digitalWrite(1, tab[uni][1]);
      digitalWrite(2, tab[uni][2]);
      digitalWrite(3, tab[uni][3]);
    
      digitalWrite(10, HIGH);
      delay (10);
      digitalWrite(10, LOW);
      delay(1);
   }
   t=millis();
   compteur = compteur +1;
}

Je créé un compteur de 0 à 99 avec à peu près 1 seconde d'intervalle entre chaque numéros.

De plus j'ai aussi testé le DS3231 seul, j'arrive bien à afficher dans la console les informations relatives à la date, l'heure et le temps unix.

Je pense que mon problème pourrait venir du passage de 'now.second()' à 'int seconde'. Je me dis que malgré la définition de seconde en int, il doit mal transposer et au final lors de l'appel 'digitalWrite(0, tab[uni][0]);' il ne comprend pas 'uni' comme un indice entier. Je ne vois que cela mais, je ne suis, comme je l'ai dit pas un expérimenté du sujet.

Merci en tout cas de prendre le temps pour m'aider ça fait plaisir, c'est mon premier post sur un forum.
Dimitri

Bonjour,

Déjà tu enlèves ton while qui ne sert à rien.

Ensuite tu affiches tes valeurs sur le moniteur serie

Serial.println(uni);
Serial.println(dec);

Il faut initialiser la liaison série dans le setup

Serial.begin(9600);

Bonjour Kamill,

L'initialisation de la liaison série est déjà dans le setup.

Par ailleurs peux_tu développer pourquoi le while est ici inutile ?

Parce que la loop est exécutée en boucle (comme son nom l'indique), il est donc inutile de mettre une boucle à l'intérieur.
Que donne l'affichage de tes variables sur le moniteur série?

Est ce que tu utilises des 7447 pour piloter tes afficheurs?
Si oui, tu n'as pas besoin de conversion, ce qui vient de la RTC est du BCD et tu peux tout de suite envoyer vers les 7447.
PS : je préfère le 74247 parce qu'il affiche 6 et 9 avec 6 segments contrairement au 7447.
Pour le 6, c'est le segment a et le 9 le segment d qui sont absents avec le 7447.

Le while me servait plutôt à gérer la commutation de mes affichages mais effectivement c'est surement, inutile, je pense que j'avais peur que la partie hors du while soit un peu longue et que ca affecte l'affichage.

pour ce qui est des variables, la console m'indique bien les valeurs souhaitées, je vois bien les dizaines et unités en chiffre entier.
Ce qui 'a fait penser à ce problème de type c'est que j'ai vu plusieurs personnes avec des codes du type : Serial.println(now.seconde(), DEC). Quelqu'un sait à quoi sert le DEC et en quoi est-il nécessaire parfois ?

DEC, c'est pour dire qu'il faut afficher en décimal. C'est la valeur par défaut donc c'est inutile de la mettre.
Si tes valeurs sont bonnes, ça devrait fonctionner. Qu'est ce qui se passe exactement?

Bonjour Gerard,

Je vais te poser une question bête mais comment je fais pour lui envoyer directement comme tu dis le signal ? je ne sais que piloter mes sorties une à une, je veux dire comment dire à l'arduino de sortir du BCD sur ces 4 pins la ?

est-ce tu entends que now.second() est un vecteur de dimension 4 ? dans ce cas les 4 bits et que je peux l'utiliser comme ceci : now.second()[0], now.second()[1],...

PS: je suis d'accord pour le 'problème' d'affichage des 7447 mais c'est seulement un circuit de test avant de passer sur de 7441 pour les nixies.

En enlevant la boucle while, mais en ne modifiant rien d'autre pour le moment, le programme continue à me retourner les bonnes valeurs dans la console mais des valeurs aberrantes sur le 7segments, la je peux lire 77, 73 ,7c (le caractère 12 ou 13 du 7447), ces 3valeurs tournent en boucle et même pas au rythme des secondes.

Tu es vraiment sur de ton cablage?

affirmatif chef, quand je ne cherche pas à obtenir l'heure par le RTC l'affichage se comporte très bien.

Je viens de m'apercevoir que tu utilises le pins 0 et 1. Ces pins sont utilisées pour la liaison série donc sont sujettes à plein d'états parasites (pour ton programme).

Kamill tu as résolu mon problème, effectivement simplement en changeant les pins de sortie tout marche nickel !

Merci beaucoup pour votre aide !

socom93:
Bonjour Gerard,

Je vais te poser une question bête mais comment je fais pour lui envoyer directement comme tu dis le signal ? je ne sais que piloter mes sorties une à une, je veux dire comment dire à l'arduino de sortir du BCD sur ces 4 pins la ?

est-ce tu entends que now.second() est un vecteur de dimension 4 ? dans ce cas les 4 bits et que je peux l'utiliser comme ceci : now.second()[0], now.second()[1],...

PS: je suis d'accord pour le 'problème' d'affichage des 7447 mais c'est seulement un circuit de test avant de passer sur de 7441 pour les nixies.

Tu as résolu ton souci?