Oui, je sais, ça faisait longtemps que je n’avais pas présenté de schéma. Et pour cause : je me bat avec celui-ci depuis presque 1 mois ! Au point que j’ai décidé de vous le publier en 2 parties 
Rassurez vous, la partie que je vais vous présenter est tout à fait fonctionnelle, mais je voulais vous présenter un joli projet fini, sous la forme d’un shield Arduino, (et éventuellement vous proposer un kit), mais je galère pas mal avec les prototypes…. (encore une fois, je me rend compte qu’il ne faut pas négliger les caractéristiques physiques des composants
)
Pour ceux qui ne connaissent pas les horloges binaires, il s’agit de représenter les heures – minutes – secondes sous leurs équivalents en binaire, ce qui permet d’afficher l’heure grace à une rangée de LED. Concernant l’affichage, il y a deux écoles : soit on affiche directement la conversion binaire pour chaque membre de l’heure, par exemple pour 10:00:45, on afficherais 101101 (soit 45 en binaire) pour les secondes, soit on décompose pour chaque membre les dizaines des unités, ce qui donnerais pour l’exemple précédent 100 et 101 (soit respectivement 4 et 5). C’est cette dernière méthode que j’ai choisi car elle permet de lire l’heure un peu plus simplement.
Je voulais une horloge relativement fiable, je ne me suis donc pas basé sur l’horloge interne de l’arduino, mais plutôt sur une base de temps externe à 1Hz, à base de quartz d’horlogerie.
Voici pour la partie matérielle, je vous met également les sources de mon code Arduino :
/*
Horloge binaire
Utilise 3 74HC595 pour gérer l’affichage Heure minutes secondes
On gère l’affichage sur colonnes separees pour les dizaines et les unites, afin de faciliter la lecture
*/
//Pin connected to latch pin (ST_CP) of 74HC595
const int latchPin = 8;
//Pin connected to clock pin (SH_CP) of 74HC595
const int clockPin = 12;
////Pin connected to Data in (DS) of 74HC595
const int dataPin = 11;
//Pin recevant les ticks d’horloge (1Hz)
const int Clock = 3;
//Pin boutton poussoir reglage heure
const int BouttonH = 7;
const int BouttonM = 6;
//const int MULTIPLEX = 5; //delai de boucle pour le multiplexage en milliseconde
const int MULTIPLEX = 200;
// On garde l’état précédent de la clock : S’il était à 0 et que la clock est à 1, on est sur un nouveau top, sinon, c’est toujours le même top.
int last_state = 0;
int cur_state = 0; //l’etat actuel de la Clock
int demisec = 0;
int increment = 0; //s’il faut incrémenter le compteur, increment vaut 1.
//On gère les dizaines et les unités séparement car elles ne font pas parties de la meme colonne d’affichage.
int HeureD = 0;
int HeureU = 0;
int MinuteD = 0;
int MinuteU = 0;
int SecondeD = 0;
int SecondeU = 0;
//Variables pour les conversion binaires
int bSecondeD = 0;
int bSeconde = 0;
int bMinuteD = 0;
int bMinute = 0;
int bHeureD = 0;
int bHeure = 0;
//Variables d’etat des boutons
int sBouttonH = 1; //etat du boutton de reglage heure (1 = relache)
int clkBouttonH = 0; //on memorise depuis combien de top est appuyé le bouton
int sBouttonM = 1;
int clkBouttonM = 0;
//variable pour le multiplexage :
// on n’eclaire pas toutes les leds en meme temps, on le fait bloc par blog (HH, puis MM, puis SS)
int multiplex = 0;
//Variable de debug : Si debug = 1, alors on active le port serie.
int debug = 1;
void setup() {
pinMode(latchPin, OUTPUT);
pinMode(dataPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(Clock, INPUT);
pinMode(BouttonH, INPUT);
if(debug == 1)
Serial.begin(9600);
last_state = digitalRead(Clock);
}
void loop() {
// est-on sur un nouveau top ?
cur_state = digitalRead(Clock);
//est-ce qu’un boutton est appuyé ?
sBouttonH = digitalRead(BouttonH);
if(sBouttonH == 1)//si le boutton H a ete relache, on remet tout a 0
clkBouttonH = 0;
sBouttonM = digitalRead(BouttonM);
if(sBouttonM == 1)//si le boutton M a ete relache, on remet tout a 0
clkBouttonM = 0;
if(debug == 1)
Serial.println(« debut top »);
if((cur_state == 1) && (last_state == 0)) // Si l’horloge viens de passer à 1, on est sur un top
demisec = demisec++;
if(demisec > 1)
//On a besoin de 2 tops pour une seconde
{
increment = 1; // on va donc pouvoir incrementer le compteur
last_state = cur_state; //on met à jour last_state
//Et on en profite pour vérifier depuis combien de temps le bouton est appuyé
if(sBouttonH == 0)
{
clkBouttonH = clkBouttonH++;
//si Le bouton était déjà appuyé la seconde precedente, alors on incremente.
if(clkBouttonH > 2)
{
//on incremente l’heure
if(HeureU < 11)
HeureU = HeureU++;
if(HeureU == 4 && HeureD == 2) //minuit, on remet tout à 0
{
HeureU = 0;
HeureD = 0;
}
else if(HeureU == 10)
{
HeureD = HeureD++;
HeureU = 0;
}
}
}
//idem pour les minutes
if(sBouttonM == 0)
{
clkBouttonM = clkBouttonM++;
//si Le bouton était déjà appuyé la seconde precedente, alors on incremente.
if(clkBouttonM > 2)
{
//on incremente les minutes
if(MinuteU < 11)
MinuteU = MinuteU ++;
if(MinuteU == 10)
{
MinuteD = MinuteD++;
MinuteU = 0;
}
if(MinuteD == 6) //on ne depasse pas les 60 minutes…
{
MinuteD = 0;
}
}
}
}
else
{
last_state = cur_state; //sinon, on se contente de rafraichir last_state
}
/// Si on doit incrémenter l’horloge :
if(increment == 1)
{
if(SecondeU < 11)
SecondeU = SecondeU ++;
if(SecondeU == 10)
{
SecondeD = SecondeD++;
SecondeU = 0;
}
if(SecondeD == 6)
{
SecondeD = 0; //on remet le compteur des secondes à 0;
if(MinuteU < 11)
MinuteU = MinuteU ++;
if(MinuteU == 10)
{
MinuteD = MinuteD++;
MinuteU = 0;
}
if(MinuteD == 6)
{
MinuteD = 0;
if(HeureU < 11)
HeureU = HeureU++;
if(HeureU == 4 && HeureD == 2) //minuit, on remet tout à 0
{
HeureU = 0;
HeureD = 0;
}
else if(HeureU == 10)
{
HeureD = HeureD++;
HeureU = 0;
}
}
}
//on a finit d’incrementer, on repasse donc le flag increment à 0
increment = 0;
//On repasse demisec = 0
demisec = 0;
//on met à jour l’affichage
if(debug == 1)
{
Serial.print(HeureD);
Serial.print(HeureU);
Serial.print(« : »);
Serial.print(MinuteD);
Serial.print(MinuteU);
Serial.print(« : »);
Serial.print(SecondeD);
Serial.println(SecondeU);
}
//on convertis l’affichage en binaire , de maniere a ce que les dizaines et unites tiennent sur 1 octet
bSecondeD = SecondeD << 4; //decalage a gauche de 4 bit pour les dizaines
bSeconde = bSecondeD | SecondeU; //OU logique pour « assembler » les dizaines et les unites
bMinuteD = MinuteD << 4;
bMinute = bMinuteD | MinuteU;
bHeureD = HeureD << 4;
bHeure = bHeureD | HeureU;
if(debug == 1)
{
Serial.print(« Binaire Heures:Minutes:Secondes « );
Serial.print(bHeure,BIN);
Serial.print(« : »);
Serial.print(bMinute,BIN);
Serial.print(« : »);
Serial.println(bSeconde,BIN);
Serial.print(« Etat du bouton Heures : »);
Serial.println(sBouttonH);
Serial.print(« Etat du bouton Minutes : »);
Serial.println(sBouttonM);
}
}
////on envoie l’heure sur le 74HC595
digitalWrite(latchPin, LOW);
//on multiplexe l’affichage
if(multiplex == 0)
{
shiftOut(dataPin, clockPin, MSBFIRST, bHeure);//on envoie les heures
shiftOut(dataPin, clockPin, MSBFIRST, 0);//on envoie les minutes
shiftOut(dataPin, clockPin, MSBFIRST, 0);//on envoie les secondes
}
if(multiplex == 1)
{
shiftOut(dataPin, clockPin, MSBFIRST, 0);//on envoie les heures
shiftOut(dataPin, clockPin, MSBFIRST, bMinute);//on envoie les minutes
shiftOut(dataPin, clockPin, MSBFIRST, 0);//on envoie les secondes
}
if(multiplex == 2)
{
shiftOut(dataPin, clockPin, MSBFIRST, 0);//on envoie les heures
shiftOut(dataPin, clockPin, MSBFIRST, 0);//on envoie les minutes
shiftOut(dataPin, clockPin, MSBFIRST, bSeconde);//on envoie les secondes
}
multiplex = multiplex++;
if(multiplex>2)
multiplex = 0;
/*
// shift the bytes out:
shiftOut(dataPin, clockPin, MSBFIRST, bHeure);//on envoie les heures
shiftOut(dataPin, clockPin, MSBFIRST, bMinute);//on envoie les minutes
shiftOut(dataPin, clockPin, MSBFIRST, bSeconde);//on envoie les secondes
*/
digitalWrite(latchPin, HIGH);
if(debug == 1)
{
Serial.print(« multiplex : « );
Serial.println(multiplex);
}
//on attend quelques millisecondes, pour pas saturer l’arduino (surtout utile en cas d’utilisation du port serie)
delay(MULTIPLEX);
}