Cours:ArduinoHorloge
Documentation
- afficheur 7 segments 12 pins : http://www.farnell.com/datasheets/2095874.pdf
- afficheur 7 segments 16 pins : https://www.vishay.com/docs/83180/tdcx10x0m.pdf
Nous utiliserons une carte arduino nano ainsi que divers composants que nous relierons ensemble sur une plaque à essais.
Sommaire
Utilisation de la plaque à essais
On utilisera dans un premier temps juste un seul digit (un seul chiffre)
|
|
1 segment
On validera déjà le principe de câblage en allumant le segment A sur l'afficheur.
L'afficheur utilisé est de type cathode commune :
Comme indiqué sur la figure précédente, pour allumer un segment il faut :
- relier une résistance 100Ω pour nous sur la broche du segment
- avec un fil, relier l'autre patte de la résistance à l'alimentation (5V ici)
- relier la cathode commune ( broche digit_U ou digit_D ou digit_C ou digit_M) à la masse
Vérifier que le segment s'allume et déplacer votre résistance pour allumer les différents segments
Déplacer maintenant le fil relié à la résistance du segment A pour le mettre sur la broche arduino D0 (Rx)
Ecrire un programme permettant de faire clignoter ce segment
void setup()
{
// mettre la broche en sortie !
}
void loop()
{
// mettre la sortie à l'état 1
// attendre un peu
// ...ensuite éteindre le segment et bien évidemment attendre encore !
}
1 segment
Nous relions maintenant les 7 segments à la carte arduino.
On veillera à mettre une résistance de 100Ω (270Ω) en série pour chaque segment.
Les segments seront connectés de la façon suivante :
Segment | a | b | c | d | e | f | g |
Broche arduino | D0 (Rx) | D1 (Tx) | D3 | D4 | D5 | D6 | D7 |
Remarque, nous n'utilisons pas la broche arduino n°2 qui servira pour un bouton poussoir par la suite.
Premier affichage
En utilisant les fonctions pinMode et digitalWrite, représentez le chiffre 2 sur l'afficheur
Modifiez votre programme pour représentez le chiffre 3
Puis affichez successivement 2 puis 3
... ça devient vite pénible !!!
tableau et PORT
PORTD
Notion de port
En observant attentivement la figure ci-contre, on constate que les pattes utilisées pour commander les leds n'ont pas été choisies au hasard.
En effet, nous utilisons les pattes 0 à 7, qui correspondent pour le µcontrôleur au PORTD (PD0, PD1, PD2, ...).
Ainsi, il devient possible de modifier l'état de toutes ces sorties/leds, en une seule instruction :
void setup()
{
// déclarer toutes les pattes en sortie :
}
void loop()
{
//mettre toutes les sorties à '1'
PORTD = 0b11111011; // nous n'utilisons pas PD2, la broche 2
delay(200);
//mettre toutes les sorties à '0'
PORTD = 0b00000000; // ou PORTD = 0x00; ou encore PORTD = 0;
delay(200);
}
Utilisation
Reprenez la question précédente, c'est à dire afficher 2 puis 3
Puis complétez pour afficher en boucle tous les chiffres
Tableau
Simplifions encore en utilisant un tableau dont le principe est donné si dessous :
// déclaration d'un tableau de 3 cases
// avec des valeurs initiales dans chaque case
uint8_t tableau[3] = {0b00000000,0b11001100,0b11110000};
//uint8_t est un type de variable sur 8 bits pour des nombres entiers positifs : unsigned int => uint
//[3] est le nombre de cases du tableau
void loop()
{
// pour modifier une case :
tableau[0] = 0b01010101; // modification de la première case
// utilisation d'une case :
x = tableau[2]; // dernière case du tableau de dimension 3
// parcourir le tableau
for (int i=0;i<3;i++)
{
.... = tableau[i] ....;
}
}
Reprendre la question précédente en utilisant un tableau
- Dans un premier temps, il suffit de remplacer PORTD=0b11111011; par PORTD=tableau[0]; ....
- vous pouvez ensuite utiliser une boucle comme indiqué ci dessus
- Ou mieux, se servir de la boucle pour changer de nombre :
uint8_t tableau[3] = {0b00000000,0b11001100,0b11110000};
int i=0;
void setup()
{
...
}
void loop()
{
PORTD = tableau[i];
if (i==2)
{
i=0;
}
else
{
i++;
}
// qu'on peut comprimer en supprimant les lignes inutiles if (i==2) i=0; else i++;
}
Terminé ? ... ajoutons l'afficheur des dizaines, centaines et le petit dernier les milliers !
Câblage
Nous allons réaliser un multiplexage des afficheurs, c'est à dire que l'on affichera successivement unité puis dizaine puis .... Du coup ça va clignoter, à moins de faire ça très vite.
Il faut alors modifier le schéma en reliant les cathodes communes (dig_U, dig_D, dig_C et dig_M) sur les broches du µcontrôleur.
Utiliser les broches A0 à A3 pour connecter les cathodes communes.
Premier programme
Écrire un programme qui affiche la valeur 2 sur chacun des digits.
void setup()
{
// pas mal de sorties !
}
void loop()
{
PORTD=quelqueChosePourAfficher2;
// mettre la sortie dig_U à 0 pour afficher les unités (attention seulement le dig_U !)
digitalWrite...
delay(100);
// ... la même chose pour les 3 autres digits
}
Remarque :
- changer la durée et vérifier que si cela est fait assez rapidement (tous les digits en 20ms), on aura l'impression que les 4 afficheurs sont allumés simultanément !
- on peut éventuellement modifier les sorties des 4 digits d'un seul coup, par ex : PORTC=0b00001111;
Compteur modulo 9999
On va réaliser un compteur modulo 9999 : un compteur qui s'incrémente jusqu'à 9999 et le coup d'après retourne à 0.
Alors on commence par faire en sorte que le compteur s'incrémente toutes les 100ms :
- installer la librairie TimerOne
- on indique dans notre programme que l'on va l'utiliser : #include <TimerOne.h>
- indiquons ensuite la périodicité de notre action (en µs) Timer1.initialize(100000);
- il reste à indiquer la fonction à exécuter : Timer1.attachInterrupt(blinkLED);
- pour récupérer la valeur :
- des unités : u = n%10;
- des dizaines : d = (n/10)%10;
- des centaines : c = (n/100)%10;
- des mil.....
- alterner rapidement (mais pas trop) entre l'affichage des unités et des dizaines
En vous servant de la base suivante et de vos programmes précédents, faire en sorte d'afficher la valeur du compteur qui s'incrémente sur votre afficheur 4 digits
#include <TimerOne.h>
//sans doute d'autres variables :
volatile int compteur=0; // volatile est nécessaire lorsqu'on utilise attachInterrupt
void incrementeCompteur(void)
{
// si compteur vaut 9999
// alors le remettre à 0
// sinon incrémenter le compteur
}
void setup() {
//initialiser les choses à initialiser !
//mise en place de l'action périodique
Timer1.initialize(100000);
Timer1.attachInterrupt(incrementeCompteur);
}
void loop()
{
//répéter en permanence afficher sur les 4 digits :
//sélectionner le digit des unités : PORTC=0b00001110;
//afficher le chiffre des unité : PORTD=tab7sgt[compteur%10];
//attendre un peu
//même chose ou presque pour les dizaines
//les centaines
//et les milliers
//that's all folks !
}
Réalisation d'une horloge
Terminez le câblage en ajoutant la gestion des ":" qui permettront de séparer minutes et heures.
Vous utiliserez la broche 12 arduino.
#include <TimerOne.h>
const unsigned int tab7Sgt[10]={0b01111011,0b00001010,0b10110011,0b10011011,0b11001010,0b11011001,0b11111001,0b00001011,0b11111011,0b11011011};
volatile uint8_t secondes=40;
volatile uint8_t minutes=59;
volatile uint8_t heures=23;
void nextSecond(void)
{
// un petit peu de travail par ici !
}
void setup() {
// broches des segments
pinMode(0,OUTPUT);
pinMode(1,OUTPUT);
pinMode(3,OUTPUT);
pinMode(4,OUTPUT);
pinMode(5,OUTPUT);
pinMode(6,OUTPUT);
pinMode(7,OUTPUT);
// broche du :
pinMode(12,OUTPUT);
// broches des cathodes communes (digits)
pinMode(A0,OUTPUT);
pinMode(A1,OUTPUT);
pinMode(A2,OUTPUT);
pinMode(A3,OUTPUT);
// éteindre tous les digits
PORTC=0x0F;
//
Timer1.initialize(1000000);
Timer1.attachInterrupt(nextSecond); // blinkLED to run every 0.15 seconds
}
void loop()
{
PORTC=0b1110;
PORTD=tab7Sgt[minutes%10];
delay(5);
PORTC=0b1101;
PORTD=tab7Sgt[(minutes/10)%10];
delay(5);
PORTC=0b1011;
PORTD=tab7Sgt[(heures)%10];
delay(5);
PORTC=0b0111;
PORTD=tab7Sgt[(heures/10)%10];
delay(5);
}
Le programme précédent permet d'afficher 23H59 sur l'afficheur.
la fonction nextSecond s'exécute toutes les secondes, complétez là pour incrémenter de façon adéquat le temps (heures/minutes/secondes)
Remarque : pour vérifier le fonctionnement vous pouvez accélérer le temps en modifiant Timer1.initialize(1000000);
Améliorations
affichage des secondes
Utilisez les points de l'afficheur pour indiquer les secondes : ils doivent s'allumer chaque seconde et non pas changer d'état toutes les secondes
réglage de l'heure
Ajoutez un bouton connecté sur la broche arduino 2 (ne pas oublier la résistance de tirage), et faire en sorte que l'on puisse régler l'heure avec ce bouton
La fonction loop se répète toutes les 20 ms. Vous pouvez faire en sorte qu'à chaque fois qu'on recommence la "loop", si le bouton est appuyé, alors on exécute la fonction nextSecond. Si c'est trop lent, il est bien évidemment possible d'exécuter plusieurs fois la fonction nextSecond. |