Arduino ile projelerimizi geliştirmeye başladığımızda öğrendiğimiz ilk fonksiyon genellikle delay() olur. Bir LED'i yakıp söndürmek, bir sensörü saniyede bir okumak için delay(1000); yazıp geçeriz. İlk başlarda her şey harika görünür.
Ancak projeniz büyüdüğünde karşınıza çok ciddi bir duvar çıkar: Aynı anda hem bir butona basılıp basılmadığını kontrol etmek, hem ekrandaki veriyi güncellemek, hem de bir motoru sürmek isterseniz, delay() tüm sistemi kilitler. Çünkü delay() fonksiyonu çağrıldığında, Arduino o süre boyunca kelimenin tam anlamıyla "uyur" ve başka hiçbir işlem yapamaz.
Peki, Arduino'ya aynı anda birden fazla işi nasıl yaptırabiliriz? Çözüm: millis() fonksiyonu.
delay() ve millis() arasındaki farkı anlamak için mutfağa girelim.
delay() Mantığı: Pilavı ocağa koyuyorsunuz ve 20 dakika boyunca tencerenin başında kronometreye bakarak dikiliyorsunuz. Bu sırada kapı çalıyor duymuyorsunuz, telefon çalıyor açmıyorsunuz. Sadece pilavın pişmesini bekliyorsunuz.
millis() Mantığı: Pilavı ocağa koyuyorsunuz, saate bakıyorsunuz (Örn: Saat 14:00). Kafanızda şu hesabı yapıyorsunuz: "Saat 14:20 olduğunda ocağı kapatacağım." Bu 20 dakikalık süreçte gidip televizyon izleyebilir, kapı çalarsa açabilir, telefonunuza bakabilirsiniz. Sadece ara sıra duvardaki saate bakıp zamanın gelip gelmediğini kontrol edersiniz.
İşte millis() tam olarak duvardaki bu saattir.
millis(), Arduino kartınıza güç verildiği andan itibaren milisaniye (saniyenin binde biri) cinsinden saymaya başlayan dahili bir kronometredir.
Önemli Bilgi: millis() fonksiyonu arka planda sürekli sayar ve unsigned long (işaretsiz büyük tam sayı) türünde bir değer döndürür. Sıfırdan başlayıp yaklaşık 50 gün boyunca kesintisiz sayabilir. 50 günün sonunda hafızası dolar ve otomatik olarak tekrar sıfıra döner.
Eğer delay() kullansaydınız, bir LED'i 1 saniyede bir, diğer LED'i ise 3 saniyede bir bağımsız olarak yakıp söndürmeniz imkansız olurdu. Gelin bunu millis() ile nasıl çok kolayca yapabileceğimizi kod üzerinde görelim:
// LED pinlerini tanımlayalım
const int led1Pin = 12;
const int led2Pin = 13;
// LED'lerin anlık durumlarını tutacak değişkenler
bool led1Durum = LOW;
bool led2Durum = LOW;
// Her bir LED'in en son ne zaman durum değiştirdiğini tutacak "saat" değişkenleri
unsigned long eskiZamanLED1 = 0;
unsigned long eskiZamanLED2 = 0;
// LED'lerin yanıp sönme aralıkları (milisaniye cinsinden)
const long aralikLED1 = 1000; // 1 saniye
const long aralikLED2 = 3000; // 3 saniye
void setup() {
pinMode(led1Pin, OUTPUT);
pinMode(led2Pin, OUTPUT);
}
void loop() {
// Duvardaki saate bakıyoruz: Şu anki zamanı milisaniye olarak al
unsigned long suankiZaman = millis();
// --- LED 1 İÇİN KONTROL ---
// Şu anki zamandan, LED1'in en son değiştiği zamanı çıkarıyoruz.
// Eğer geçen süre 1000 ms'yi geçmişse içeri gir!
if (suankiZaman - eskiZamanLED1 >= aralikLED1) {
eskiZamanLED1 = suankiZaman; // Saati güncelle (Son işlem zamanını kaydet)
led1Durum = !led1Durum; // Durumu tersine çevir (Açıksa kapat, kapalıysa aç)
digitalWrite(led1Pin, led1Durum);
}
// --- LED 2 İÇİN KONTROL ---
// Eğer geçen süre 3000 ms'yi geçmişse içeri gir!
if (suankiZaman - eskiZamanLED2 >= aralikLED2) {
eskiZamanLED2 = suankiZaman; // Saati güncelle
led2Durum = !led2Durum; // Durumu tersine çevir
digitalWrite(led2Pin, led2Durum);
}
// GÖRDÜĞÜNÜZ GİBİ DÖNGÜ HİÇ DURMUYOR!
// Buraya bir buton okuma kodu eklerseniz, anında tepki verecektir.
}
Arduino'da profesyonel, endüstriyel ve takılma yapmayan kararlı projeler üretmek istiyorsanız delay() fonksiyonuna elveda demeli ve millis() tabanlı asenkron kodlama yapısına alışmalısınız. İlk başta mantığı karmaşık gelse de, birkaç pratikten sonra projelerinizdeki özgürlüğü fark edeceksiniz.
Bu rehberle birlikte projelerinizdeki kilitlenme sorunlarını çözebildiniz mi? Bir sonraki projenizde millis() fonksiyonunu nerede kullanmayı planlıyorsunuz? Sorularınızı yorumlarda paylaşın!
Henüz yorum yapılmamış. İlk yorumu siz yapın!