Carte ATMEGA32 avec télécommande IR,télémètre IR, etc.
From Eric
Contents |
Objectifs
Cette première carte à base d'Atmega32 avait pour but initial de servir de carte de contrôle du robot roulant M1. En définitive, elle représente actuellement le "banc d'essais" de l'Atmega32, du capteur de distance Sharp, du bus I2C, etc.
Réalisation
Aperçu général de la carte
Télécommande infrarouge
La carte est équipée d'un capteur à infrarouge du type TSOP4838 (gamme 38KHz) qui permet de capter le signal d'une télécommande de téléviseur (notamment).
Le capteur réalise le filtrage et la démodulation du signal de la télécommande. En sortie du capteur, la valeur du signal est binaire.
Le signal est codé selon le standard RC5. La structure d'une trame est donnée ci-après :
On trouvera sur internet de nombreuses versions de programmes permettant le décodage des trames RC5, dont une proposée par Atmel (rc5.pdf ici).
Notre implémentation utilise les interruptions. C'est un choix. Il nous a permis d'expérimenter la gestion des interruptions sur Atmega.
Le principe est de déterminer l'instant d'échantillonnage du signal du capteur de sorte que la valeur du signal à cet instant corresponde à la valeur du bit reçu.
Pour ce faire, on procède ainsi :
- on détecte le premier front descendant correspondant à la réception du bit de start ;
- on mesure la durée qui sépare cette première transition de la suivante, l'intervalle est appelé dt ;
- à partir de cet instant, on échantillonnera le signal 3/2 dt après chaque front descendant.
Ce principe est illustré ci-dessous.
* ------------------------------------------------------------- * Le comportement est le suivant * +-- 1er échantillon * | * t0 t1 v v * -----+ +---+ +---+ +---+---+ * | | | | . | | . | * | | | | . | v | . | * +---+ +---+ . +---+---+ . +--- * start. start . . . . . * 1 . 2 . . . . . * . . . . . . . . * . . . . . . . . * . . . . . . . . * . . . . . . . . * <---> . . . . . . * dt <-----> <-----> <-----> * 3/2dt 3/2dt 3/2dt
La gestion du décodage est réalisé par une machine à états dont les transitions sont réalisées lors de la réception :
- de l'interruption INT1 qui est émise lors de toute transition du signal en provenance du capteur
- de l'interruption TIMER1_COMPARE qui est émise lorsque le compteur du timer 1 atteint une valeur programmée
Le code du handler de l'interruption INT1 est donné ci-après :
ISR(INT1_vect) { uint16_t tmp; switch ( state ) { case 0: // Front milieu du premier bit de start { it_tmp=0; // Réinitialiser le compteur. TCNT1 = 0; // Configurer le timer en mode normal. TCCR1A = 0; // Configurer la source et faire démarrer le timer. // Le prescaler vaut 8. TCCR1B |= ( (0 << CS12) | (1 << CS11) | (0 << CS10)); state = 1; break; } case 1: // Front montant deuxième bit de start // Lire la valeur du timer (dt) tmp = TCNT1; // Et calculer la valeur de l'attente (3/2 largeur d'un bit) ir_dt = tmp; ir_dt += (tmp >> 1); // Stopper le timer. TCCR1B = 0; // Initialiser le comparateur OCR1A = ir_dt; // Initialiser le timer TCNT1 = 0; // Activer l'interruption sur CTC TIMSK |= (1 << OCIE1A); state = 2; break; case 2: default: // Front milieu // Inhiber l'IT INT1. GICR ^= (1 << INT1); // Configurer le timer dans le mode CTC // et démarrer le timer. TCCR1B |= ( (1 << WGM12) | (0 << CS12) | (1 << CS11) | (0 << CS10)); break; } }
Le code du handler d'interruption TIMER1 COMPARE est donné ci-après :
ISR(TIMER1_COMPA_vect) { // Capturer le bit. it_tmp |= ( PIND & (1<<PD3)) >> PD3 ; it_tmp <<= 1; // Stopper le timer (CS10..12 = 0). TCCR1B = 0; // Faire évoluer l'état. state++; // A-t-on fini d'échantillonner ? if ( state == 15 ) { // OUI: Stocker le résultat ir_code = it_tmp; // Réinitialiser la machine à états state = 0; // Effacer le flag (éventuellement positionné) GIFR |= ( 1<< INTF1); // Réactiver l'IT sur front pour une prochaine acquisition GICR |= (1 << INT1); } else { // Supprimer le flag de détection de front // éventuellement positionné pendant l'attente. GIFR |= ( 1<< INTF1); // Réactiver l'IT sur front. GICR |= (1 << INT1); } }
Actuellement, ce mode de gestion du décodage RC5 n'est pas robuste à la perte d'une transition puisque la machine à états attend un nombre fixe de bits avant de considérer la réception achevée. Une amélioration indispensable consisterait à introduire un délai maximum (timeout) entre la réception du bit de start et la réception du bit de stop et de rejeter la trame si ce délai vient à être dépassé.