Cours:XR207 tp digicode
Vous allez développer un système de digicode architecturé autour d'un atmega328p (le µcontrôleur présent sur les cartes arduino).
Pour ce TP, nous utilisons une carte arduino sans le shieldinfo
Sommaire
Informations lumineuses
Le digicode sera équipé de 2 voyants lumineux (rouge et vert).
On utilisera des résistances de 330Ω, et vous êtes libre de choisir un montage à anodes ou cathodes communes.
Câbler sur une plaque à essais les leds sur les pin PC0 (Rouge) et PC1 (Verte)
Écrire une fonction pour éteindre ou allumer une led dont l'usage sera le suivant :
#include <avr/io.h>
#include <util/delay.h>
#define ledRouge PC0
#define ledVerte PC1
#define allumerLed 0
#define eteindreLed 1
void setEtatLed(unsigned char numLed,unsigned char val)
{
// suivant la valeur de val
// allumer ou éteindre la led
}
int main()
{
// config des sorties
while(1)
{
setEtatLed(ledRouge,allumerLed);
_delay_ms(100);
setEtatLed(ledVerte,allumerLed);
_delay_ms(100);
setEtatLed(ledRouge,eteindreLed);
_delay_ms(100);
setEtatLed(ledVerte,eteindreLed);
_delay_ms(100);
}
}
|
#define led PB5
int main()
{
DDRB |= 1 << led;
while(1)
{
PORTB |= 1 << led;
delay(100);
PORTB &= ~(1 << led);
delay(100);
}
}
|
Decodage d'un clavier
Câblage
Le tableau suivant résume la disposition physique du clavier avec la position physique sur le connecteur des lignes (L1 à L4) et colonnes (C1 à C3) en vue de dessus :
|
|
Câbler sur une plaque à essais le clavier 12 touches que l'on vous donne. Les colonnes seront reliées sur le port D et les lignes sur le port B (cf indications ci dessus)
Remarque : On ne câblera aucune résistance de tirage, on utilisera les résistances internes au µcontrôleur.
Indice de ligne
Ecrire et tester le programme lecture_ligne() qui renvoie le numéro de ligne sur laquelle un bouton est appuyé
- Servez-vous bien évidemment du travail en TD !
- Rappelons qu'il faut écrire un '1' sur une entrée, pour activer la résistance de pull-up associée
- La validation se fera en utilisant des leds connectées sur le port C :
- On mettra 4 leds sur les broches PC3 à PC0
- On visualisera un nombre n sur 4 bits en écrivant PORTC = n;
char lecture_ligne()
{
char ch;
DDRD ?= .... ; // commençons par lister les sorties sur le port D
DDRB ?= .... ; // puis les entrées sur le port B
PORTD?=..... ; // on place les sortie à l'état 0
PORTB?= .... ; // on active les résistances de pull-up sur les entrées
_delay_ms(1); // un délais est nécessaire pour l'activation des pull-ups
ch = PINB & 0x??; // on récupère ensuite l'état des entrées
switch (ch)
{
case : return 0; // aucune touche
case : return 1; // L1
case : return 2; // L2
case : return 3; // L3
case : return 4; // L4
// si autre cas, deux touches ou autre
default : return -1;
}
}
Indice de colonne
De la même façon, écrire et tester la fonction lecture_colonne() qui permettra d'obtenir le numéro de colonne sur laquelle un bouton est appuyé.
Touche appuyée
Nous souhaitons maintenant écrire une fonction qui renverra une valeur tel que décrit ci dessous :
char touches[LIGNES][COLONNES] = { // tableau de char à 2 dimensions
{1,,},
{...},
{...},
{,,11}
};
char getTouche();
|
La valeur retournée sera :
|
Écrire cette fonction en vous servant bien évidemment des 2 fonctions précédentes et pourquoi pas du tableau "touches" complété.
char getTouche()
{
....
}
Assemblons le tout
Nous allons utiliser les 2 fonctions getTouche() et setEtatLed() pour réaliser un programme de digicode.
Cahier des charges
Commençons pour définir les contraintes :
- On appuie sur la touche ON (touche '*') => la led rouge s'allume
- L'utilisateur doit alors saisir le code sur 4 chiffres
- On valide le code par la touche OK (touche '#')
- Si le code est bon la led verte s'allume pendant 10s, sinon la led rouge clignote pendant 10s
Codez !!
Nous commençons par décrire le programme grâce à l'algorigramme suivant :
- initialiser i
- éteindre les leds
- si la touche apuyé est '*'
- allumer led rouge
- répéter
- attendre plus de touches appuyées ( à l'aide d'un while(getTouche....); )
- répéter
- lire clavier => touche ( touche = getTouche(); !!! )
- tant que touche<0
- si touche '*'
- réinitialiser i
- sinon
- sauvegarder touche dans un tableau
- incrémenter i
- tant que i<4
- attendre plus de touches appuyés
- attendre appui sur touche
- si touche '#'
- vérifier le code
- si code valide
- allumer led verte pendant 10s
- sinon
- faire clignoter led rouge pendant 10s
Remarque : Utiliser un tableau pour mémoriser le code, ex :
const unsigned char code[4]={1,2,3,4};
Écrire le programme correspondant
Améliorations
Il serait intéressant de proposer une procédure de changement du code.
Il est également intéressant de régler une durée maximum (4s) de saisie du code, en utilisant un timer.
Buzzer
Objectif
Nous souhaitons utiliser le buzzer afin d'avoir une information sonore sur la touche du clavier appuyée.
Pour ce faire, chaque touche sera associée à une note de musique tel qu'indiqué dans le tableau suivant :
| Touche | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | * | # |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Note | Do | Do# | Ré | Ré# | Mi | Fa | Fa# | Sol | Sol# | La | La# | Si |
| Fréquence (Hz) | 261,63 | 277,18 | 293,66 | 311,13 | 329,63 | 349,23 | 369,99 | 392 | 415,3 | 440 | 466,16 | 493,88 |
| Période (µs) | 3822 | 3608 | 3405 | 3214 | 3037 | 2863 | 2703 | 2551 | 2408 | 2273 | 2145 | 2025 |
Programmons
Vous utiliserez le programme réalisé au tp précédent, et notamment la fonction playnote(note,duree) pour jouer la note associée à chaque appui d'une touche


