Kararsız sistem
Tek eşik neden yetmez — bir mühendislik hatası yap, sonra düzelt
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:
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:
- Değer
600'ün üstüne çıkarsa → susuz say - Değer
450'nin altına inerse → susuz sayma - Arada kalırsa hiçbir şey değiştirme — en son ne dediysen o kalsı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.
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
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 birifyazma biçimi: şart doğruysa soldakini, değilse sağdakini kullan. İstersen normalif'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
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
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:
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ı.