Go Down

Topic: [Info] Horloge binaire (Read 5307 times) previous topic - next topic

alfredcore

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

Code: [Select]
byte decodeBCD(byte bcdValue)
{
return  (10 * (bcdValue >> 4)) + (0xf & bcdValue);
}

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


Sinon voici mon code
Code: [Select]


#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 :)

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 : /

nulentout

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 

B@tto

http://fr.openclassrooms.com/sciences/cours/arduino-pour-bien-commencer-en-electronique-et-en-programmation/presentation-du-74hc595
Blog électronique : battomicro.wordpress.com
Photographie : www.interactive-celebration.fr
Fablab de Montpellier : www.labsud.org

fdufnews

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

nulentout

#4
Feb 20, 2014, 09:36 am Last Edit: Feb 21, 2014, 08:37 am by nulentout Reason: 1
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.

fdufnews

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

B@tto

http://arduino.cc/en/Reference/PortManipulation
Blog électronique : battomicro.wordpress.com
Photographie : www.interactive-celebration.fr
Fablab de Montpellier : www.labsud.org

alfredcore

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

@nulentout :
A) oui je désire afficheur l'heure en binaire pur sur 6 afficheur :) 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 ;-) 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 :) 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 : /

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

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

Code: [Select]
byte decodeBCD(byte bcdValue)
{
return  (10 * (bcdValue >> 4)) + (0xf & bcdValue);
}


Mais là je ne comprends vraiment rien :/


Merci pour ton pense-bête :D sa m'a aider à comprendre


fdufnews


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



... j'ai compris ^^

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

Code: [Select]
byte encodeBCD(byte value)
{
  return ((value/10)<< 5) | ((value % 10) << 1);
}


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



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

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

alfredcore

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 ?

Code: [Select]
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
Code: [Select]
void setTime()
{
  DateTime now = RTC.now();
  RTC.adjust(DateTime:"FEB 21 2014","(decodeBCD(bcdHour)):(decodeBCD(bcdMinute)):00");
}


nulentout

#10
Feb 21, 2014, 08:50 am Last Edit: Feb 21, 2014, 08:57 am by nulentout Reason: 1
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.

patg_

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:

Code: [Select]

//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);

Mes Arduineries: http://breizhmakers.over-blog.com/

alfredcore

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é

patg_

Bizarre.

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

Mes Arduineries: http://breizhmakers.over-blog.com/

alfredcore

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 ;-)

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 ? :P

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

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

  }



Go Up