🛠 Registres AVR et interruption timer : échantillonner le multiplexeur

Arduino Esplora — Ficha de placa · avance · Schéma : IMG-esplora-avance-1-esplora-registres-interruption-timer.svg — Schéma fonctionnel du multiplexeur 4 vers 1 de l'Esplora : broches A0-A3 en adresse, A4 en ADC commun, canaux boutons/slider/lumière/température/son, avec le timer TCNT2 en horloge.

Objetivos

Comprender — y luego anular — la biblioteca Esplora. Los 10 canales multiplexados (botones, deslizador, luz, temperatura, micrófono, TinkerKit A/B, joystick) comparten la entrada ADC A4, seleccionados mediante los pines de dirección A0–A3 (MAX_CHANNELS=13 en Esplora.cpp). Este tutorial manipula directamente los registros AVR (DDRB/PORTB, ADMUX, ADCSRA) y dispara el muestreo mediante una interrupción de comparación del Timer2, para lograr un barrido periódico preciso sin usar delay.

Material

Código completo

/* Balayage periodique du multiplexeur de l'Esplora SANS la bibliotheque,
   pilote par interruption de comparaison du Timer2 (~1 kHz).
   Adresses physiques d'apres 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, entree 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]);
  }
}

> NO VERIFICADO: la tabla de correspondencia exacta número de canal → sensor en el código sin librería depende de las constantes internas de Esplora.cpp (CH_SLIDER, CH_LIGHT, etc.); verifíquelos en el código fuente de la biblioteca antes de interpretar sus mediciones.

Verificación esperada

El monitor serie muestra cuatro columnas que varían cuando manipula el deslizador, la luz, la temperatura y el micrófono — sin llamar nunca a la biblioteca Esplora (verifique con el gestor de bibliotecas que no está compilada). La regularidad del barrido está garantizada por el Timer2: si desconecta el monitor, el muestreo continúa a ~1 kHz.

Errores frecuentes

  1. Escribir en PORTB sin máscara: los bits 4–5 de PORTB también llevan A4/A5 (acelerómetro); siempre haga MUX_PORT = (MUX_PORT & 0xF0) | canal.
  2. Olvidar el tiempo de estabilización: después de cambiar de canal, se necesitan ~50 µs antes de la conversión; un Timer2 demasiado rápido (varias decenas de kHz) mezcla los canales.
  3. ADCL/ADCH en el orden incorrecto: leer ADCH antes que ADCL corrompe la última conversión; leer ADCL primero bloquea los registros.
  4. Conflicto con la biblioteca Servo o tone: Timer2 también es utilizado por tone en el AVR; este sketch no usa tone, pero si lo añade, elija Timer1 o Timer0.
  5. Confundir canales lógicos de la biblioteca y canales ADC: el número enviado a A0–A3 no es el MUX de 3 bits de ADMUX; el canal ADC sigue siendo siempre A4.

Otros tutoriales para esta placa

Ejemplos de código para esta placa

← Volver a la ficha 🛠 Todos los tutoriales