Cours:ArduinoHorloge : Différence entre versions
Ligne 42 : | Ligne 42 : | ||
==1 segment== | ==1 segment== | ||
− | [[Fichier: | + | [[Fichier:7sgts_tinkercad2.png|droite|500px]] |
On validera déjà le principe de câblage en allumant le segment A sur l'afficheur. | On validera déjà le principe de câblage en allumant le segment A sur l'afficheur. |
Version du 30 septembre 2021 à 16:09
Documentation
- afficheur 7 segments :http://www.farnell.com/datasheets/2095874.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 !
}
7 segments !
Nous relions maintenant les 7 segments à la carte arduino.
On veillera à mettre une résistance de 100Ω 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
- on pourra ajouter un bouton connecté sur la broche 3 (INT1) qui incrémente n à chaque appui
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éter 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);
- essayer de faire clignoter les ":" toutes les secondes
- ou mieux, toutes les 500ms