3 / 8 tamamlandı
görev 3 · ~35 dk

Kararsız sistem

Tek eşik neden yetmez — bir mühendislik hatası yap, sonra düzelt

hedef

Görev 2'de yazdığın kodun gizli bir kusuru var. Önce onu göreceksin, sonra düzelteceksin.

Önce hatayı yaşa

Görev 2'nin kodu duruyor. Şimdi sırayla şu sayıları gir:

kod
599   ->  iyi
601   ->  SUSUZ
600   ->  iyi
602   ->  SUSUZ
598   ->  iyi

Gördün mü? Sayılar eşiğin etrafında dolaşırken karar her seferinde değişiyor.

Şimdi bunun gerçekte ne demek olduğunu düşün. Toprak tam eşiğin sınırında. Sensör doğal olarak biraz oynuyor — 599, 601, 600, 602. Sistem her ölçümde fikir değiştiriyor.

Bu bir sulama sistemiyse pompa saniyede bir açılıp kapanıyor. Bir kilitse servo titriyor. Bir termostatsa kombi durmadan yanıp sönüyor.

Buna kararsızlık deniyor ve ölçüm yapan her sistemin baş belasıdır.

Buzdolabının neden sürekli çalışmadığını hiç düşündün mü? İçerisi 4 dereceye gelince durur, 6 dereceye çıkana kadar beklemez — 4'te durur, 7'ye çıkınca çalışır. Arada üç derecelik bir boşluk bırakır. Tam olarak bu görevde yapacağın şey.

Çözüm: bir eşik değil, iki eşik

Tek çizgi yerine bir bant kullanacaksın:

Aradaki 150 birimlik boşluk, sensörün doğal oynamasını yutuyor. Buna histerezis deniyor.

bool — iki değerli değişken

Sistemin kararını bir yerde tutman lazım. Bunun için int gerekmiyor, sadece iki hal var: susuz ya da değil.

kod · .ino
bool susuzMu = false;

bool sadece true (doğru) ya da false (yanlış) tutar. Adını soru gibi koymak iyi bir alışkanlık: susuzMu, kilitAcik, kapiKapali — okuduğunda cevabı belli oluyor.

Kod

kod · .ino
const int SUSUZ_ESIGI = 600;   // bunun ÜSTÜNE çıkarsa: susuz
const int DOYDU_ESIGI = 450;   // bunun ALTINA inerse: doydu

bool susuzMu = false;

void setup() {
  Serial.begin(9600);
  Serial.println("Toprak degeri gir (0-1023):");
}

void loop() {
  if (Serial.available() > 0) {
    int deger = Serial.parseInt();
    while (Serial.available()) Serial.read();

    // ŞİMDİ SEN YAZ:
    // deger SUSUZ_ESIGI'nin ustundeyse susuzMu = true
    // deger DOYDU_ESIGI'nin altindaysa susuzMu = false
    // Arada kalirsa hicbir sey yapma.

    Serial.print(deger);
    Serial.println(susuzMu ? "  ->  SUSUZ" : "  ->  iyi");
  }
}

Son satırdaki ? ve : garip görünüyor olabilir. Kısa bir if yazma biçimi: şart doğruysa soldakini, değilse sağdakini kullan. İstersen normal if'le de yazabilirsin, aynı şey.

Şimdi sen yaz

🔍 İpucu 1

İki tane ayrı if yazacaksın. else kullanma.

else kullanırsan "ya öyle ya böyle" demiş olursun — ama sen üçüncü bir ihtimal istiyorsun: hiçbir şey yapma.

✅ Cevap
kod · .ino
if (deger > SUSUZ_ESIGI) {
  susuzMu = true;
}
if (deger < DOYDU_ESIGI) {
  susuzMu = false;
}

Bu iki ayrı if, if/else değil. Fark burada:

if/else yazsaydın her değer için mutlaka bir karar verilirdi — ya true ya false. Arada kalan değerler de bir tarafa itilirdi ve titreme geri gelirdi.

İki ayrı if ile 500 girdiğinde hiçbiri çalışmıyor. susuzMu neyse öyle kalıyor. Sistemin kararlı olmasının sebebi tam olarak bu: bazen hiçbir şey yapmamak.

Kodda "hiçbir şey yapma" durumunu bilerek bırakmak, yeni başlayanların en zor kabul ettiği fikirdir. Boşluk bir eksiklik değil, tasarımın parçası.

📄 Görevin tam kodu
kod · .ino
const int SUSUZ_ESIGI = 600;   // kendi sayın
const int DOYDU_ESIGI = 450;   // kendi sayın

bool susuzMu = false;

void setup() {
  Serial.begin(9600);
  Serial.println("Toprak degeri gir (0-1023):");
}

void loop() {
  if (Serial.available() > 0) {
    int deger = Serial.parseInt();
    while (Serial.available()) Serial.read();

    if (deger > SUSUZ_ESIGI) {
      susuzMu = true;
    }
    if (deger < DOYDU_ESIGI) {
      susuzMu = false;
    }

    Serial.print(deger);
    Serial.println(susuzMu ? "  ->  SUSUZ" : "  ->  iyi");
  }
}

Çalıştı mı?

Aynı testi tekrar yap:

kod
599   ->  iyi
601   ->  SUSUZ
600   ->  SUSUZ     ← degismedi!
598   ->  SUSUZ     ← hala degismedi
440   ->  iyi       ← ancak burada dondu

601'de susuz oldu ve 440'a inene kadar öyle kaldı. Arada ne yazarsan yaz fikrini değiştirmedi.

Sistem artık kararlı. Bunu tek bir else silerek yaptın.

Olmadıysa

Ne görüyorsun Ne yap
Hâlâ her sayıda değişiyor if/else yazmışsın. İki ayrı if olacak
Hep "SUSUZ" yazıyor, hiç dönmüyor İkinci if'te < yerine > yazmışsın
Hep "iyi" yazıyor DOYDU_ESIGI SUSUZ_ESIGI'den büyük olmuş, sayıları kontrol et
Derleme hatası: susuzMu was not declared bool susuzMu satırını setup'ın üstüne, en dışa yazdın mı?

Kendini test et

Soru: İki eşik arasını 150 yerine 5 yapsan ne olur? Ya 900 yapsan?

Cevabı gör

Çok dar (5): Titreme geri gelir. Sensörün doğal oynaması boşluğu aşar ve sistem yine kararsızlaşır.

Çok geniş (900): Sistem tembelleşir. Toprak kupkuru olmadan "susuz" demez, sonra da bataklığa dönene kadar "iyi" der. Kararlıdır ama işe yaramaz.

Doğru genişlik yok, doğru soru var: Sensörüm ne kadar oynuyor? Boşluk o oynamadan büyük, ama sistemin tepki vermesi gereken gerçek değişimden küçük olmalı.

Bunu masa başında hesaplayamazsın — ölçersin. Sensörü sabit bırakıp bir süre okuduğun değerlere bakarsın; en yüksek ile en düşük arasındaki fark, boşluğun alt sınırıdır.

Mühendislikte çoğu sayı böyle bulunur: tahminle değil, ölçümle.


Takıldın, hata tablosu da yetmedi mi?

WhatsApp'tan sor — hangi görevdesin, ekranda ne yazıyor, devrenin fotoğrafı.