Beklemeden beklemek
delay() sistemi dondurur — millis() ile donmadan bekle
delay() yerine millis() kullanmak. Gömülü yazılımın en temel dersi bu.
Önce donmayı yaşa
Şu kodu yükle:
void setup() {
Serial.begin(9600);
Serial.println("Bir sayi yaz:");
}
void loop() {
if (Serial.available() > 0) {
int deger = Serial.parseInt();
while (Serial.available()) Serial.read();
Serial.print("Aldim: ");
Serial.println(deger);
}
Serial.println("bekliyorum...");
delay(3000);
}
Çalıştır. Her üç saniyede bir bekliyorum... yazıyor.
Şimdi hızlıca bir sayı yaz ve Enter'a bas. Sonra bir tane daha. Bir tane daha.
Yazdıklarının çoğu kayboluyor. Sistem seni duymuyor.
Neden
delay(3000) çalışırken kart hiçbir şey yapamaz. Uyuyor. Serial'e bakmıyor, sensör okumuyor, tuş dinlemiyor. Üç saniye boyunca tamamen kör.
Şimdiye kadar sorun olmadı çünkü kodun tek iş yapıyordu. Ama gerçek bir sistem aynı anda birkaç şeye bakmak zorunda: toprağı ölçmek, depoyu kollamak, ekranı güncellemek, kart okumak.
Bir kapı kilidi düşün: kilit açıldıktan sonra beş saniye bekliyor. O beş saniyede kart okumuyor, alarma bakmıyor, kapının zorlanıp zorlanmadığını görmüyor.
delayile yazılmış bir güvenlik sistemi, beklerken güvensizdir.
Çözüm: beklemek yerine saate bakmak
millis() kart açıldığından beri geçen milisaniyeyi verir. Sen ne yaparsan yap, o saymaya devam eder.
Fikir şu: "3 saniye bekle" demek yerine, "en son ne zaman yaptım, üstünden 3 saniye geçti mi" diye sor.
// PARCA - sadece kalibi gosteriyor, tam kod asagidaki blokta
unsigned long sonYazma = 0;
const unsigned long ARALIK = 3000;
void loop() {
if (millis() - sonYazma >= ARALIK) {
sonYazma = millis();
Serial.println("bekliyorum...");
}
// buraya gelen kod HER TURDA calisir, donma yok
}
unsigned longneden?millis()çok büyük sayılar üretiyor — 50 gün yaklaşık 4 milyar milisaniye.intbu kadarını tutamaz, taşar ve saçmalar.unsigned longdört bayt yer kaplar ve negatif olmayan büyük sayıları tutar. Zamanla çalışan her değişkeni böyle tanımla.
Kod
unsigned long sonYazma = 0;
const unsigned long ARALIK = 3000;
void setup() {
Serial.begin(9600);
Serial.println("Bir sayi yaz:");
}
void loop() {
if (Serial.available() > 0) {
int deger = Serial.parseInt();
while (Serial.available()) Serial.read();
Serial.print("Aldim: ");
Serial.println(deger);
}
// ŞİMDİ SEN YAZ:
// Son yazmanin uzerinden ARALIK kadar zaman gectiyse
// "bekliyorum..." yaz ve sonYazma'yi guncelle.
}
Şimdi sen yaz
🔍 İpucu 1
Geçen süre: millis() - sonYazma
Bunu ARALIK ile karşılaştır. Yeterince geçtiyse yazdır — ve sonYazma'yı şu ana güncellemeyi unutma, yoksa bir daha hiç durmaz.
✅ Cevap
if (millis() - sonYazma >= ARALIK) {
sonYazma = millis();
Serial.println("bekliyorum...");
}
Neden çıkarma yapıyoruz, sonYazma + ARALIK ile karşılaştırmıyoruz?
millis() yaklaşık 50 günde sayacın sonuna gelip sıfırdan başlıyor. Toplama yaparsan o an hesap bozulur ve sistem takılır. Çıkarma yaparsan başa sarma otomatik olarak doğru sonucu verir.
Elli gün sana uzak geliyor olabilir. Bir kapı kilidi ya da sulama sistemi için değil — ve o gün geldiğinde sen orada olmayacaksın.
📄 Görevin tam kodu
unsigned long sonYazma = 0;
const unsigned long ARALIK = 3000;
void setup() {
Serial.begin(9600);
Serial.println("Bir sayi yaz:");
}
void loop() {
if (Serial.available() > 0) {
int deger = Serial.parseInt();
while (Serial.available()) Serial.read();
Serial.print("Aldim: ");
Serial.println(deger);
}
if (millis() - sonYazma >= ARALIK) {
sonYazma = millis();
Serial.println("bekliyorum...");
}
}
Çalıştı mı?
Aynı testi tekrar yap: üç saniyede bir bekliyorum... akarken hızlıca sayı yaz.
Bu sefer hepsi anında cevap alıyor. Sistem hem bekliyor hem uyanık.
bekliyorum...
Aldim: 5
Aldim: 12
bekliyorum...
Aldim: 7
Olmadıysa
| Ne görüyorsun | Ne yap |
|---|---|
| Hiç durmadan yazıyor | sonYazma = millis(); satırını yazmamışsın |
| Bir kez yazıp susuyor | sonYazma = millis() satırını if'in dışına koymuşsun |
| Sayılar hâlâ kayboluyor | delay(3000) satırını silmemişsin |
| Bir süre sonra tuhaflaşıyor | sonYazma'yı int yapmışsın, unsigned long olacak |
Kendini test et
Soru: delay() hiç kullanılmamalı mı?
Cevabı gör
Hayır. Kural "delay yasak" değil.
Kural şu: sistemin fark etmesi gereken bir şeyi kaçıracak kadar uzun bekleme.
Bir servo motorun dönmesi iki saniye sürüyorsa ve o sırada sistemin vereceği başka bir karar yoksa, delay(2000) gayet iyi bir araçtır — kısa, okunur, hatasız. Ama otuz saniye beklerken depo boşalabilir, kapı zorlanabilir, koşullar değişebilir. Orada körlük pahalıya patlar.
İyi mühendislik "şu komutu asla kullanma" ezberi değil. Bu bekleme sırasında neyi kaçırırım? diye sormaktır. Cevap "hiçbir şey" ise delay doğru araçtır.
İleride biri sana kesin bir kural olarak "delay kötüdür" derse, ona bu soruyu sor.
Takıldın, hata tablosu da yetmedi mi?
WhatsApp'tan sor — hangi görevdesin, ekranda ne yazıyor, devrenin fotoğrafı.