Menu
CoddyTech

Partager avec volatile

Fait partie de la section Gestion du temps sans delay du Journey Arduino de Coddy. Leçon 14 sur 18.

Une ISR doit effectuer une seule action rapide, elle définit donc généralement une variable que le reste du sketch peut lire. Une variable que les deux utilisent doit être déclarée volatile :

volatile bool started = false;

void onPress() {
  started = true;
}

Pour gagner du temps, le compilateur (le programme qui transforme votre C++ en instructions pour la puce) peut conserver une copie d’une variable dans le processeur au lieu de lire la mémoire. Il ne sait pas qu’une interruption peut modifier la variable, le sketch risque donc d’utiliser indéfiniment l’ancienne copie. volatile lui indique de relire la variable à chaque fois.

Ce sketch attend dans setup() avec une boucle while : while (condition) { } répète son contenu tant que la condition est vraie, ici !started. Comme dans la section Inputs, ! signifie « non » : la boucle se répète tant que started est faux. Sans volatile, l’attente peut durer indéfiniment, même après l’appui.

challenge icon

Défi

Facile

Ce sketch doit attendre que le bouton soit appuyé, puis faire clignoter la LED. Pour le moment, il attend indéfiniment. Corrige-le :

  • dans onPress(), définis started sur true
  • déclare started comme volatile

Appuie sur Run, appuie sur le bouton, puis sur Check. Essaie une fois sans volatile pour voir la carte rester bloquée.

Essayez vous-même

const int ledPin = 13;
const int buttonPin = 2;

bool started = false;   // défini par l’interruption, lu par le sketch

unsigned long previousMillis = 0;
int ledState = LOW;

void onPress() {
  // définir started à true ici
}

void setup() {
  pinMode(ledPin, OUTPUT);
  pinMode(buttonPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(buttonPin), onPress, FALLING);

  // attendre ici jusqu’à ce que le bouton soit pressé
  while (!started) {
  }
}

void loop() {
  // clignoter toutes les 250 ms
  unsigned long now = millis();
  if (now - previousMillis >= 250) {
    previousMillis = now;
    if (ledState == LOW) {
      ledState = HIGH;
    } else {
      ledState = LOW;
    }
    digitalWrite(ledPin, ledState);
  }
}
quiz iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Gestion du temps sans delay

Entraînez-vous par vous-même : Playground Arduino