🛠 Registres AVR et interruption timer : échantillonner le multiplexeur
Objectifs
Comprendre — puis court-circuiter — la bibliothèque Esplora. Les 10 canaux multiplexés (boutons, slider, lumière, température, micro, TinkerKit A/B, joystick) partagent l'entrée ADC A4, sélectionnés par les broches d'adresse A0–A3 (MAX_CHANNELS=13 dans Esplora.cpp). Ce tutoriel manipule les registres AVR directement (DDRB/PORTB, ADMUX, ADCSRA) et déclenche l'échantillonnage par interruption de comparaison du Timer2, pour un balayage périodique précis sans delay.
Matériel
- Arduino Esplora + câble micro-USB.
- Notions : brochage port B de l'ATmega32u4 (PB0–PB5 = A0–A5... attention au mapping Arduino analogique), datasheet ATmega16U4/32U4.
- Aucun composant externe.
Code complet
/* Balayage periodique du multiplexeur de l'Esplora SANS la bibliotheque,
pilote par interruption de comparaison du Timer2 (~1 kHz).
Adresses physiques d'après Esplora.cpp : A0..A3 = adresse, A4 = commun.
Sur l'ATmega32u4, A0..A4 correspondent a PORTB bit0..bit4. */
#include <avr/io.h>
#include <avr/interrupt.h>
#define MUX_PORT PORTB
#define MUX_DDR DDRB
#define ADC_COM 4 // A4 -> ADMUX MUX = 4
volatile uint16_t mesures[6]; // boutons non mesures ici : canaux analogiques
volatile uint8_t canal = 0;
ISR(TIMER2_COMPA_vect) {
// 1) selection du canal sur A0..A3
MUX_PORT = (MUX_PORT & 0xF0) | (canal & 0x0F);
// 2) lancement d'une conversion sur A4 (ADMUX deja configure)
ADCSRA |= (1 << ADSC);
}
ISR(ADC_vect) {
mesures[canal] = ADCL | (ADCH << 8); // lecture 10 bits
canal = (canal + 1) % 6; // cycle : 4=slider? voir note
}
void setup {
Serial.begin(9600);
MUX_DDR |= 0x0F; // A0..A3 en sortie
ADMUX = (1 << REFS0) | ADC_COM; // ref 5V, entrée A4
ADCSRA = (1 << ADEN) | (1 << ADIE) | (1 << ADPS2) | (1 << ADPS1); // /64
// Timer2 en CTC, comparaison ~1 kHz (16 MHz / 1024 / 16)
TCCR2A = (1 << WGM21);
TCCR2B = (1 << CS22) | (1 << CS21) | (1 << CS20);
OCR2A = 124;
TIMSK2 = (1 << OCIE2A);
sei;
}
void loop {
static uint32_t t = 0;
if (millis - t > 250) {
t = millis;
// Canaux physiques : dependront du cablage exact du mux (voir Esplora.cpp)
Serial.print("c4="); Serial.print(mesures[4]);
Serial.print(" c5="); Serial.print(mesures[5]);
Serial.print(" c6="); Serial.print(mesures[6]);
Serial.print(" c7="); Serial.println(mesures[7]);
}
}
Vérification attendue
Le moniteur série affiche quatre colonnes qui varient quand vous manipulez slider, lumière, température et micro — sans jamais appeler la bibliothèque Esplora (vérifiez avec le gestionnaire de bibliothèques qu'elle n'est pas compilée). La régularité du balayage est garantie par le Timer2 : débranchez le moniteur, l'échantillonnage continue à ~1 kHz.
Erreurs fréquentes
- Écrire sur PORTB sans masque : les bits 4–5 de PORTB portent aussi A4/A5 (accéléromètre) ; toujours faire
MUX_PORT = (MUX_PORT & 0xF0) | canal. - Oublier le temps d'établissement : après changement de canal, ~50 µs sont nécessaires avant conversion ; un Timer2 trop rapide (plusieurs dizaines de kHz) mélange les canaux.
- ADCL/ADCH dans le mauvais ordre : lire ADCH avant ADCL corrompt la dernière conversion ; lire ADCL d'abord verrouille les registres.
- Conflit avec la bibliothèque Servo ou tone : Timer2 est aussi utilisé par
tonesur l'AVR ; ce croquis n'utilise pas tone, mais si vous l'ajoutez, choisissez Timer1 ou Timer0. - Confondre canaux logiques de la bibliothèque et canaux ADC : le numéro envoyé sur A0–A3 n'est pas le MUX=3 bits d'ADMUX ; le canal ADC reste toujours A4.
Autres tutoriels pour cette carte
Exemples de code pour cette carte
joystick-couleur.inoArduinojeu-boutons.inoArduinoslider-luminosite.inoArduinothermometre-couleur.inoArduinosonometre.inoArduinoaccelerometre-tilt.inoArduino