Cours:Eval Mecatro : Différence entre versions
(Une révision intermédiaire par le même utilisateur non affichée) | |||
Ligne 1 : | Ligne 1 : | ||
− | + | ||
[[Cours:Eval_Mecatro_corr|{{Vert|<big>Corrigé uniquement accessible aux enseignants</big>}}]] | [[Cours:Eval_Mecatro_corr|{{Vert|<big>Corrigé uniquement accessible aux enseignants</big>}}]] |
Version actuelle datée du 3 juillet 2017 à 15:22
Corrigé uniquement accessible aux enseignants
L'objectif consiste à réaliser un dé avec un affichage sur sept segments en lieu et place des chiffres d'un dé de la vraie vie.
Sommaire
Quelques évaluations d'expressions
Vous disposez pour ce travail d'introduction du code suivant :
void setup(){
char i;
for (i=6;i<=13;i++) pinMode(i,OUTPUT); // Déclaration des 6 so
pinMode(2,INPUT);
}
void allumeLeds(unsigned char motif){
char i;
for (i=0;i<8;i++) {
digitalWrite(i+6,(motif>>i) & 1);
}
}
Il est capable d'allumer les LEDs en fonction de la valeur passée dans motif.
Expressions booléennes
La variable a (de type unsigned char) est initialisée à 0xC7. Écrire un programme qui est capable de trouver la valeur des expressions booléennes en allumant ou pas une Led choisie par avance :
- (a & 0x80)== 0x80
- (a & 0x47)== 0x47
Expression de décalage
La variable a (de type unsigned char) est encore initialisée à 0xC7. Écrire un programme qui est capable de trouver la valeur des expressions :
- a >> 2
- a << 3
Réalisation du dé avec le shield de l'IUT
Nous désirons réaliser un dé avec le shield que l'on utilise régulièrement à l'IUT. Les leds étant alignées, elles ne présentent pas une organisation facilement exploitable pour un affichage de type "dé à jouer". Nous décidons donc d'afficher directement le chiffre sur un afficheur sept segments.
Nous allons utiliser un tableau précalculé de valeurs.Nous décidons d'utiliser la configuration du tableau ci-dessous.
Segment | pt | g | f | e | d | c | b | a |
---|---|---|---|---|---|---|---|---|
Arduino Pin | 11 | 9 | 10 | 8 | 7 | 6 | 12 | 13 |
Port | PB3 | PB1 | PB2 | PB0 | PD7 | PD6 | PB4 | PB5 |
On vous impose le sous programme suivant :
const char pinMux = 4;
const char pinAff[8]={13,12,6,7,8,10,9,11};
const char de[7]={/*A compléter les valeurs 0,1,2,3,4,5,6*/};
void affiche7seg(unsigned char v){
char i,s;
unsigned char c;
// boucle d'affichage :
for (i=0;i<8;i++) {
if ((v & (1<<i)) == (1<<i) ) digitalWrite(pinAff[i],1); // Modifie successivement l'état des segments a (ou patte 13)
else digitalWrite(pinAff[i],0);
}
}
Exercice 1 : calculer les valeurs pour afficher 0, 1, 2, 3, 4 , 5 et 6 et mettez-les dans le tableau à compléter.
Affichage du tableau
Exercice 2 : après ce calcul on fera un programme de test qui affiche toutes les secondes toutes les valeurs possibles du dé. On prendra bien soin de gérer la sélection de l'afficheur (de droite avec pinMux à 1).
void setup() {
// put your setup code here, to run once:
char i;
for (i=0;i<8;i++) pinMode(pinAff[i],OUTPUT); // Déclaration des 8 sorties des afficheurs
pinMode(pinMux,OUTPUT); // + sortie de multiplexage (choix de l'afficheur)
digitalWrite(??,??); // sur l'afficheur 1 : à compléter
}
void loop() {
// put your main code here, to run repeatedly:
}
L'étape suivante consiste à introduire de l'aléatoire pour que cela ressemble le plus possible à un vrai dé.
Utilisation du pseudo aléatoire
On vous propose le code suivant :
unsigned char pseudoAleat(int Lim) {
unsigned char Result;
static unsigned int Y=1;
Y = (Y * 32719 + 3) % 32749;
Result = ((Y % Lim)+1);//+1 : eviter 0
return Result;
}
Exercice 3 : Réaliser un programme qui fait défiler les valeurs de cette fonction pseudo aléatoire pour un appel avec un paramètre égal à 6 (qui vous permet d'avoir systématiquement des nombres entre 1 et 6 compris).
Gestion du bouton de lancement
Description
Le shield comporte 4 boutons, dont 2 possèdent une interruption spécifique. Chaque bouton est relié à une porte "non". Une fonction "trigger" sur les entrées permet de limiter les changements d'états impromptus (rebonds) lors du changement d'état des boutons.
Le tableau suivant donne les caractéristiques utiles :
Bouton | Position | Arduino Pin | Port | Interruption | Niveau logique si bouton appuyé |
---|---|---|---|---|---|
A | Bas Gauche | 2 | PD2 | int0 | 1 |
D | Haut Gauche | 3 | PD3 | int1 | 1 |
B | Bas Droite | A0 | PC0 | 0 | |
C | Haut Droite | A1 | PC1 | 0 |
On utilisera le bouton B qui est en pullup sur PC0.
Exercice 4 : après avoir mis au point une boucle d'attente d'un appui sur le bouton B, réaliser le programme complet qui attend un appui du bouton B et appelle le générateur pseudo-aléatoire pour afficher le résultat.
Gestion de deux dés
C'est le bit PD4 du PORTD (appelé "pinMux" dans nos programmes) qui est responsable de la sélection d'un afficheur :
- PD4 = 1 c'est l'afficheur de droite qui est en action
- PD4 = 0 c'est l'afficheur de gauche qui est en action
Si vous voulez afficher deux valeurs, il vous faut les écrire en synchronisme avec la commutation des afficheurs. Cette commutation doit être réalisée à plus de 25 Hz pour un fonctionnement correct (sans scintillation pour les yeux).
Exercice 5 : Réaliser un programme qui affiche sur deux afficheurs deux résultats de la fonction pseudo-aléatoire. Il faut afficher pendant un certain temps pour que l’œil perçoive ! INDICATION : Le sous-programme ci-dessous affiche les deux valeurs et dure 400 ms
void affiche2Digits(char de2,char de1) {
char c;
for (c=0;c<20;c++) {
digitalWrite(pinMux,1); // sur l'afficheur unité
affiche7seg(de1);
delay(10);
digitalWrite(pinMux,0); // puis sur l'afficheur dizaine
affiche7seg(de2);
delay(10); }
}
Exercice 6 : Réaliser un programme complet qui attend que l'on appui sur le bouton B et qui alors utilise deux fois la fonction pseudo-aléatoire pour trouver la valeur des deux dé et qui affiche alors les deux valeurs sur les deux afficheurs.
Indication : il est impossible d'utiliser la boucle d'attente de l'exercice 4 car pendant l'attente, on perdrait l'affichage. Il faut donc utiliser la technique de détection de changement d'état :
void loop(){
etatPasse=etatPresent; // mémorise l'état précédent (le présent devient le passé)
etatPresent=digitalRead(??); // lecture de la valeur actuelle
if ( ( etatPresent == ?? ) && ( etatPasse == ?? ) ) { // si appui alors ....
.....
}
delay(20); // est-ce obligatoire ???
}
dans laquelle on remplacera le "delay(20)" par l'affichage des deux dés. Cela devient un peu lent mais suffisant pour nos propos.