Arkadaşlar merhaba, bu yazıda Arduino’da kesme(interrupt) nedir, nerede ve nasıl kullanılır onu anlatmaya çalışacağım. Basitçe kesme, Arduino’da kullanılan işlemcimizin, bizim belirlediğimiz bir anda yapmakta olduğu işi bırakıp, bizim istediğimiz işi yapması ve sonra kaldığı yerden devam etmesidir.

Akıllarda daha iyi otursun diye bir örnek vermek gerekirse; siz belirli aralıklar ile bilgisayarınızda belirli işleri yapıyorsunuz, bilgisayar başında ödevinizi yapıp, ders çalışıyorsunuz , daha sonra düzenlenmesi gereken işleri yapıyorsunuz aniden kapı çalıyor. Ne yaparsınız? Tabiki de yaptığınız işi bırakıp kapıyı açar daha sonra yarım kalan işe geri dönersiniz. İşte bu örnekte, hali hazırda yapmakta olduğunuz iş işlemcinizin içindeki kodda yaptığınız iş. Arduino için örnek vermek gerekirse, void loop() fonksiyonu. Kapının çalması ise kesme yani interrupt.

Yukarıdaki örnekte olduğu gibi kesme işlemi kapının çalması gibi dışarıdan da gelebilir ya da belirli zaman aralıkları ile de oluşabilir. Örneğe sadık kalmak amacı ile, ders çalışırken belirli aralıklar ile hap içmeniz gibi düşünebilirsiniz.

Yukarıda kısaca anlattığım gibi kesmeler Zaman Kesmesi(Timer Interrupt) ve Dış Kesme(External Interrupt) olarak ikiye ayrılır.

 

Interrupt Neden Kullanılır?

Örneğin bizim arduino’nun interrupt pinlerine bağlı bir butonumuz olsun. Normal şartlarda interrupt kullanmazdan direk buton kodu ile  if-else şeklinde butonu kullanmayı denersek kodumuz sadece if kısmı geldiğinde butona basılıp basılmadığını kontrol edecek ve o zaman if’in içine girebilecek. Örneğin 5 saniye yanıp 5 saniye sönen bir led imiz olsun ve butona basıldığında ledin yanıyorsa yönmesini, sönük durumda ise yanmasını isteyelim. Bu durumda koddaki 5 saniyelik delay kısmına butona istediğimiz kadar basalım kod beklemede olduğu için hiç bir işlemi yerine getiremeyecektir.

İşte bu noktada devreye interrupt giriyor. Interrupt, kod delay fonksiyonu içinde bile olsa devreye girip istenilen işlemleri yaptırabiliyor. Yani kısaca interrupt, anlık müdehale yapamız gereken yerlerde kullanılıyor.

Kesme Çeşitleri 

1)Dış Kesme(External Interrupt)

Dış kesme, Arduino’nun özel pinlerindeki voltaj değişimlerine göre davranan kesmedir.

Board Kesme için kullanılabilecek dijital pinler
Uno, Nano, Mini, other 328-based 2, 3
Mega, Mega2560, MegaADK 2, 3, 18, 19, 20, 21
Micro, Leonardo, other 32u4-based 0, 1, 2, 3, 7
Zero 4. hariç tüm dijital pinler
MKR1000 Rev.1 0, 1, 4, 5, 6, 7, 8, 9, A1, A2
Due Tüm dijital pinler

 

Dış kesme pinleri her Arduino modelinde farklılık göstermektedir. Örneğin, Arduino UNO’nun 3. pinine bir buton bağlayalım ve kesme olarak kullanılacak şekilde ayarlayalım. Bu butona basıldığında kod her nerde olursa olsun bizim istediğimiz işlemleri yapacaktır.

Dış kesme 4 farklı şekilde yapılabilir. Bunlar;

LOW – Dijital pindeki gerilim 0 olduğunda kesmeye girer

CHANGE – Belirli dijital pinde oluşacak her gerilim değişiminde kesmeye girer. Yani pindeki gerilim 0’dan 5’e yükseldiğinde veya 5’ten 0’a düştüğünde kesmeye girer.

RISING – Yükselen kenar olduğunda kesmeye girer. Yani dijital pindeki gerilim 0’dan 5 Volta çıktığında kesmeye girer.

FALLING – Düşen kenar olduğunda kesmeye girer. Yani dijital pindeki gereilim 5’dan 0 Volta çıktığında kesmeye girer.

şeklindeki kesmelerdir.

Arduino da dış kesme AttachInterrupt(); fonksiyonu kullanılarak yapılmaktadır. AttachInterrup fonksiyonu içerisinde 3 adet değişken barındırır.

AttachInterrupt(dijitalPin,kesme fonksiyonu, kesme modu); 

Bu değişkenlerin ilki dijitalPin olup Arduino’nun kesme için kullandığımız pinidir. Fakat burada dijital pin olarak Arduino’da kaçıncı pine bağladığımız değil örneğin Arduino UNO da 2. dijital pine bağlı ise 0, 3. dijital pine bağlı ise 1 yazılmalıdır.

Kesme fonksiyonu, kesmeye girildiğinde yapılması gereken işlemlerin içinde bulunduğu fonksiyondur. Void loop’un altına yazılmalıdır.

Kesme modu, kesmeye ne zaman girileceğini gösteren modlar. LOW, RISING vb.

Dış Kesme Örneği:

Dış kesmeyi bir örnek ile pekiştirelim. Örneğimizde bir led, buton ile kontrol edilecektir. Bunun için 1 adet interrupt, CHANGE modunda kullanılmıştır.

external_interrupt_devre_semasi

int ledPin = 8;
boolean led_durumu = LOW;
int butonPin = 7;
void setup() {
  pinMode(ledPin, OUTPUT);
  pinMode(butonPin,INPUT);
  attachInterrupt(1, goz_kirpmasi, CHANGE);
}

void loop() {
  
}

void goz_kirpmasi() {
  led_durumu = !led_durumu;
  digitalWrite(ledPin, led_durumu);
}

2)Zaman Kesmesi(Timer Interrupt)

Zaman kesmesi, belirlediğimiz süre sonunda, belirlediğimiz görevleri yapmaya yarayan kesmedir. Örneğin 1 saniyede bir kodda nerede olursak olalım sensörden veri okumak istersek bu kesmeyi kullanabiliriz. Kod o sırada delay fonksiyonu içinde bile olsa sensörden veri almaya devam edecektir.

Timer kullanımı için zaman sayıcısının değerleri ayarlanmalıdır. Zaman sayıcısı, her saat sinyalinde 1 artan sayaç gibi düşünülebilir ve belirli bir değere ulaştığında sürenin dolduğu anlaşılır ve işlemcimiz kesme fonksiyonu içerisine girer.

Örneğin 8 bitlik bir zaman sayıcımız olsun. Sayıcımızın ilk değeri 100 olarak belirlensin. Bu değer her bir saat darbesinde artacak olup 255’i geçtiği anda sıfırlanacaktır ve kesme fonksiyonu içerisine girilecektir. Bu fonksiyon ISR(TIMER1_COMPA_vect) fonksiyonudur.

Zaman kesmesinin frekansı şu formül ile bulunur:

Zaman Kesmesi(Hz) = Arduino’nun kristal Hızı/(Zaman Kesmesinin Çözünürlüğü – Sayıcının Başlangıç Değeri + 1)

Burada Arduino’nun kristal hızı 16MHz olup, zaman kesmesi çözünürlüğü 8 bit olduğu için 255’tir. yani Zaman kesmesinin frekansı maximum 62.500 olabilir.

Zaman Kesmesi Örneği:

Bu örnekte Arduino’yu ilk kullanmaya başladığımızda gördüğümüz led yakıp söndürme işlemini zaman kesmesi kullanarak yapacağız. Kodu Arduino’ya attıktan sonra, 13. pine bağlı olan ledin saniyede bir yanıp söndüğünü göreceğiz.

int ledPin = 13;
boolean led_durumu = LOW;

void setup(){
  pinMode(ledPin,OUTPUT);
  
  cli();

  // Timer1 kesmesi ayarlanıyor
  TCNT1  = 0;
  TCCR1A = 0;
  TCCR1B = 0;
  OCR1A = 15624;  // 1 saniye çalışması için gerekli zaman kesmesi frekansı
  TCCR1B |= (1 << WGM12);
  TCCR1B |= (1 << CS12) | (1 << CS10);
  TIMSK1 |= (1 << OCIE1A);
  sei();
}


ISR(TIMER1_COMPA_vect){     //Her kesmeye girildiğinde otomatik çalıştırılacak fonksiyon.
 led_durumu = !led_durumu;
  digitalWrite(ledPin, led_durumu);
}

void loop(){
delay(10000);
}

 

8 Yorumlar

  1. Merhaba,
    Dış kesme için yazmış olduğunuz kod yanlış sanırım.Buton değişkeninin 7.pine değil 3.pine bağlanması gerekli.

    • Evet orda bir ayrıntıyı atlamışlar
      Makalede uno da 2 ve 3 numaralı pin kullanılabilir demişler ama örnekte 7 kullanılmış.

  2. Bir sorum olacak;
    Bir led düşünün ve led yandığında role ve arduino yardımı ile elektrik kesebilecek bir devre lazım çok önemli lütfen böyle biiey mümkünmü ve mümkünse varmı?

    • Mümkündür. LED’in durumunu Arduino’nun dijital girişlerine bağlayarak okutabilir ve bu duruma bağlı olarak bir röle veya kontaktör ile anahtarlama yapabilirsiniz.

CEVAP VER