Daten teilen mit volatile
Teil des Abschnitts Timing ohne Delay der Arduino-Journey von Coddy. Lektion 14 von 18.
Eine ISR sollte eine schnelle Aufgabe erledigen, deshalb setzt sie normalerweise eine Variable, die der Rest des Sketches ausliest. Eine Variable, die beide verwenden, muss als volatile deklariert werden:
volatile bool started = false;
void onPress() {
started = true;
}Um Zeit zu sparen, kann der Compiler (das Programm, das deinen C++-Code in die Anweisungen für den Chip umwandelt) eine Kopie einer Variable im Prozessor behalten, anstatt den Speicher auszulesen. Er weiß nicht, dass ein Interrupt die Variable ändern kann, deshalb verwendet der Sketch möglicherweise für immer die alte Kopie. Mit volatile wird die Variable jedes Mal neu ausgelesen.
Dieser Sketch wartet in setup() mit einer while-Schleife: while (condition) { } wiederholt den Inhalt der geschweiften Klammern, solange die Bedingung wahr ist, hier !started. Wie im Abschnitt „Eingaben“ bedeutet ! „nicht“: Die Schleife wird wiederholt, solange started falsch ist. Ohne volatile kann sie für immer warten, auch nachdem die Taste gedrückt wurde.
Aufgabe
EinfachDieser Sketch sollte warten, bis die Taste gedrückt wird, und dann die LED blinken lassen. Im Moment wartet er für immer. Behebe das:
- setze in
onPress()startedauftrue - deklariere
startedalsvolatile
Drücke Run, drücke die Taste und dann Check. Probiere es einmal ohne volatile aus, um zu sehen, wie das Board hängen bleibt.
Probier es selbst
const int ledPin = 13;
const int buttonPin = 2;
bool started = false; // vom Interrupt gesetzt, vom Sketch gelesen
unsigned long previousMillis = 0;
int ledState = LOW;
void onPress() {
// started hier auf true setzen
}
void setup() {
pinMode(ledPin, OUTPUT);
pinMode(buttonPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(buttonPin), onPress, FALLING);
// hier warten, bis der Taster gedrückt wurde
while (!started) {
}
}
void loop() {
// alle 250 ms blinken
unsigned long now = millis();
if (now - previousMillis >= 250) {
previousMillis = now;
if (ledState == LOW) {
ledState = HIGH;
} else {
ledState = LOW;
}
digitalWrite(ledPin, ledState);
}
}
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Timing ohne Delay
3Interrupts
Ein Tastendruck, den die Schleife verpasstFALLING, RISING und CHANGEDaten teilen mit volatileTastendrücke per Interrupt zählenÜbe selbstständig: Arduino-Playground