diff --git a/Language/Variables/Variable Scope & Qualifiers/volatile.adoc b/Language/Variables/Variable Scope & Qualifiers/volatile.adoc index 20fbd6fbd..79927f386 100644 --- a/Language/Variables/Variable Scope & Qualifiers/volatile.adoc +++ b/Language/Variables/Variable Scope & Qualifiers/volatile.adoc @@ -55,34 +55,47 @@ There are several ways to do this: === Example Code // Describe what the example code is all about and add relevant code ►►►►► THIS SECTION IS MANDATORY ◄◄◄◄◄ +The `volatile` modifier ensures that changes to the `state` variable are immediately visible in `loop()`. Without the `volatile` modifier, the `state` variable may be loaded into a register when entering the function and would not be updated anymore until the function ends. [source,arduino] ---- -// toggles LED when interrupt pin changes state +// Flashes the LED for 1 s if the input has changed +// in the previous second. -int pin = 13; -volatile byte state = LOW; +volatile byte changed = 0; void setup() { - pinMode(pin, OUTPUT); - attachInterrupt(digitalPinToInterrupt(2), blink, CHANGE); + pinMode(LED_BUILTIN, OUTPUT); + attachInterrupt(digitalPinToInterrupt(2), toggle, CHANGE); } void loop() { - digitalWrite(pin, state); + if (changed == 1) { + // toggle() has been called from interrupts! + + // Reset changed to 0 + changed = 0; + + // Blink LED for 200 ms + digitalWrite(LED_BUILTIN, HIGH); + delay(200); + digitalWrite(LED_BUILTIN, LOW); + } } -void blink() { - state = !state; +void toggle() { + changed = 1; } ---- +To access a variable with size greater than the microcontroller’s 8-bit data bus, use the `ATOMIC_BLOCK` macro. The macro ensures that the variable is read in an atomic operation, i.e. its contents cannot be altered while it is being read. [source,arduino] ---- #include // this library includes the ATOMIC_BLOCK macro. volatile int input_from_interrupt; +// Somewhere in the code, e.g. inside loop() ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { // code with interrupts blocked (consecutive atomic operations will not get interrupted) int result = input_from_interrupt;