Théorie d'une horloge binaire

Bonjour a tous,

Comme vous avez pu le voir dans le titre, j'ai un projet de longue date en tête, c'est de me faire une horloge binaire. Je me suis donc dit pourquoi pas essayé avec l'arduino.

Dans un premier temps, je souhaite vous présenté mon idée de projet. Voir si mon raisonnement est bon
et faisable.

Alors, pour ce qui est de l'horloge je compte partir sur une ds3231 (que j'ai déjà), mon idée serait de récuperer via la division et le modulo chaque valeur séparément.
Ex : 14 : 25 : 31s

  • 1
  • 4
  • 2
  • 5
  • 3
  • 1

je sais déjà le faire via le terminal et Serial.println Mais je bloque sur la façon comment exploiter/stocker ces valeurs pour ensuite les afficher sur mes leds.

Là pareil pour les leds vous me conseillerez quoi ? plutôt registre a décalage ou multiplexer ?

Désolé, pour le moment je n'ai pas encore foncer tête baisser et taper du code, :-[ Pour vous montrer une partie donc pas évident de répondre sans avoir trop d'informations.

Tout ce que je peux vous dire, c'est que pour la RTC, j'utilise la lib de Petre Rodan disponible ici vous avez une petite explication sur cette page

Voilà voilà :smiley:

Je continue mes recherches de mon coté. Apres si vous avez des exemples identiques a mon idée je suis preneur :wink:
D'avance merci.

@++

bienvenue Venom
(ce post aurait été plus adapté dans la section "Presentez vous" du sous forum "bar" comme introduction) !

familiarisez vous aussi avec les règles pour poster, elles peuvent différer des autres forum auxquels vous pouvez participer

Bonjour J-M-L,

Désolé. Mon internet a fait des siennes, j’ai donc poster le début de mon message avant qu’il ne soit perdu dans le néant.

J’ai éditer mon message et ajouter ma présentation dans la section adéquate. :smiley:

@++

j'ai vu - pas de souci — on attend de voir le projet !

Tu peux chercher des exemples sur Google : Arduino binary clock. Ça te donnera des idées pour le design et les composants à utiliser.

Il n'y a pas de règle, c'est à toi de voir ce que tu veux faire. La RTC est une option, tu peux aussi chercher l'heure sur Internet, grâce à un ESP8266 ou un ESP32 (qui se programment comme un arduino).

je sais déjà le faire via le terminal et Serial.println Mais je bloque sur la façon comment exploiter/stocker ces valeurs pour ensuite les afficher sur mes leds.

la librairie RTClib vous donne accès facile à heures minutes et secondes de votre DS3231, ensuite un test et soustraction (ou modulo et reste) vous donnent le premier et second chiffre. ensuite c’est juste une question d’allumer les bonnes LEDs en fonction de la valeur. Le framework Arduino intègre toute une série de macro-fonctions pour manipuler des bits afin d’extraire quels LEDs allumer ou éteindre

BitRead(x, n);
bitWrite(x, n, b);
bitSet(x, n);
bitClear(x, n);
bit(n);

Montrez nous comment vous faites. vous ne devez pas être loin

Là pareil pour les leds vous me conseillerez quoi ? plutôt registre a décalage ou multiplexer ?

pour une horloge de base HH:MM:SS il faut 4 bits par lettres donc 24 LEDs
sur un UNO ça ne passe pas, sur une MEGA c’est sans problème.
on peut aussi tricher pour diminuer le nombre de pins nécessaire avec un montage où on pilote la colonne à afficher (6 colonnes) et ensuite les 4 LEDs de cette colonne → 10 pins, ça marche partout mais faudra coder le balayage pour qu’avec la persistance rétinienne on voit les 6 ‘chiffres’

Merci de vos réponses.

Pour ce qui est de l’heure je préfère rester sur la rtc plutôt que l’esp car l’horloge ne sera peut être pas toujours près de ma box.

Pour ce qui est de bitread bitwrite merci je vais regarder.

Je suis tomber sur un site qui a exactement le projet que j’avais en tête ici je vais creuser de ce côté là si mes capacitée me le permettent. :smiley: après je me complique peut être va vie en faisant ça ?

Je vais déjà voir pour m’amuser avec le 74hc595 (j’en ai en stock).

Je vous montrerez l’avancer de cette étape. Ou bien je vous solliciterai ::slight_smile:

@++

on reste à l'écoute ! n'hésitez pas à explorer !

Bonjour, j’apporte les news.

J’ai commencer a utilisé l’arduino avec un 74HC595. Je suis tomber sur un tuto excellent qui explique bien le fonctionnement. J’arrive a de très bon résultats.

La preuve 8) :

Bon maintenant reste a voir comment envoyé au 74HC595 les valeurs retourner par la DS3231 :smiley: Car pour le moment le tuto explique via une boucle for next.

@++

Re, bon j’ai réusssssssssi 8) :smiley:
J’ai légerement modifier le tuo du 74HC595 et coller une partie de l’exemple DS3231, et ça fonctionne.

Je récupère simplement la valeur de t.sec qui correspond au pointeur de la librairie Ds3231 et j’envoie cette valeur au 74HC595 qui transforme ça en binaire. Tout simplement.

Voici mon code qui pour le moment ne gère que les secondes (breadbord oblige) :slight_smile:
Il me restera a voir comment envoyer les valeurs des minutes et heures aux 2 autres 74HC595 et comment faire la gestion des 3 en même temps. :o :confused:

Et voir pour séparer les 8 bits en 2.
0000 0000

 // partie DS3231
  #include <Wire.h>
  #include <ds3231.h>
  ts t; //ts est la structure que l'on peut trouver dans ds3231.h


  // partie 74HC595
  // Attention les led doivent etre relier en pull-up et non pull-down.
  // pour le montage ceux sont des led vertes avec une resistance de 220 ohms

  // Broche connectée au ST_CP du 74HC595
  const int verrou = 11;
  // Broche connectée au SH_CP du 74HC595
  const int horloge = 12;
  // Broche connectée au DS du 74HC595
  const int data = 10;



void setup() {
  { // partie DS3231
    Wire.begin(); //démarrer i2c (requis pour la connexion)
    DS3231_init(DS3231_INTCN); //enregistrer le ds3231 (DS3231_INTCN est l'adresse par défaut du ds3231, elle est définie par la macro pour qu'il n'y ait pas de perte de performance)
  }

  { // partie 74HC595
    // On met les broches en sortie
    pinMode(verrou, OUTPUT);
    pinMode(horloge, OUTPUT);
    pinMode(data, OUTPUT);
  }

}

void loop() {
    // partie DS3231
    DS3231_get(&t); //obtenir la valeur et passer à la fonction le pointeur à t, qui font une empreinte mémoire plus faible et une exécution plus rapide que l'utilisation du retour
    //DS3231_get() utilisera le pointeur de t pour changer directement la valeur de t (plus rapide, moins de mémoire utilisée)


    // partie 74HC595
    // On active le verrou le temps de transférer les données
    digitalWrite(verrou, LOW);
    // on envoi toutes les données grâce à notre belle fonction
    envoi_ordre(data, horloge, t.sec);
    // et enfin on relâche le verrou
    digitalWrite(verrou, HIGH);
    // une petite pause pour constater l'affichage
    delay(100);

  }



// procedure pour envoyer les bits au 74HC595
void envoi_ordre(int dataPin, int clockPin, char donnee)
{
    // on va parcourir chaque bit de l'octet
    for(int i=0; i<8; i++)
    {
        // on met l'horloge à l'état bas
        digitalWrite(clockPin, LOW);
        // on met le bit de donnée courante en place
        digitalWrite(dataPin, donnee & 0x01 << i);
        // enfin on remet l'horloge à l'état haut pour
        // faire prendre en compte cette dernière
        digitalWrite(clockPin, HIGH);
    }
}

i will be back

@++

bravo :slight_smile:

tenez voici un petit code à analyser:

#define dizaine(x) ((x) / 10)
#define unite(x) ((x) % 10)

void imprimeBinaire(uint8_t octet)
{
  for (int8_t i = 7; i >= 0; i--) {
    Serial.write(bitRead(octet, i) == 0 ? '0' : '1');
    if (i == 4) Serial.write(' '); // on met un espace au bout de 4 éléments
  }
}

void setup()
{
  Serial.begin(115200);
  // imaginons qu'il soit 21h43 et 56s
  uint8_t h = 21;
  uint8_t m = 43;
  uint8_t s = 56;

  // on veut chaque chiffre individuel --> les dizaines et unités

  uint8_t h_d = dizaine(h);
  uint8_t h_u = unite(h);

  uint8_t m_d = dizaine(m);
  uint8_t m_u = unite(m);

  uint8_t s_d = dizaine(s);
  uint8_t s_u = unite(s);

  Serial.print(F("h_d:\t")); imprimeBinaire(h_d); Serial.write('\t'); Serial.println(h_d);
  Serial.print(F("h_u:\t")); imprimeBinaire(h_u); Serial.write('\t'); Serial.println(h_u);
  Serial.print(F("m_d:\t")); imprimeBinaire(m_d); Serial.write('\t'); Serial.println(m_d);
  Serial.print(F("m_u:\t")); imprimeBinaire(m_u); Serial.write('\t'); Serial.println(m_u);
  Serial.print(F("s_d:\t")); imprimeBinaire(s_d); Serial.write('\t'); Serial.println(s_d);
  Serial.print(F("s_u:\t")); imprimeBinaire(s_u); Serial.write('\t'); Serial.println(s_u);

  // on sait que chaque chiffre indivuel est entre 0 et 9, donc sur 4 bits au max
  // on veut former un octet ayant comme partie haute  les 4 bits des dizaines
  // et comme partie basse les 4 bits des unités (par exemple)
  // il suffit donc de décaler nos bits à gauche de 4 positions pour les dizaines
  // et de coller les 4 bits des unités en partie basse (avec un OU Logique)
  // un masque n'est pas nécessaire car on sait qu'aucun bit n'est à 1 en partie haute des unités

  uint8_t h_bin = (h_d << 4) | (h_u); // OU binaire
  uint8_t m_bin = (m_d << 4) | (m_u); // OU binaire
  uint8_t s_bin = (s_d << 4) | (s_u); // OU binaire
  Serial.println(F("----"));
  Serial.print(F("h_bin:\t")); imprimeBinaire(h_bin); Serial.println();
  Serial.print(F("m_bin:\t")); imprimeBinaire(m_bin); Serial.println();
  Serial.print(F("s_bin:\t")); imprimeBinaire(s_bin); Serial.println();
}

void loop() {}

le code câble en dur qu’il est 21h43 et 56s juste par simplification (suffit de lire hour, minute et second de la RTC)

vous verrez dans le moniteur série (à 115200 bauds)

[color=purple]
h_d: [glow=green,2,300]0000[/glow] [color=red]0010[/color] 2
h_u: [glow=green,2,300]0000[/glow] [color=green]0001[/color] 1
m_d: [glow=green,2,300]0000[/glow] [color=blue]0100[/color] 4
m_u: [glow=green,2,300]0000[/glow] [color=maroon]0011[/color] 3
s_d: [glow=green,2,300]0000[/glow] [color=black]0101[/color] 5
s_u: [glow=green,2,300]0000[/glow] [color=navy]0110[/color] 6
----
h_bin: [color=red]0010[/color] [color=green]0001[/color]
m_bin: [color=blue]0100[/color] [color=maroon]0011[/color]
s_bin: [color=black]0101[/color] [color=navy]0110[/color]
[/color]

J’ai rajouté bien sûr ici des couleurs et on voit bien que les 8 digits ont les 4 bits de poids fort à 0 (normal car ils sont entre 0 et 9 au max) et on voit bien qu’on a réussi à combiner les parties hautes et basses des différentes variables pour fabriquer un octet avec 4 bits de poids fort pour les dizaines et 4 bits de poids faible pour les unités

en espérant que ça vous aide :slight_smile:

Oh ! Merci. Je n'en demandé pas tant.
Je vais étudier votre code. Merci pour votre aide. 8)

@++

Bonjour,

Merci J-L-M pour vos explications / exemples. J’ai réussi a introduire votre exemple dans mon code est le résultat est là 8) :stuck_out_tongue:

J’ai le résultat souhaiter. Test fait avec les secondes, j’ai bien les unités séparer des dizaines.
Encore merci.

Voici mon code :

  // partie DS3231
  #include <Wire.h>
  #include <ds3231.h>
  ts t; //ts est la structure que l'on peut trouver dans ds3231.h


  // variables pour séparer les unites des dixaines
  #define dizaine(x) ((x) / 10)
  #define unite(x) ((x) % 10)


  // partie 74HC595
  // Attention les led doivent etre relier en pull-up et non pull-down.
  // pour le montage ceux sont des led vertes avec une resistance de 220 ohms

  // Broche connectée au ST_CP du 74HC595
  const int verrou = 11;
  // Broche connectée au SH_CP du 74HC595
  const int horloge = 12;
  // Broche connectée au DS du 74HC595
  const int data = 10;



void setup() {
    // partie DS3231
    Wire.begin(); //démarrer i2c (requis pour la connexion)
    DS3231_init(DS3231_INTCN); //enregistrer le ds3231 (DS3231_INTCN est l'adresse par défaut du ds3231, elle est définie par la macro pour qu'il n'y ait pas de perte de performance)
  

    // partie 74HC595
    // On met les broches en sortie
    pinMode(verrou, OUTPUT);
    pinMode(horloge, OUTPUT);
    pinMode(data, OUTPUT);

}

void loop() {
    // partie DS3231
    DS3231_get(&t); //obtenir la valeur et passer à la fonction le pointeur à t, qui font une empreinte mémoire plus faible et une exécution plus rapide que l'utilisation du retour
    //DS3231_get() utilisera le pointeur de t pour changer directement la valeur de t (plus rapide, moins de mémoire utilisée)

    
    // on recupere les heures, minutes, secondes du Ds3231
    uint8_t h = t.hour;
    uint8_t m = t.min;
    uint8_t s = t.sec;


    // on separe les chiffre individuellement. les dizaines et unités
    uint8_t h_d = dizaine(h);
    uint8_t h_u = unite(h);

    uint8_t m_d = dizaine(m);
    uint8_t m_u = unite(m);

    uint8_t s_d = dizaine(s);
    uint8_t s_u = unite(s);


    // on additionne les 8 bits (4 pour les dizsaine, 4 pour les unites)
    // on sait que chaque chiffre indivuel est entre 0 et 9, donc sur 4 bits au max
    // on veut former un octet ayant comme partie haute  les 4 bits des dizaines
    // et comme partie basse les 4 bits des unités
    // il suffit donc de décaler nos bits à gauche de 4 positions pour les dizaines
    // et de coller les 4 bits des unités en partie basse (avec un OU Logique)
    uint8_t h_bin = (h_d << 4) | (h_u); // OU binaire
    uint8_t m_bin = (m_d << 4) | (m_u); // OU binaire
    uint8_t s_bin = (s_d << 4) | (s_u); // OU binaire
    

    // on envoie le tout aux 74HC595
    // partie 74HC595
    // On active le verrou le temps de transférer les données
    digitalWrite(verrou, LOW);
    // on envoi toutes les données grâce à notre belle fonction
    envoi_ordre(data, horloge, s_bin);
    // et enfin on relâche le verrou
    digitalWrite(verrou, HIGH);
    // une petite pause pour constater l'affichage
    delay(100);

  }



// procedure pour envoyer les bits au 74HC595
void envoi_ordre(int dataPin, int clockPin, char donnee)
{
    // on va parcourir chaque bit de l'octet
    for(int i=0; i<8; i++)
    {
        // on met l'horloge à l'état bas
        digitalWrite(clockPin, LOW);
        // on met le bit de donnée courante en place
        digitalWrite(dataPin, donnee & 0x01 << i);
        // enfin on remet l'horloge à l'état haut pour
        // faire prendre en compte cette dernière
        digitalWrite(clockPin, HIGH);
    }
}

Je pense avoir bon puisque ça fonctionne. :smiley:

Reste a voir la gestion avec trois 74HC595 (branchement et surtout envoi) :o :disappointed_relieved:

@++

bravo !!! :slight_smile:

Bon je me suis renseigné sur l'ajout de plusieurs 74hc595 voici ce que j'ai cru comprendre :

On relie les pin's ST et SH ensemble, ensuite on relie la pin Q7' du premier sur DS du second. Et ensuite on envoie les données du 74hc595 le plus loin jusqu'au plus près c'est bien ça ?

@++

Oui l’idée est de faire rentrer le bit qui « tombe » dans le prochain composant (un petit tuto et du code ici si vous ne l’avez pas trouvé)

Donc quand on pousse les bits on met d’abord ceux qui doivent aller au bout de chaîne et on décale jusqu’à avoir tout transmis

Comme vous avez besoin de 24 bits il vous faut 3 composants

J-M-L:
l’idée est de faire rentrer le bit qui « tombe » dans le prochain composant

Merci pour cette illustration. Je comprends mieux comment fonctionne les composants entre eux :wink:

Merci pour le lien, c’est en effet un des tutos que je suit en parallèle d’ici. :stuck_out_tongue:

Reste donc a faire le montage et observer le résultat :slight_smile:

@++

Attention, la DS3231 renvoie en format BCD, il faut convertir en binaire.
Tu pourrais aussi utiliser un MCP23016 pour piloter les LED.
Tu penses utiliser combien de LED?

Salut Gerard68, :wink:

En faite il me faut 20 LEDs et dans l'idée 3 bouton pour incrémenter les heures, minutes et secondes. (En cas de réglages)

Mais comme j'ai l'avantage d'être partie avec des 74hc595, je n'ai pas besoin mcp23016. Car les 74hc595 permettent avec 3 fil d'avoir 8 sortie digital de plus sur l'arduino 8)

En faite je suis partie de cette idée

@++

Salut Venom, c'est moi de Fanstas-PIC,
Je ne comprends pas comment on lit l'heure.
En binaire, il faut 6 LED pour les minutes et 6 pour les secondes. Pour les heures 5 suffisent.