[Info] Horloge binaire

Bonjour à tous je me permets de crée un post pour demander quelque information pour mon projet d’horloge binaire

Je suis un débutant en programmation je m’y connais un peut en Electronique, je sais utiliser l’arduino (je suis électricien a la base) soient gentil avec moi c’est mon premier post ^^

J’ai déjà trouvé pas mal d’information et divers code mais jamais ce que j’avais besoin

J’aimerai piloter mon horloge à l’aide d’un arduino mini pro (je fais mes tests avec un micro), 3x74HC595 et un module rtc pour retenir l’heure

J’ai réalisé une petite image de mon prototype pour faire simple ^^ elle n’est pas vraiment parfaite mais sa suffira pour donne une idée ^^

J’ai réussi a créé un code “fonctionnel” mais qui ne l’est pas vraiment, je m’explique normalement dans une horloge binaire les unités des heure/minute/seconde se compte en binaire sur les 4 première led et les dizaines sur les 3/2 led suivante, dans mon cas il ne sépare pas les unités des dizaines

Pour faire “simple” quand il écrit le chiffre 15 en binaire il l’écrit avec les 4 première led " 1111 " Alor qu’il devrai l’écrire avec les 3 autre led " 001 / 1001 "

Je pense avoir la solution dans la partie du code que j’ai récupéré mais je n’arrive pas à la comprendre

byte decodeBCD(byte bcdValue)
{
 return  (10 * (bcdValue >> 4)) + (0xf & bcdValue);
}

byte encodeBCD(byte value)
{
  return ((value/10)<< 4) | (value % 10);
}

Sinon voici mon code

#include <Wire.h>
#include "RTClib.h"
RTC_DS1307 RTC;


int latchPin = 8;
int clockPin = 12;
int dataPin = 11;



void setup() {
    Serial.begin(9600);
    Wire.begin();
    RTC.begin();
    pinMode(latchPin, OUTPUT);
    pinMode(clockPin, OUTPUT);
    pinMode(dataPin, OUTPUT);
    RTC.adjust(DateTime(__DATE__, __TIME__));
    
}


byte bcdSecond;
byte bcdMinute;
byte bcdHour;
    

void loop() {
  DateTime now = RTC.now();
  
  bcdSecond= now.second();
  bcdMinute= now.minute();
  bcdHour= now.hour();
  
    
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, MSBFIRST, bcdHour);  
  shiftOut(dataPin, clockPin, MSBFIRST, bcdMinute);   
  shiftOut(dataPin, clockPin, MSBFIRST, bcdSecond);  
  digitalWrite(latchPin, HIGH);
  
  
}

Pour bien faire il faudrait que les 74h595 «oublie » leur première sortie c’est plus simple pour les pcb :slight_smile:

Pouvez-vous m’aider à comprendre la partie du code qui me manque et à l’appliquer correctement ? J’ai essayé de chercher pendant plusieurs jours mais je n’arrive pas à trouver quelque chose de clair en français et surtout je ne sais pas quoi chercher exactement : /

Bonjour les Amis, Pour l’heure je ne suis pas capable de pouvoir t’aider, car je ne suis pas certain d’avoir vraiment compris les détails de ton projet. En particulier l’aspect électronique. L’idée consiste à te poser quelques questions pour mieux comprendre, ainsi nous serons tous certainement mieux documentés pour t’aider. A) Je crois avoir compris que tu désires te réaliser une horloge avec six afficheurs qui sous forme « binaire pur » vont t’indiquer l’heure. Exact ? B) Pour obtenir l’heure tu utilises un circuit intégré spécialisé représenté en vert sur ton dessin. Exact ? C) Pour interfacer Arduino avec tes LED tu a intercalé des circuits intégrés logiques. Ce sont des registres à décalage ? Sur ton dessin je ne vois pas de résistances de limitation de courant pour tes LED. Ce sont des modèles « auto régulés » ? Amicalement : Nulentout

http://fr.openclassrooms.com/sciences/cours/arduino-pour-bien-commencer-en-electronique-et-en-programmation/presentation-du-74hc595

Ton problème vient du fait qu'actuellement tu affiches l'heure en binaire. alors que tu voudrais que l'heure soit affichée en BCD (Binary Coded Decimal)

Il faudrait faire ça:

  shiftOut(dataPin, clockPin, MSBFIRST, encodeBCD(bcdHour));  
  shiftOut(dataPin, clockPin, MSBFIRST, encodeBCD(bcdMinute));   
  shiftOut(dataPin, clockPin, MSBFIRST, encodeBCD(bcdSecond));

Du coup ce ne sera plus une horloge binaire mais une horloge BCD XD

Avec votre permission les amis, je souhaite profiter de ce sujet pour poser une question que je ne crois pas hors sujet. Depuis que je "triture" des µp, j’ai appris à traiter les entrées et les sorties avec des masques logiques. Pour ce faire, on travaille avec des mots entiers, en l’occurrence des octets par exemple. Est-il possible avec Arduino de considérer par exemple que les E/S binaires 0 à 7 puissent constituer un OCTET et travailler en bloc sur ce dernier. Par exemple forcer des 0 partout avec une instruction de type OCTET = 0 ou forcer des "1" avec un masque du genre OCTET = OCTET II 5 ? Du reste avec les opérateurs booléens j’ai encore deux difficultés : A) Pour le OU on utilise II est-ce le I majuscule ou un autre caractère ? B) Existe t’il l’opérateur OU EXCLUSIF, car sans lui le traitement par masques logiques serait bancal ? C) Merci d’avance pour vos réponses éventuelles : Nulentout.

On peut utiliser les macro PINx et PORTx pour lire et écrire dans les ports du microcontroleur ( x = A, B, C, D, ...)

Le OU c'est | (la barre vertical AltGr-6 sur les claviers français) Le OU exclusif c'est ^

Un pense-bête http://users.ece.utexas.edu/~adnan/c-refcard.pdf

http://arduino.cc/en/Reference/PortManipulation

D’abord Merci beaucoup pour vos réponses :slight_smile: ça fait plaisir de trouver un peu d’aide :slight_smile:

@nulentout :
A) oui je désire afficheur l’heure en binaire pur sur 6 afficheur :slight_smile: sa devrai ressemble à quelque chose du genre

B) oui j’utilise un module rtc (real time clock) qui fonctionne a l’aide d’un BS1307 ^^
C) oui les 74hc595 sont des registre a décalage, pour les résistances il n’y en a pas sur mon dessin parce que je les ai oubliée :wink: mais j’utilise des led normal avec une résistance de 220?

@B@tto:
Merci j’avais déjà lus et relus cette page (j’ai imprimé les 326 pages du guide Oo ^^) mais j’ai toujours du mal à comprendre la partie de mon code

@fdufnews :

WaZaaaa Parfait bien vus :slight_smile: sa fonctionne déjà un petit peut mieux j’ai encore quelque souci mais je pense que c’est dû au prototypage

Par contre sur mon prototype actuel j’utilise les broche de Q0 a Q6 est ‘il possible de modifier pour qu’il oublie la broche Q0 et commence à partir de Q1 jusqu’à Q7 ?

Sinon j’ai compris qu’elle partie du code est vraiment “importante” mais je n’arrive toujours pas à la comprendre : /

byte encodeBCD(byte value)
{
  return ((value/10)<< 4) | (value % 10);
}

Je pense avoir compris quelque chose tout d’un coup en écrivant mon message

Il prend la valeur il la divise en 10 et l’écrit en se décalent de 4 bit vert la gauche ?
Ou il prend la valeur la divise par 10 et il écrit se qu’il reste

… j’ai compris ^^

Donc pour ne pas utiliser la broche Q0 je devrai faire ceci ?

byte encodeBCD(byte value)
{
  return ((value/10)<< 5) | ((value % 10) << 1);
}

Je compte aussi rajouter des boutons pour règle l’heure et les minute il faudra donc aussi que je comprenne la partie “decodeBCD”

byte decodeBCD(byte bcdValue)
{
 return  (10 * (bcdValue >> 4)) + (0xf & bcdValue);
}

Mais là je ne comprends vraiment rien :confused:

Merci pour ton pense-bête :smiley: sa m’a aider à comprendre

alfredcore:

byte encodeBCD(byte value)

{
  return ((value/10)<< 4) | (value % 10);
}




Je pense avoir compris quelque chose tout d'un coup en écrivant mon message 

Il prend la valeur il la divise en 10 et l'écrit en se décalent de 4 bit vert la gauche ? 
Ou il prend la valeur la divise par 10 et il écrit se qu'il reste

Exactement

alfredcore:
… j’ai compris ^^

Donc pour ne pas utiliser la broche Q0 je devrai faire ceci ?

byte encodeBCD(byte value)

{
  return ((value/10)<< 5) | ((value % 10) << 1);
}

Exactement cela décale tout d’un bit vers la gauche

alfredcore:
Je compte aussi rajouter des boutons pour règle l’heure et les minute il faudra donc aussi que je comprenne la partie “decodeBCD”

byte decodeBCD(byte bcdValue)

{
return  (10 * (bcdValue >> 4)) + (0xf & bcdValue);
}




Mais là je ne comprends vraiment rien :/

C’est pourtant le même raisonnement que pour encodeBCD.
Lorsqu’un nombre est encodé en BCD on trouve les dizaines sur les 4 poids forts de l’octet et les unités sur les 4 poids faibles.
Si on passe la valeur 0x15 dans bcdValue
(0xf & bcdValue) isole les 4 poids faibles donc donne 5
(10 * (bcdValue >> 4)) se décompose ainsi:
(bcdValue >> 4) décale bcdValue de 4 bits vers la droite. Donc les 4 poids forts se retrouvent à la place des 4 poids faibles donc le 0x15 devient 0x01
ensuite on le multiplie par 10
et on y ajoute les poids faibles
au final on 1 x 10 + 5 ce qui fait bien 15

Encore Merci beaucoup pour toute c'est explication sa m'aide beaucoup à comprendre la logique des choses :)

J’ai une autre question, je compte rajouter des boutons pour changer l'heure mais je bloque sur le fait de mettre à jour directement le module rtc apprêt quelque recherche j'ai essayé plusieurs chose mais sans succès pouvez-vous me remettre sur le droit chemin ?

void setTime()
{
  DateTime now = RTC.now();
 RTC.adjust(DateTime(now.year(2014), now.month(02), now.day(21), now.hour(decodeBCD(bcdHour)), now.minute(decodeBCD(bcdMinute)) + 1, 0));
}

et

 void setTime()
{
  DateTime now = RTC.now();
  RTC.adjust(DateTime:"FEB 21 2014","(decodeBCD(bcdHour)):(decodeBCD(bcdMinute)):00");
}

Bonjour les Amis, C'est pour une petite question relative au "pense-bête" dont fdufnews a eu la gentillesse de me donner le lien : http://users.ece.utexas.edu/~adnan/c-refcard.pdf C'est effectivement un document très utile que je ne vais pas tarder à imprimer, car je passe mon temps à chercher la syntaxe en ligne quand je suis en train de coder sur Arduino. Ma question : Ce document me semble une référence pour le langage C "normalisé". Le C d'Arduino est-il 100% conforme où existe t'il des différences ? Pour ma question sur le caractère | je suis une mule ... je le savais car je l'ai déjà utilisé. Par moment j'ai des trous dans ma SD RAM, faut que j'avale rapidos des vitamines. :)

Pour remettre à l'heure le DS1307 c'est dommage, je ne peux pas t'aider. Je me suis fait un petit projet avec le DS1302 qui affiche l'heure sur un écran LCD. J'utilise les boutons du SHIELD de cet écran LCD pour remettre à l'heure mon horloge. Mais pas de chance, les protocoles du DS1302 et ceux du DS1307 sont très différents. Mon code ne te servirait à rien.

Bonjour, Moi aussi j'ai une horloge que je mets à l'heure à l'aide de boutons. Celle actuellement accrochée au mur de ma salle à manger est à base de DS1307 et celle en cours de construction sur la table de la salle à manger est à base de DS3234, plus précis :D

J'utilise la RTCLib et voici un extrait du code qui permet de mettre à jour l'heure et les minutes:

//réglage des heures et des minutes buttonState1 et  buttonState2 sont les états des boutons de réglage des heures et minutes respectivement
//quand les heures atteignent 24 ou les minutes 60, elles repassent à 0
        if(buttonState1 || buttonState2){
            if(buttonState1){
                now = DateTime(now.year(),now.month(),now.day()
                ,(now.hour()+1)%24,now.minute(),now.second());
                #ifdef DEBUG_SERIAL
                    Serial.println("+1h");
                #endif
            }else{
                if(buttonState2){
                    now = DateTime(now.year(),now.month(),now.day()
                ,now.hour(),(now.minute()+1)%60,0);
                    #ifdef DEBUG_SERIAL
                    Serial.println("+1mn");
                    #endif
                }               
            }
//mise à l'heure de l'horloge
RTC.adjust(now);

Merci beaucoup patg_ pour ton bout de code sa fonctionne déjà un peu mieux comme sa :) mais petit problème j'arrive à changer l’heure /minute mais quand c'est fait le rtc arête de compter et "freezer" ? Enfin c'est toujours les même heure/min/sec qui sont affiché

Bizarre.

Est-ce que RTC.isrunning() te retourne bien true? Est-ce que RTC.now().unixtime() s'incrémente toutes les secondes?

je n’ai pas de RTC.isrunning() ni de RTC.now().unixtime() dans mon code oO ^^

Comme je le disais plus haut je n’ai aucune formation en programmation j’essaye de me débrouiller comme je le peux pour faire ce que je veux :wink:

Je sais que RTC.isrunning() est fait pour tester l’état du rtc via la communication série mais je ne sais pas exactement comment l’insère dans mon code

Par contre RTC.now().unixtime() c’est quoi ça ? :stuck_out_tongue:

mtn j’ai découvert un autre problème : / il continue de changer l’heure quand je ne fais rien, je pense à un mauvais contact du au prototypage

mon code pour le moment

//mon test

#include <Wire.h>
#include "RTClib.h"
RTC_DS1307 RTC;


int latchPin = 8;
int clockPin = 12;
int dataPin = 11;

const int BouttonH = 5;
const int BouttonM = 4;

int sBouttonH = 1;
int clkBouttonH = 0;
int sBouttonM = 1;
int clkBouttonM = 0;


void setup() {
    Serial.begin(9600);
    Wire.begin();
    RTC.begin();
    pinMode(latchPin, OUTPUT);
    pinMode(clockPin, OUTPUT);
    pinMode(dataPin, OUTPUT);
    pinMode(BouttonH, INPUT);
    pinMode(BouttonM, INPUT);
  }
  
    
}


byte bcdSecond;
byte bcdMinute;
byte bcdHour;
    

byte decodeBCD(byte bcdValue)
{
 return  (10 * (bcdValue >> 5)) + ((0xf & bcdValue) >> 1 );
}

byte encodeBCD(byte value)
{
  return ((value/10)<< 5) | ((value % 10) << 1 );
}

void loop() {
  DateTime now = RTC.now();
  
  bcdSecond= now.second();
  bcdMinute= now.minute();
  bcdHour= now.hour();
  
  sBouttonH = digitalRead(BouttonH);
if(sBouttonH == 1)
  clkBouttonH = 0;
sBouttonM = digitalRead(BouttonM);
if(sBouttonM == 1)
  clkBouttonM = 0;
  
  
  
        if(sBouttonH == 0)
      {
        clkBouttonH = clkBouttonH++;
        if(clkBouttonH > 2){
        now = DateTime(now.year(),now.month(),now.day()
				,(now.hour()+1)%24,now.minute(),now.second());
        }
      }
      //idem pour les minutes
          if(sBouttonM == 0)
      {      
        clkBouttonM = clkBouttonM++;
        if(clkBouttonM > 2){
        now = DateTime(now.year(),now.month(),now.day()
				,now.hour(),(now.minute()+1)%60,0);
        }
      }
    
    
  
  
RTC.adjust(now);		
  
    
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, MSBFIRST, encodeBCD(bcdHour));  
  shiftOut(dataPin, clockPin, MSBFIRST, encodeBCD(bcdMinute));   
  shiftOut(dataPin, clockPin, MSBFIRST, encodeBCD(bcdSecond)); 
  digitalWrite(latchPin, HIGH);
  
  
  
    //We print the day
    Serial.print(now.day(), DEC);
    Serial.print('/');
    Serial.print(now.month(), DEC);
    Serial.print('/');
    Serial.print(now.year(), DEC);
    Serial.print(' ');
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.print(now.second(), DEC);
    Serial.println();

  }

nulentout: Ma question : Ce document me semble une référence pour le langage C "normalisé". Le C d'Arduino est-il 100% conforme où existe t'il des différences ?

Arduino s'appuie sur les compilateurs C et C++ pour AVR en ajoutant une surcouche pour "simplifier" l'usage pour les novices. Donc l'environnement Arduino n'apporte à priori pas de limitation au langage. Les limitations sont celles du compilateur qui n'implémente pas certaines fonctionnalités trop lourdes pour un microcontrôleur.

Pour les courageux, la doc est là: http://www.nongnu.org/avr-libc/

alfredcore: je n'ai pas de RTC.isrunning() ni de RTC.now().unixtime() dans mon code oO ^^

Ajoute-le comme ça: Serial.println(RTC.isrunning()) ; et regarde ce que ça te donne dans le moniteur série.

alfredcore: Par contre RTC.now().unixtime() c'est quoi ça ? :P

Ca récupère le nombre de secondes écoulées depuis le 1er Janvier 1970:

Serial.print("nb de secondes depuis 1970: ");
Serial.println(RTC.now().unixtime());

D’accord je comprends un peu mieux merci :) Alor j'ai fait le test comme dit et ça me donne sa :)

21/2/2014 12:22:0
nb de secondes depuis 1970: 1392985320
1
21/2/2014 12:22:0
nb de secondes depuis 1970: 1392985320
1
21/2/2014 12:22:0
nb de secondes depuis 1970: 1392985320
1
21/2/2014 12:22:0
nb de secondes depuis 1970: 1392985320
1
21/2/2014 12:22:0
nb de secondes depuis 1970: 1392985320
1

Par contre sans avoir de bouton connecter il modifie seul l'heure /minute

au debut il etai comme sa

1
21/2/2014 15:24:0
nb de secondes depuis 1970: 1392996240

et a la fin

21/2/2014 21:34:0
nb de secondes depuis 1970: 1393018440
1

Je crois comprends: Es-tu sûr que tu n'appelles

RTC.adjust(now);

que lorsqu'un bouton est appuyé?

Là tout se passe comme si tu appelais

RTC.adjust(now);

à chaque itération de loop() avec pour effet une heure qui ne change pas puisque tu remets à l'ancienne heure à chaque itération.

Effectivement tu as raison :slight_smile: j’ai modifié sa passe un peu beaucoup mieux :slight_smile: il compte enfin correctement apprêt avoir modifié l’heure :smiley:

Mais j’ai toujours un problème pour le changement d’heure :confused: et j’ai trouvé pourquoi mais je n’ai pas trouvé comment modifier correctement :slight_smile: je cherche ^^

Enfait dans mon “code” il met à jour les heure/minute uniquement quand il n’y a rien de connecter sur les borne quand les deux sont connecter il ne modifie plus l’heure il faudrait que j’inverse, mais comme je n’ai pas créé cette partie du code moi-même j’ai du mal :confused:

//mon test

#include <Wire.h>
#include "RTClib.h"
RTC_DS1307 RTC;


int latchPin = 8;
int clockPin = 12;
int dataPin = 11;

const int BouttonH = 6;
const int BouttonM = 7;

int sBouttonH = 1;
int clkBouttonH = 0;
int sBouttonM = 1;
int clkBouttonM = 0;


void setup() {
    Serial.begin(9600);
    Wire.begin();
    RTC.begin();
    pinMode(latchPin, OUTPUT);
    pinMode(clockPin, OUTPUT);
    pinMode(dataPin, OUTPUT);
    pinMode(BouttonH, INPUT);
    pinMode(BouttonM, INPUT);
  }
  
    



byte bcdSecond;
byte bcdMinute;
byte bcdHour;
    

byte decodeBCD(byte bcdValue)
{
 return  (10 * (bcdValue >> 5)) + ((0xf & bcdValue) >> 1 );
}

byte encodeBCD(byte value)
{
  return ((value/10)<< 5) | ((value % 10) << 1 );
}


void loop() {
  
Serial.println(RTC.isrunning()) ;

  DateTime now = RTC.now();
  
  bcdSecond= now.second();
  bcdMinute= now.minute();
  bcdHour= now.hour();
  
  sBouttonH = digitalRead(BouttonH);
if(sBouttonH == 1)
  clkBouttonH = 0;
sBouttonM = digitalRead(BouttonM);
if(sBouttonM == 1)
  clkBouttonM = 0;
  
  
  
        if(sBouttonH == 0)
      {
        clkBouttonH = clkBouttonH++;
        if(clkBouttonH > 2){
        now = DateTime(now.year(),now.month(),now.day(),(now.hour()+1)%24,now.minute(),now.second());
        RTC.adjust(now);
        }
      }
      
          if(sBouttonM == 0)
      {      
        clkBouttonM = clkBouttonM++;
        if(clkBouttonM > 2){
        now = DateTime(now.year(),now.month(),now.day(),now.hour(),(now.minute()+1)%60,0);
        RTC.adjust(now);
        }
      }
    
    
  
  
		
  
    
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, MSBFIRST, encodeBCD(bcdHour));  
  shiftOut(dataPin, clockPin, MSBFIRST, encodeBCD(bcdMinute));   
  shiftOut(dataPin, clockPin, MSBFIRST, encodeBCD(bcdSecond)); 
  digitalWrite(latchPin, HIGH);
  
  
  
    //We print the day
    Serial.print(now.day(), DEC);
    Serial.print('/');
    Serial.print(now.month(), DEC);
    Serial.print('/');
    Serial.print(now.year(), DEC);
    Serial.print(' ');
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.print(now.second(), DEC);
    Serial.println();
    
Serial.print("nb de secondes depuis 1970: ");
Serial.println(RTC.now().unixtime());

  }