Menu
CoddyTech

Condividere usando volatile

Fa parte della sezione Temporizzazione senza delay del percorso Arduino di Coddy. Lezione 14 di 18.

Un ISR dovrebbe svolgere rapidamente una sola operazione, quindi di solito imposta una variabile che il resto dello sketch leggerà. Una variabile usata da entrambi deve essere dichiarata volatile:

volatile bool started = false;

void onPress() {
  started = true;
}

Per risparmiare tempo, il compilatore (il programma che trasforma il tuo C++ nelle istruzioni del chip) può conservare una copia di una variabile nel processore invece di leggere la memoria. Non sa che un interrupt può modificare la variabile, quindi lo sketch potrebbe usare per sempre la vecchia copia. volatile fa sì che la variabile venga letta da capo ogni volta.

Questo sketch attende in setup() con un ciclo while: while (condition) { } ripete il contenuto delle parentesi graffe finché la condizione è vera, qui !started. Come nella sezione Inputs, ! significa non: il ciclo si ripete mentre started è falso. Senza volatile, può attendere per sempre, anche dopo la pressione.

challenge icon

Sfida

Facile

Questo sketch dovrebbe attendere finché non viene premuto il pulsante, poi far lampeggiare il LED. Al momento attende per sempre. Correggilo:

  • in onPress(), imposta started su true
  • dichiara started come volatile

Premi Run, premi il pulsante, poi Check. Prova una volta senza volatile per vedere la scheda rimanere bloccata.

Provalo tu

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

bool started = false;   // impostato dall'interrupt, letto dallo sketch

unsigned long previousMillis = 0;
int ledState = LOW;

void onPress() {
  // imposta started a true qui
}

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

  // attendi qui finché non viene premuto il pulsante
  while (!started) {
  }
}

void loop() {
  // lampeggia ogni 250 ms
  unsigned long now = millis();
  if (now - previousMillis >= 250) {
    previousMillis = now;
    if (ledState == LOW) {
      ledState = HIGH;
    } else {
      ledState = LOW;
    }
    digitalWrite(ledPin, ledState);
  }
}
quiz iconMettiti alla prova

Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.

Tutte le lezioni di Temporizzazione senza delay

Esercitati da solo: Playground Arduino