Değişkeni volatile(geçici) olarak bildirmek, derleyiciye yönelik bir yönergedir. Derleyici, C/C++ kodunuzu Arduino'daki Atmega çipi için gerçek talimatlar olan makine koduna çeviren bir yazılımdır.
Spesifik olarak, derleyiciyi, değişkeni program değişkenlerinin depolandığı ve işlendiği geçici bir bellek konumu olan bir depolama kaydından değil, RAM'den yüklemesi için yönlendirir. Belirli koşullar altında, kayıtlarda saklanan bir değişkenin değeri yanlış olabilir.
Bir değişken, aynı anda çalışan bir iş parçacığı gibi göründüğü kod bölümünün kontrolü dışındaki bir şey tarafından değeri değiştirilebildiğinde geçici olarak bildirilmelidir.Arduino'da, bunun meydana gelmesi muhtemel olan tek yer, "servis rutinini kesintiye uğratmak" olarak adlandırılır.
Çözümü:
Değişken okunurken, kesmelerin devre dışı bırakılması gerekir, böylece okunurken bitlerle uğraşamazlar. Bunu yapmanın birkaç yolu vardır:
1.)noInterrupts
2.)ATOMIC_BLOCK makrosunu kullanın. Atomik işlemler tek MCU işlemler ve mümkün olan en küçük birimdir.
// "input" değiştiyse LED'i 1 saniye yanıp söner
// önceki saniyede.
volatile byte changed = 0;
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
attachInterrupt(digitalPinToInterrupt(2), toggle, CHANGE);
}
void loop() {
if (changed == 1) {
// toggle() kesintilerden çağrıldı!
// sıfırlama 0(sıfır) olarak değiştirildi.
changed = 0;
// 200 ms boyunca yanıp sönen LED
digitalWrite(LED_BUILTIN, HIGH);
delay(200);
digitalWrite(LED_BUILTIN, LOW);
}
}
void toggle() {
changed = 1;
}
#include util/atomic.h // Bu kitaplık, ATOMIC_BLOCK makrosunu içerir.
volatile int input_from_interrupt;
// Kodun içinde bir yerde,örn. inside loop()
ATOMIC_BLOCK(ATOMIC_RESTORESTATE){
// kesintili kod bloke edildi (ardışık atomik işlemler kesintiye uğramaz)
int result = input_from_interrupt;
}