Rehberler · 19 dk okuma

Arduino Akıllı Sera Projesi: Sensörler, Sulama, Fan ve Kod

Arduino akıllı sera projesi: DHT22, toprak nemi ve LDR ile ölçüm; röle ve MOSFET ile fan, ısıtıcı, pompa ve LED kontrolü, histerezis, LCD ve ESP32 kodu.

Akıllı sera projesi, bir Arduino ya da ESP32 ile seradaki sıcaklığı, havadaki nemi, toprağın nemini ve ışığı ölçüp fanı, ısıtıcıyı, su pompasını ve bitki yetiştirme LED'lerini kendiliğinden çalıştırdığın bir otomasyon sistemidir. Arduino ile yapılan akıllı sera; bilim fuarlarının, TÜBİTAK 4006 ve 2204 projelerinin ve teknoloji derslerinin en sevilen konularından biridir, çünkü sonucu gözle görülür: toprak kuruyunca pompa çalışır, içerisi ısınınca fan döner, akşam olunca LED'ler yanar. Üstelik bir saklama kutusundan yapılmış maket sera ile balkondaki gerçek bir mini sera arasında devre ve kod açısından neredeyse hiç fark yoktur.

Bu rehberde bitkilerin hangi değerleri istediğinden başlıyoruz; ardından maket serayı, malzeme listesini ve yaklaşık maliyeti, sensörlerin (DHT22, kapasitif toprak nem sensörü, LDR) ve eylemcilerin (röle ve MOSFET ile fan, ısıtıcı, pompa ve LED) bağlantısını, güç planını ve pin tablosunu adım adım kuruyoruz. Sonra rölelerin durmadan tıkırdamasını önleyen eşik ve histerezis mantığını, delay() kullanmayan tam Arduino kodunu ve 16x2 LCD ekranı anlatıyoruz. Son bölümlerde serayı ESP32 ile telefondan izlemeyi, Raspberry Pi Pico ile MicroPython sürümünü, okul ve TÜBİTAK sunumu için ipuçlarını ve sık yapılan hataları bulacaksın.

DHT22 (AM2302)
DHT22 (AM2302)
LDR
LDR
I2C LCD 16x2
I2C LCD 16x2
LM2596
LM2596
Arduino Uno
Arduino Uno

Akıllı sera nasıl çalışır?

Her akıllı sera dört adımlık aynı döngüyle çalışır: ölç, karar ver, uygula, göster. Sensörler ortamı ölçer: içerisi kaç derece, hava ne kadar nemli, toprak kurudu mu, ışık yeterli mi? Arduino bu değerleri senin belirlediğin kurallarla karşılaştırır: "sıcaklık 30 °C'yi geçtiyse fanı çalıştır", "toprak nemi %35'in altına düştüyse sula". Eylemciler kararı uygular; röle fanı, ısıtıcıyı ve pompayı açıp kapatır, MOSFET ise LED şeridin parlaklığını ayarlar. Son olarak LCD ekran ve telefon, seranın o anki durumunu sana gösterir. Gerçek ticari seralardaki iklim kontrol bilgisayarları da tam olarak bu döngüyle çalışır; yalnızca daha çok sensör ve daha büyük motorlar kullanırlar.

Ne ölçülür?SensörEylemciKural (örnek)
Hava sıcaklığıDHT22Fan ve ısıtıcı30 °C'de fan çalışır, 16 °C'de ısıtıcı açılır
Havadaki bağıl nemDHT22Fan%85'te fan çalışır, %75'te durur
Toprak nemiKapasitif toprak nem sensörüMini dalgıç pompa%35'in altında 3 saniyelik darbelerle sular
IşıkLDRLED şerit (MOSFET)Hava kararınca LED'ler en fazla 4 saat yanar
Depodaki suŞamandıralı seviye sensörüPompa kilidiDepo boşsa pompa hiç çalışmaz

Bitkiler ne ister? Hedef sıcaklık, nem ve ışık

Kuralları yazmadan önce neyi hedeflediğini bilmen gerekir. Bitkilerin çoğu gündüz ve gece farklı sıcaklık ister; gece biraz serinlemek bitkinin dinlenmesine yardım eder. Havadaki nem uzun süre %85'in üstünde kalırsa yaprak yüzeyinde su yoğuşur, küf ve mildiyö gibi mantar hastalıkları hızla yayılır; bu yüzden seralarda fan yalnızca serinletmek için değil, nemi dışarı atmak için de çalışır. Işık tarafında sebze fidelerinin çoğu günde 14–16 saat ışık ister, ama en az 6–8 saatlik bir karanlık dönem de gerekir; LED'leri bütün gece açık bırakmak bitkiye yarardan çok zarar verir. Aşağıdaki değerler başlangıç için iyi bir rehberdir; yetiştirdiğin türe göre ayarlayabilirsin.

BitkiGündüzGeceBağıl nemNot
Domates21–27 °C15–18 °C%60–7532 °C'nin üstünde çiçekler dökülebilir
Biber21–29 °C16–20 °C%60–75Soğuğa domatesten daha duyarlıdır
Marul ve ıspanak15–20 °C10–15 °C%60–70Sıcak ve uzun günlerde erkenden tohuma kalkar
Çilek18–24 °C10–13 °C%60–75Yüksek nemde kurşuni küf riski artar
Fide ve çimlenme20–25 °C18–20 °C%70–85Toprak sıcaklığı hava sıcaklığından daha önemlidir
Gösteri günü sınıf 22 °C ise 30 °C'de çalışan bir fan hiç dönmez. Sunumda eşikleri ortamın 2–3 derece üstüne çek ki DHT22'yi avucunla ısıttığında jüri fanın çalıştığını birkaç saniyede görsün. Gerçek kullanımda ise tablodaki değerlere geri dön.

Maket sera yapımı

En kolay ve en ucuz gövde, şeffaf ve kapaklı bir plastik saklama kutusudur: 40–60 litrelik bir kutu iki ya da üç saksı için yeterlidir, su geçirmez ve maket bıçağıyla ya da ısıtılmış bir uçla kolayca delinir. Daha gerçekçi bir görünüm istersen ahşap çıtalardan bir iskelet kurup 2–3 mm'lik şeffaf pleksi (akrilik) ya da PETG levhalarla kaplayabilirsin; çift eğimli çatısı olan bir sera sunumda çok daha iyi görünür. Boyut olarak yaklaşık 50×35×40 cm iyi bir başlangıçtır. Hangi gövdeyi seçersen seç, kapağın ya da bir yan duvarın açılabilir olması gerekir; bitkiyi sulamak, sensörü taşımak ve kabloları düzeltmek için içeriye elini sokacaksın.

  • Elektronik dışarıda: Seranın içi nemli olur ve sabahları duvarlarda su yoğuşur. Arduino'yu, röle modülünü ve güç kaynağını seranın dışına, ayrı bir kutuya koy; içeride yalnızca sensörler, fan, ısıtıcı, pompa hortumu ve LED kalsın.
  • Havalandırma: Sıcak hava yükseldiği için fanı kısa duvarlardan birinin üst kısmına, havayı dışarı atacak yönde yerleştir. Karşı duvarın alt kısmına fan çapında bir hava giriş deliği aç ve üzerine sinek teli yapıştır; böylece taze hava alttan girer, sıcak ve nemli hava üstten çıkar.
  • Isıtıcı: Isıtıcıyı tabana yakın, bir alüminyum levhanın ya da seramik bir karonun üzerine, plastik duvarlardan ve bitkilerden en az 5 cm uzağa monte et. Isınan hava yükselirken bütün serayı dolaşır.
  • LED aydınlatma: LED şeridi kapağın iç yüzüne, bitkilerin 15–30 cm üstüne yapıştır. Şeridi ince bir alüminyum profilin üzerine yapıştırırsan ısısı daha iyi dağılır ve yapışkanı zamanla gevşemez.
  • Sensörler: DHT22'yi bitki yüksekliğinde, doğrudan güneş ya da LED ışığı almayacak bir yere koy. Toprak nem sensörünü kök bölgesine, saksı kenarından uzağa göm. LDR ise LED'leri görmemeli: onu seranın dışına, çatıya, gökyüzüne bakacak şekilde yerleştir.
  • Su deposu: 1–2 litrelik bir kap, pompa ve şamandıra için yeterlidir. Saksıların altına drenaj tabağı koy; fazla su tabakta toplanır ve kutunun tabanı göle dönmez.
Hortumun ucu depodaki su seviyesinden aşağıdaysa pompa durduktan sonra da su sifon etkisiyle akmaya devam eder ve saksıyı taşırır. Depoyu saksılardan alçakta tut ya da hortumun en yüksek noktasına iğneyle küçük bir hava deliği aç; pompa durunca deliğe hava girer ve akış hemen kesilir.

Malzeme listesi ve maliyet

ParçaAdetGöreviFiyat seviyesi
Arduino Uno R3 ya da ESP32 DevKit1Seranın beyniOrta
DHT22 (AM2302) sıcaklık ve nem modülü1Hava sıcaklığı ve nemiDüşük
Kapasitif toprak nem sensörü (v1.2)1 (her saksıya 1)Toprak nemiDüşük
LDR (GL5528) ve 10 kΩ direnç1 + 1Ortam ışığıÇok düşük
Şamandıralı su seviye sensörü1Depo boşken pompayı kilitlerDüşük
4 kanallı 5 V röle modülü (optokuplörlü, JD-VCC'li)1Fan, ısıtıcı ve pompaDüşük
Lojik seviye N-kanal MOSFET (IRLZ44N), 220 Ω ve 100 kΩ direnç1 takımLED şeridin parlaklığı (PWM)Çok düşük
3–6 V mini dalgıç pompa ve 1 m silikon hortum1SulamaDüşük
12 V 80 mm bilgisayar fanı1–2Havalandırma ve nem atmaDüşük
12 V PTC ısıtıcı (10–30 W) ve termal sigorta1 + 1IsıtmaDüşük
12 V LED şerit (bitki yetiştirme ya da soğuk beyaz), yaklaşık 1 m1Ek aydınlatmaDüşük
I2C 16x2 LCD ekran1Durum ekranıDüşük – orta
12 V 5 A adaptör ve LM2596 voltaj düşürücü1 + 1GüçOrta
1N5819 ya da 1N4007 diyot, 470 µF kondansatör, klemens, jumper kablolar–Koruma ve bağlantılarÇok düşük
Kapaklı şeffaf saklama kutusu ya da pleksi levha, saksılar, drenaj tabağı–Sera gövdesiOrta

Fiyatlar satıcıya ve kura göre sık değiştiği için kesin rakam yerine kabaca bir bütçe verelim. Kart hariç temel sürüm (DHT22, toprak nem sensörü, LDR, 2 kanallı röle, pompa ve 5 V fan) genellikle 400–700 TL arasında tutar. Isıtıcı, LED şerit, LCD, 12 V adaptör, LM2596, şamandıra ve gövdeyle tam sürüm ise çoğunlukla 1.200–2.000 TL civarındadır; bütçenin büyük kısmını kart, adaptör, ekran ve gövde oluşturur. Elinde bir Arduino başlangıç seti varsa kart, breadboard, kablolar, LDR, dirençler ve çoğu zaman LCD zaten hazırdır. Bütçe darsa ısıtıcıyı ve LED'i ikinci aşamaya bırak; sulama ve havalandırma tek başına da çalışan, anlamlı bir projedir.

Sensörler: DHT22, toprak nem sensörü ve LDR

Serada DHT22 (AM2302) kullanmanı öneriyoruz. DHT11'den biraz pahalıdır ama sıcaklığı −40 ile 80 °C arasında ±0,5 °C, nemi %0–100 aralığında yaklaşık ±%2 doğrulukla ölçer; DHT11 ise yalnızca 0–50 °C aralığında ±2 °C doğrudur ve %90'ın üstündeki nemi göremez. Sera sabahları %90'ı aşan neme ve kışın sıfırın altındaki sıcaklıklara sahne olabildiği için DHT22 bu işe çok daha uygundur. Sensör en fazla 2 saniyede bir ölçüm yapar, bu yüzden kod onu 2,5 saniyede bir okur. Sensörü güneşin ya da LED'in doğrudan vurduğu bir yere koyarsan gövdesi ısınır ve havadan birkaç derece yüksek okur; delikli beyaz bir kapakla gölgelemek bunu önler. Bağlantı ve kütüphane ayrıntıları DHT11 ve DHT22 sıcaklık ve nem sensörü yazısında.

Toprak nem sensörü modülü
Toprak nem sensörü: kök bölgesine gömülen uç, toprağın ne kadar ıslak olduğunu analog bir gerilimle bildirir; serada uzun ömür için kapasitif modeli seç.

Toprak nemi için kapasitif sensör seç. Ucuz rezistif sensörlerin (YL-69, FC-28) iki metal ucu toprağa doğrudan değer ve sürekli beslenirse elektroliz yüzünden birkaç haftada aşınır; serada aylarca çalışacak bir sistem için uygun değildir. Kapasitif sensörün elektrotu kaplamalıdır, metal toprağa hiç değmez. Çıkışı analogdur ve toprak ıslandıkça düşer: Uno'da havada tutulan bir sensör yaklaşık 500–600, suya batırılmış hâli 250–300 civarında okur. Bu sayılar her sensörde farklıdır; bu yüzden ana kodu yüklemeden önce kendi sensörünün havadaki ve sudaki değerini Seri Monitör'den okuyup koddaki SOIL_DRY_RAW ve SOIL_WET_RAW sabitlerine yaz. Kod bu iki değeri map() ile %0–100'e çevirir. Ayrıntılar Toprak nem sensörü yazısında.

Işık için kitlerdeki LDR (GL5528) yeterlidir. LDR'yi 10 kΩ'luk bir dirençle gerilim bölücü olarak bağla: 5V → LDR → A1 → 10 kΩ → GND. Işık arttıkça LDR'nin direnci düşer ve A1'deki değer yükselir; kod bu değeri de karanlıkta ve güneş altında ölçtüğün iki sayıya göre %0–100'e çevirir. LDR lüks ölçen hassas bir cihaz değildir, ama "hava karardı mı, bulutlu mu, güneşli mi?" sorusuna güvenilir bir cevap verir. Daha doğru ışık ölçümü istersen BH1750 gibi I2C bir ışık sensörüne geçebilirsin. Bölücü hesabı için Gerilim bölücü aracını, ayrıntılar için LDR ışık sensörü yazısını kullanabilirsin.

LDR, LED'lerin ışığını görürse sistem kendi kendine yanıp sönen bir döngüye girer: hava kararır, LED'ler yanar, LDR aydınlık sanıp LED'leri söndürür, sonra yeniden karanlık görür. Bunu önlemek için LDR'yi LED'lerden uzağa, seranın dışına yerleştir ve kodda tek eşik yerine histerezis kullan. Kapasitif toprak sensörünün üst kısmındaki elektronik de su geçirmez değildir; sensörü üzerindeki çizginin üstüne kadar gömme, kartın kenarlarını sıcak silikon ya da şeffaf ojeyle kapla.

Eylemciler: röle mi, MOSFET mi?

Arduino'nun bir pini en fazla yaklaşık 20 mA verebilir; fan, ısıtıcı, pompa ve LED şerit ise yüzlerce miliamper, hatta birkaç amper çeker. Bu yüzden her yük ya bir röle ya da bir MOSFET üzerinden sürülür. Röle mekanik bir anahtardır: yükü tamamen ayrı bir devrede, AC ya da DC fark etmeden açıp kapatır; ama yalnızca aç-kapa yapabilir, her geçişte tık sesi çıkarır ve kontaklarının ömrü sınırlıdır. MOSFET ise sessiz bir elektronik anahtardır; yalnızca DC yüklerde çalışır ama saniyede yüzlerce kez açılıp kapanabildiği için PWM ile parlaklık ve hız ayarı yapabilir. Bu projede ısıtıcı, fan ve pompa için 4 kanallı bir röle modülü, LED şeridin parlaklığı için bir MOSFET kullanıyoruz.

YükTipik değerSürücüNeden?
12 V PTC ısıtıcı10–30 W, yaklaşık 1–2,5 ARöle (IN2)Yüksek akım, yalnızca aç-kapa gerekir
12 V 80 mm fan0,1–0,2 ARöle (IN1) ya da MOSFETRöle basittir; MOSFET ile PWM hız ayarı da yapılabilir
3–6 V mini dalgıç pompa0,1–0,25 A, kalkışta daha fazlaRöle (IN3) ya da MOSFET ve diyotKısa darbelerle çalışır; motor paraziti yalıtılmalıdır
12 V LED şerit (5050, 60 LED/m)Metre başına yaklaşık 1,2 ALojik seviye MOSFETPWM ile parlaklık ayarı ve sessiz çalışma
Mini dalgıç su pompası
3–6 V mini dalgıç pompa: su deposuna batırılır, yaklaşık 100–200 mA çeker ve hortumla saksıya su basar; asla susuz çalıştırılmamalıdır.

Mini dalgıç pompa, hortum yüksekliğine göre dakikada yaklaşık 1–1,5 litre su basar; yani 3 saniyelik bir darbe saksıya 50–75 mL su verir. Bu yüzden pompayı "toprak ıslanana kadar" sürekli çalıştırmak yerine kısa darbelerle çalıştırıyoruz: 3 saniye sula, suyun toprağa yayılması için 60 saniye bekle, sonra yeniden ölç. Sensör suyun ulaşmasını beklemeden yeniden ölçülseydi toprak hâlâ kuru görünür ve pompa saksıyı taşırana kadar çalışırdı. Pompa susuz çalışırsa birkaç dakikada ısınıp bozulur; depodaki şamandıra, su bittiğinde pompayı kilitler. Motor her durduğunda bobininden ters yönde bir gerilim sıçraması gelir; pompanın uçlarına ters yönde bir diyot (1N5819 ya da 1N4007, bantlı ucu + tarafına) bağlamak hem röle kontağını hem de Arduino'yu bu parazitten korur. Pompa seçimi ve sürme yöntemleri mini su pompası yazısında.

Isıtıcı olarak 12 V'luk bir PTC ısıtıcı kullan. PTC (pozitif sıcaklık katsayılı) seramik elemanların direnci ısındıkça artar, bu yüzden yüzey sıcaklıkları kendiliğinden belli bir değerde sınırlanır; açıkta kızaran bir rezistans telinden çok daha güvenlidir. Plastik bir gövdede yüzey sıcaklığı 80 °C civarında sınırlanan düşük sıcaklıklı bir model seç. 24 W'lık bir ısıtıcı, P = V × I formülüne göre 12 V'ta 2 A çeker; soğukken ilk saniyelerde bu akım biraz daha yüksektir. Aydınlatma için kırmızı-mavi bitki yetiştirme LED şeridi ya da soğuk beyaz bir LED şerit kullanabilirsin; bitkiler fotosentezde en çok kırmızı (yaklaşık 660 nm) ve mavi (yaklaşık 450 nm) ışığı kullanır. Şeridi IRLZ44N gibi lojik seviye bir MOSFET ile sür: kapı (gate) 220 Ω'luk dirençle D9'a, ayrıca 100 kΩ'luk dirençle GND'ye bağlanır; şeridin + ucu 12 V'a, − ucu MOSFET'in drain'ine, source ise GND'ye gider. IRF520 gibi standart MOSFET modülleri 5 V'luk kapı geriliminde tam açılmaz ve amperlik yüklerde ısınır; ayrıntılar Arduino ile MOSFET kullanımı yazısında. Akım ve gücü hesaplamak için Ohm Kanunu aracını kullanabilirsin.

Isıtıcı, seradaki tek gerçek yangın riskidir. Plastik duvarlara değmeyecek şekilde metal bir tabana monte et, 12 V hattına ısıtıcıyla seri ve monte edildiği levhaya temas eden bir termal sigorta ekle ve sistemi gözetimsiz bırakmadan önce saatlerce test et. Sigorta, ısıtıcının sınır sıcaklığının biraz üstünde açmalıdır (80 °C'lik bir PTC için örneğin 92 °C); daha düşük bir değer normal çalışmada boşuna atar. Fide ısıtma matları ve büyük ısıtıcılar çoğunlukla 220 V ile çalışır ve şebeke gerilimi öldürücüdür. Maket serada 220 V kullanma, 12 V'luk PTC ısıtıcı yeterlidir. Şebekeye bağlı bir cihaz gerçekten gerekiyorsa bağlantıyı bir elektrikçi ya da işinin ehli bir yetişkin yapmalı, röle kartı da kapalı ve yalıtılmış bir kutuda durmalıdır. Güvenli bağlantı kuralları Röle modülü nedir? yazısında.

Güç planı: 12 V ve 5 V hatları

Akıllı seralarda en sık yaşanan sorunlar ("pompa çalışınca Arduino resetleniyor", "LCD'de garip karakterler çıkıyor") güçten gelir. En temiz çözüm, tek bir 12 V 5 A adaptörden iki hat çıkarmaktır. 12 V hattı ısıtıcıyı, fanları ve LED şeridi doğrudan besler, ayrıca Arduino Uno'nun DC jakına gider. Aynı 12 V, 5 V'a ayarlanmış bir LM2596 voltaj düşürücüye de girer; röle bobinleri, pompa ve LCD bu 5 V hattından beslenir. Röle modülünde JD-VCC jumper'ını çıkarırsan bobin akımı tamamen LM2596'dan gelir, Arduino tarafı yalnızca optokuplörlerin LED'lerini yakar. Sensörleri (DHT22, toprak nem sensörü ve LDR bölücüsü) ise Arduino'nun kendi 5V pininden besle: analogRead() ölçümü kartın kendi 5 V'una göre yaptığı için analog sensörlerin aynı gerilimden beslenmesi okumaları kararlı tutar. Adaptörün, LM2596'nın ve Arduino'nun GND'lerini mutlaka birleştir.

YükHatYaklaşık akım
PTC ısıtıcı (24 W)12 V2 A (soğukken ilk anda daha fazla)
LED şerit (1 m)12 V1–1,2 A
İki adet 80 mm fan12 V0,2–0,4 A
Arduino Uno ve sensörler (DC jaktan)12 VYaklaşık 0,06–0,08 A
LM2596 girişi (5 V tarafı 1 A çekerken)12 VYaklaşık 0,5 A
Röle modülü (üç röle çekiliyken)5 V0,2–0,25 A
Mini dalgıç pompa5 V0,1–0,25 A (kalkışta daha fazla)
I2C LCD (arka ışık açık)5 V20–30 mA

Her şey aynı anda çalışsa bile toplam akım 4–4,5 A civarındadır; 12 V 5 A (60 W) bir adaptör yeterli pay bırakır. Uygulamada ısıtıcı ile sıcaklık fanı hiçbir zaman aynı anda çalışmaz, çünkü eşikleri arasında geniş bir boşluk vardır. LM2596'yı devreye bağlamadan önce çıkışını multimetreyle ölçüp üzerindeki trimpotla 5,0 V'a ayarla; kutudan çıktığı ayarda girişteki 12 V'u neredeyse aynen geçirebilir. Arduino'yu kod yüklerken USB'den, sahada DC jakından besleyebilirsin; ikisinin aynı anda bağlı olması Uno için sorun değildir. Ayrıntılar Arduino güç besleme rehberinde.

Bağlantı ve pin tablosu

Aşağıdaki tablo, bu rehberdeki üç kodun kullandığı pinleri gösterir. Uno'da LED şeridi süren MOSFET'i PWM destekli D9'a bağladık; Uno'da PWM yalnızca D3, D5, D6, D9, D10 ve D11'de vardır. Şamandıra ve röleler için PWM gerekmez. LCD yalnızca I2C hattını (A4 ve A5) kullandığı için çok az pin harcar; Uno'da ikinci bir toprak sensörü ya da buton eklemek için A2, A3 ve birkaç dijital pin boş kalır. ESP32'de analog sensörleri Wi-Fi açıkken de çalışan ADC1 pinlerine (GPIO 34 ve 35) bağladık. Kartının pin yerleşimini Pinout aracında görebilirsin.

BağlantıArduino UnoESP32Raspberry Pi Pico
DHT22 DATAD2GPIO 4GP15
Şamandıra (diğer ucu GND)D3GPIO 13GP14
Röle IN3: pompaD4GPIO 25GP18
Röle IN1: fanD7GPIO 26GP16
Röle IN2: ısıtıcıD8GPIO 27GP17
MOSFET kapısı (220 Ω üzerinden): LEDD9GPIO 18GP19
Toprak nem sensörü AOUTA0GPIO 34GP26
LDR bölücüsünün orta noktasıA1GPIO 35 (bölücü 3V3'ten)GP27 (bölücü 3V3'ten)
I2C LCD SDA / SCLA4 / A5GPIO 21 / 22GP4 / GP5
Sensör beslemesi5V3V33V3
ESP32 ve Pico'nun pinleri 3,3 V ile çalışır ve 5 V'a dayanıklı değildir. Bu kartlarda DHT22'yi, toprak nem sensörünü ve LDR bölücüsünü 3V3 pininden besle; böylece analog pine 3,3 V'tan yüksek gerilim gelmez. Aktif LOW bir 5 V röle modülü 3,3 V'luk HIGH sinyaliyle bazen tam bırakmaz; röle hep çekili kalıyorsa JD-VCC'li bir modülde VCC'yi 3,3 V'tan, JD-VCC'yi 5 V'tan besle ya da 3,3 V tetiklemeli bir modül al. LED şerit için de 3,3 V'luk kapı geriliminde tam açılan bir MOSFET (örneğin IRLB8721) seç.

Eşik ve histerezis: röleler neden tıkırdar?

Fanı "sıcaklık 30 °C'nin üstündeyse çalıştır, değilse durdur" diye tek bir eşikle kontrol ettiğini düşün. Sıcaklık 29,9 ile 30,1 °C arasında gidip geldikçe (sensör gürültüsü yüzünden bu çok sık olur) röle her ölçümde açılıp kapanır. Hem röle kontakları hem fanın motoru yıpranır; ısıtıcıda ise kablolar ve adaptör her açılışta boşuna zorlanır. Çözüm histerezistir: açma ve kapama için iki ayrı eşik kullanırsın. Fan 30 °C'de çalışır ama ancak sıcaklık 27 °C'ye düşünce durur. Aradaki 3 derecelik ölü bölgede sistem son durumunu korur. Kombilerin oda termostatları ve buzdolapları da aynı mantıkla çalışır.

KontrolAçılırKapanırÖlü bölge
Fan (sıcaklık)≥ 30 °C≤ 27 °C3 °C
Fan (nem)≥ %85≤ %75%10
Isıtıcı≤ 16 °C≥ 19 °C3 °C
SulamaToprak ≤ %35Toprak ≥ %50%15
LED aydınlatmaIşık ≤ %25Işık ≥ %35 ya da 4 saat dolunca%10

Ölü bölgenin genişliği bir dengedir: çok dar olursa röle yine sık çalışır, çok geniş olursa sıcaklık hedeften fazla uzaklaşır. Sıcaklıkta 2–3 °C, nemde %8–10, toprak neminde %10–15 iyi bir başlangıçtır. Isıtıcının kapandığı 19 °C ile fanın çalıştığı 30 °C arasında da geniş bir boşluk bıraktık; böylece ısıtıcı ile sıcaklık fanı hiçbir zaman birbirine karşı çalışmaz. Kodda histerezis, her kontrol için tekrar tekrar yazılmasın diye küçük bir hysteresis() fonksiyonunda toplanır: açma eşiği kapama eşiğinden büyükse "yükselince aç" (fan), küçükse "düşünce aç" (ısıtıcı, sulama, LED) anlamına gelir. Sensör verisindeki sıçramaları ayrıca yumuşatmak istersen sensör verisi filtreleme yazısına göz at.

Kod yapısı: ölç, karar ver, uygula, göster

Akıllı seranın kodundaki en önemli kural, hiçbir işin diğerini beklememesidir. Pompadan sonra delay(60000) ile bir dakika bekleseydin o süre boyunca ne fan çalışır ne de ekran güncellenirdi. Bu yüzden kod, zamanı millis() ile ölçen ve her biri tek bir işten sorumlu küçük fonksiyonlardan oluşur; loop() bunları saniyede binlerce kez sırayla çağırır, her fonksiyon da yalnızca zamanı geldiyse bir şey yapar. Sulama, üç durumlu küçük bir durum makinesidir: bekle (IDLE), sula (PUMPING) ve suyun yayılmasını bekle (SOAKING). Bütün ayarlar kodun en üstünde sabit olarak durur; eşikleri değiştirmek için kodun içinde dolaşman gerekmez. Bu yaklaşımın mantığını millis() ve delay() ile Arduino'da durum makinesi yazılarında bulabilirsin. Kodda ayrıca şu güvenlik önlemleri var:

  • Güvenli açılış: Röle pinlerine pinMode() çağrılmadan önce "kapalı" değeri yazılır; Arduino açılırken röleler bir anlığına bile çekmez.
  • Sensör arızası: DHT22 üst üste üç kez okunamazsa kod güvenli duruma geçer: ısıtıcıyı kapatır, fanı çalıştırır ve LCD'de "Sensor hatasi" yazar. Sıcaklığı bilmeyen bir sistemin ısıtıcıyı açık bırakması kabul edilemez.
  • Depo koruması: Şamandıra depo boş dediğinde pompa hiç başlamaz, çalışıyorsa hemen durur.
  • Taşma koruması: Bir sulama döngüsünde altı darbeye rağmen toprak nemi %50'ye çıkmıyorsa sensör topraktan çıkmış ya da hortum kopmuş olabilir; kod sulamayı durdurur ve "Sulama hatasi" gösterir. Toprak yeniden ıslandığında uyarı kendiliğinden kalkar.
  • Veri kaydı: Kod her 10 saniyede bir ölçümleri Seri Monitör'e virgülle ayrılmış (CSV) bir satır olarak yazar; bu satırları kopyalayıp Excel'de grafik çizebilirsin.

Adım adım kurulum ve test

  1. Gövdeyi hazırla: fan, hava girişi, hortum ve kablo deliklerini aç; elektronik kutusunu seranın dışına yerleştir.
  2. Güç hattını kur: 12 V adaptörü bir klemense bağla, LM2596'yı multimetreyle 5,0 V'a ayarla ve bütün GND'leri birleştir.
  3. I2C LCD'yi bağla ve ekrana bir yazı yazdır. Ekran bir şey göstermiyorsa I2C LCD yazısındaki tarayıcı kodunu ve kontrast trimpotunu dene.
  4. Sensörleri tek tek ekle ve Seri Monitör'de dene: DHT22'nin değerlerini, toprak sensörünün havadaki ve sudaki ham değerini, LDR'nin karanlıktaki ve güneş altındaki değerini not al.
  5. Röleleri önce yük bağlamadan, LED'lerini ve tık seslerini izleyerek dene. Sonra fanı, pompayı (depo dolu olsun) ve en son ısıtıcıyı bağla.
  6. LED şeridi MOSFET üzerinden bağla; analogWrite() değerini değiştirerek parlaklığın değiştiğini gör.
  7. Ana kodu yükle, notlarındaki kalibrasyon değerlerini sabitlere yaz ve sistemi birkaç saat gözetim altında çalıştır: yanlış sulama, sürekli tıklayan bir röle ya da aşırı ısınan bir parça var mı?
Her şeyi bir anda bağlayıp tek seferde çalıştırmaya çalışma. Altı modül birlikte çalışmadığında hatanın nerede olduğunu bulmak saatler sürer; tek tek test edilmiş modüller ise birleştirildiğinde çoğu zaman ilk denemede çalışır.

Arduino Uno ile tam kod

Kodu derlemek için Kütüphane Yöneticisi'nden Adafruit'in DHT sensor library kütüphanesini (bağımlılığı Adafruit Unified Sensor ile birlikte) ve Frank de Brabander'in LiquidCrystal I2C kütüphanesini kur; Wire, Arduino IDE ile birlikte gelir. LCD'nin adresi çoğunlukla 0x27, bazı modüllerde 0x3F'tir. Yüklemeden önce kendi ölçtüğün kalibrasyon değerlerini SOIL_DRY_RAW, SOIL_WET_RAW, LDR_DARK_RAW ve LDR_BRIGHT_RAW sabitlerine yaz. Şamandıran suyla kapanmak yerine açılıyorsa TANK_OK değerini HIGH yap; röle modülün aktif HIGH ise RELAY_ON ve RELAY_OFF değerlerini yer değiştir.

C++ (Arduino IDE)
1#include <Wire.h>
2#include <LiquidCrystal_I2C.h>
3#include <DHT.h>
4
5// Pinler / Pins
6const byte DHT_PIN = 2, FLOAT_PIN = 3, PUMP_RELAY = 4, FAN_RELAY = 7, HEATER_RELAY = 8;
7const byte LED_PIN = 9;                          // MOSFET gate (PWM)
8const byte SOIL_PIN = A0, LDR_PIN = A1;
9
10// Kalibrasyon: kendi ölçümlerini yaz / Calibration: write your own readings
11const int SOIL_DRY_RAW = 520, SOIL_WET_RAW = 260;   // havada ve suda / in air and in water
12const int LDR_DARK_RAW = 60, LDR_BRIGHT_RAW = 900;  // karanlık ve güneş / dark and sunlight
13
14// Eşikler (açma, kapama) / Thresholds (on, off)
15const float FAN_ON_C = 30, FAN_OFF_C = 27;       // sıcaklıkta fan / fan on heat
16const float HUM_ON = 85, HUM_OFF = 75;           // nemde fan / fan on humidity
17const float HEAT_ON_C = 16, HEAT_OFF_C = 19;     // ısıtıcı / heater
18const float SOIL_DRY = 35, SOIL_OK = 50;         // sulama başla, dur / start, stop watering
19const float DARK_ON = 25, DARK_OFF = 35;         // ışık % / light %
20
21// Zamanlar / Timing
22const unsigned long READ_MS = 2500;              // DHT22: en az 2 sn / at least 2 s
23const unsigned long PUMP_MS = 3000;              // tek sulama darbesi / one watering pulse
24const unsigned long SOAK_MS = 60000;             // suyun yayılması / let the water soak in
25const byte MAX_PULSES = 6;                       // fazlası arıza / more means a fault
26const unsigned long EXTRA_LIGHT_MS = 4UL * 3600000UL;  // günü 4 saat uzat / extend the day by 4 h
27const byte LED_LEVEL = 200;                      // LED parlaklığı 0-255 / LED brightness 0-255
28const byte RELAY_ON = LOW, RELAY_OFF = HIGH;     // aktif LOW röle / active-LOW relay
29const byte TANK_OK = LOW;                        // şamandıra suyla kapanır / float closes with water
30
31DHT dht(DHT_PIN, DHT22);
32LiquidCrystal_I2C lcd(0x27, 16, 2);
33
34float tempC = NAN, hum = NAN, soil = 0, light = 0;
35byte dhtErrors = 0, pulses = 0, page = 0;
36bool fanByTemp = false, fanByHum = false, fanOn = false, heaterOn = false;
37bool needWater = false, pumpFault = false, isDark = false, ledOn = false, tankOk = true;
38unsigned long lastRead = 0, lastLcd = 0, lastLog = 0, pumpAt = 0, darkSince = 0;
39
40enum PumpState { IDLE, PUMPING, SOAKING };
41PumpState pumpState = IDLE;
42
43// onAt > offAt: yükselince aç (fan) / turn on when rising (fan)
44// onAt < offAt: düşünce aç (ısıtıcı) / turn on when falling (heater)
45bool hysteresis(bool state, float value, float onAt, float offAt) {
46  if (onAt > offAt) {
47    if (value >= onAt) return true;
48    if (value <= offAt) return false;
49  } else {
50    if (value <= onAt) return true;
51    if (value >= offAt) return false;
52  }
53  return state;                                  // ölü bölgede durumu koru / keep state in the dead band
54}
55
56void setRelay(byte pin, bool on) {
57  digitalWrite(pin, on ? RELAY_ON : RELAY_OFF);
58}
59
60float readPercent(byte pin, int raw0, int raw100) {
61  long sum = 0;
62  for (byte i = 0; i < 10; i++) sum += analogRead(pin);   // 10 ölçüm ortalaması / average of 10
63  long pct = map(sum / 10, raw0, raw100, 0, 100);
64  return constrain(pct, 0, 100);
65}
66
67void setup() {
68  Serial.begin(9600);
69  setRelay(PUMP_RELAY, false);   pinMode(PUMP_RELAY, OUTPUT);    // açılışta kapalı / off at boot
70  setRelay(FAN_RELAY, false);    pinMode(FAN_RELAY, OUTPUT);
71  setRelay(HEATER_RELAY, false); pinMode(HEATER_RELAY, OUTPUT);
72  pinMode(LED_PIN, OUTPUT);
73  pinMode(FLOAT_PIN, INPUT_PULLUP);
74  dht.begin();
75  lcd.init();
76  lcd.backlight();
77  lcd.print(F("BlueGrays Sera"));
78  Serial.println(F("sn,sicaklik,nem,toprak,isik,fan,isitici,pompa,led"));  // CSV başlığı / CSV header
79  delay(2000);                                   // DHT22 açılış süresi / DHT22 start-up time
80  readSensors();
81  lastRead = millis();
82}
83
84void loop() {
85  unsigned long now = millis();
86  if (now - lastRead >= READ_MS) {
87    lastRead = now;
88    readSensors();
89  }
90  controlClimate();
91  controlLight(now);
92  controlPump(now);
93  updateLcd(now);
94  logCsv(now);
95}
96
97// 1) Ölç / Measure
98void readSensors() {
99  float t = dht.readTemperature();
100  float h = dht.readHumidity();
101  if (isnan(t) || isnan(h)) {
102    if (dhtErrors < 255) dhtErrors++;            // okuma hatası / read error
103  } else {
104    tempC = t;
105    hum = h;
106    dhtErrors = 0;
107  }
108  soil = readPercent(SOIL_PIN, SOIL_DRY_RAW, SOIL_WET_RAW);
109  light = readPercent(LDR_PIN, LDR_DARK_RAW, LDR_BRIGHT_RAW);
110  tankOk = digitalRead(FLOAT_PIN) == TANK_OK;
111}
112
113// 2) Fan ve ısıtıcı / Fan and heater
114void controlClimate() {
115  if (dhtErrors >= 3) {                          // sensör yok: güvenli durum / no sensor: safe state
116    heaterOn = false;
117    fanByTemp = true;
118  } else {
119    fanByTemp = hysteresis(fanByTemp, tempC, FAN_ON_C, FAN_OFF_C);
120    fanByHum = hysteresis(fanByHum, hum, HUM_ON, HUM_OFF);
121    heaterOn = hysteresis(heaterOn, tempC, HEAT_ON_C, HEAT_OFF_C);
122  }
123  fanOn = fanByTemp || fanByHum;
124  setRelay(FAN_RELAY, fanOn);
125  setRelay(HEATER_RELAY, heaterOn);
126}
127
128// 3) LED aydınlatma / LED grow light
129void controlLight(unsigned long now) {
130  bool wasDark = isDark;
131  isDark = hysteresis(isDark, light, DARK_ON, DARK_OFF);
132  if (isDark && !wasDark) darkSince = now;      // akşam oldu / dusk detected
133  ledOn = isDark && (now - darkSince < EXTRA_LIGHT_MS);
134  analogWrite(LED_PIN, ledOn ? LED_LEVEL : 0);
135}
136
137// 4) Sulama: darbe + bekleme / Watering: pulse + soak
138void controlPump(unsigned long now) {
139  needWater = hysteresis(needWater, soil, SOIL_DRY, SOIL_OK);
140  if (!needWater) {
141    pulses = 0;
142    pumpFault = false;                           // toprak ıslandı / soil is wet again
143  }
144  switch (pumpState) {
145    case IDLE:
146      if (needWater && tankOk && !pumpFault) {
147        if (pulses >= MAX_PULSES) {
148          pumpFault = true;                      // nem yükselmiyor / moisture is not rising
149        } else {
150          pumpState = PUMPING;
151          pumpAt = now;
152          pulses++;
153        }
154      }
155      break;
156    case PUMPING:
157      if (now - pumpAt >= PUMP_MS || !tankOk) {
158        pumpState = SOAKING;
159        pumpAt = now;
160      }
161      break;
162    case SOAKING:
163      if (now - pumpAt >= SOAK_MS) pumpState = IDLE;
164      break;
165  }
166  setRelay(PUMP_RELAY, pumpState == PUMPING);
167}
168
169// 5) LCD: üç sayfa / three pages
170void updateLcd(unsigned long now) {
171  if (now - lastLcd < 3000) return;
172  lastLcd = now;
173  page = (page + 1) % 3;
174  lcd.clear();
175  if (page == 0) {
176    lcd.print(F("Sicaklik: "));
177    if (isnan(tempC)) lcd.print(F("--")); else lcd.print(tempC, 1);
178    lcd.print('C');
179    lcd.setCursor(0, 1);
180    lcd.print(F("Hava nemi: %"));
181    if (isnan(hum)) lcd.print(F("--")); else lcd.print(hum, 0);
182  } else if (page == 1) {
183    lcd.print(F("Toprak: %"));
184    lcd.print(soil, 0);
185    lcd.setCursor(0, 1);
186    lcd.print(F("Isik: %"));
187    lcd.print(light, 0);
188  } else {
189    lcd.print(F("F:"));  lcd.print(fanOn);
190    lcd.print(F(" I:")); lcd.print(heaterOn);
191    lcd.print(F(" P:")); lcd.print(pumpState == PUMPING);
192    lcd.print(F(" L:")); lcd.print(ledOn);
193    lcd.setCursor(0, 1);
194    if (dhtErrors >= 3) lcd.print(F("Sensor hatasi"));
195    else if (!tankOk) lcd.print(F("Depo bos!"));
196    else if (pumpFault) lcd.print(F("Sulama hatasi"));
197    else lcd.print(F("Sistem normal"));
198  }
199}
200
201// 6) Seri port CSV kaydı / Serial CSV log
202void logCsv(unsigned long now) {
203  if (now - lastLog < 10000) return;
204  lastLog = now;
205  Serial.print(now / 1000);  Serial.print(',');
206  Serial.print(tempC, 1);    Serial.print(',');
207  Serial.print(hum, 0);      Serial.print(',');
208  Serial.print(soil, 0);     Serial.print(',');
209  Serial.print(light, 0);    Serial.print(',');
210  Serial.print(fanOn);       Serial.print(',');
211  Serial.print(heaterOn);    Serial.print(',');
212  Serial.print(pumpState == PUMPING); Serial.print(',');
213  Serial.println(ledOn);
214}
FonksiyonGöreviNe sıklıkla?
readSensors()DHT22, toprak nemi, LDR ve şamandırayı okur; analog değerleri 10 ölçümün ortalamasıyla %0–100'e çevirir2,5 saniyede bir
controlClimate()Fanı sıcaklık ya da nem histerezisiyle, ısıtıcıyı sıcaklık histerezisiyle sürer; sensör yoksa güvenli duruma geçerHer döngüde
controlLight()Hava kararınca LED'leri PWM ile yakar, en fazla 4 saat sonra söndürürHer döngüde
controlPump()Sulama durum makinesi: 3 sn sula, 60 sn bekle, yeniden ölç; depo ve taşma korumalıHer döngüde
updateLcd()Üç sayfa arasında geçiş yapar: hava ölçümleri, toprak nemi ve ışık, cihaz durumları3 saniyede bir
logCsv()Ölçümleri ve durumları CSV satırı olarak Seri Monitör'e yazar10 saniyede bir

LCD'nin ilk sayfasında sıcaklık ve hava nemi, ikinci sayfasında toprak nemi ve ışık yüzdesi, üçüncü sayfasında ise cihazların durumu yer alır: "F:1 I:0 P:0 L:1" satırı fanın çalıştığını, ısıtıcı ile pompanın kapalı olduğunu ve LED'lerin yandığını söyler. Alt satır ise "Sistem normal", "Depo bos!", "Sulama hatasi" ya da "Sensor hatasi" mesajlarından birini gösterir. Bu kod derlendiğinde Uno'nun program belleğinin yaklaşık %31'ini, RAM'in ise %25'ini kullanır; yani ikinci bir toprak sensörü, bir buzzer ya da bir RTC saat modülü eklemek için bol yer vardır. Uno'nun gerçek bir saati olmadığından LED kuralı "akşam olunca en fazla 4 saat" diye çalışır; bu, kışın kısa günleri uzatmak için iyi bir yöntemdir. LED'leri her gün belirli saatlerde yakmak istersen bir RTC modülü ekle ya da aşağıdaki ESP32 sürümüne geç.

ESP32 ile telefondan izleme ve sulama

ESP32 geliştirme kartı
ESP32: Wi-Fi'si sayesinde serayı telefondan izlemeyi sağlar ve internetten aldığı saatle LED'leri gerçek saate göre yönetir.

Uno'nun Wi-Fi'si yoktur. Seranın durumunu telefondan görmek ve uzaktan sulamak istiyorsan beyni bir ESP32 ile değiştir. Aşağıdaki kod aynı kontrol mantığını ESP32'ye taşır ve küçük bir web sunucusu başlatır. Telefonun aynı Wi-Fi ağındayken Seri Monitör'de görünen IP adresini tarayıcıda açtığında sıcaklığı, nemi, toprak nemini, ışığı, depo durumunu ve her cihazın açık mı kapalı mı olduğunu görürsün; sayfa 10 saniyede bir kendini yeniler. Şimdi sula düğmesi, depoda su varsa pompayı bir kez 3 saniye çalıştırır. ESP32 açılışta internetten saati (NTP) alır; böylece LED'ler yalnızca 06:00 ile 20:00 arasında ve ortam karanlıksa yanar, gece ise bitkiler dinlenir.

C++ (Arduino IDE)
1#include <WiFi.h>
2#include <WebServer.h>
3#include <DHT.h>
4#include <time.h>
5
6const char* ssid = "AgAdi";                      // Wi-Fi adın / your Wi-Fi name
7const char* password = "Sifre123";               // Wi-Fi şifren / your Wi-Fi password
8
9// Pinler / Pins
10const int DHT_PIN = 4, FLOAT_PIN = 13, PUMP_RELAY = 25, FAN_RELAY = 26, HEATER_RELAY = 27;
11const int LED_PIN = 18;                          // MOSFET gate (PWM)
12const int SOIL_PIN = 34, LDR_PIN = 35;           // ADC1: Wi-Fi açıkken çalışır / works with Wi-Fi on
13
14// Kalibrasyon (0-4095): kendin ölç / Calibration (0-4095): measure your own
15const int SOIL_DRY_RAW = 2800, SOIL_WET_RAW = 1200;
16const int LDR_DARK_RAW = 200, LDR_BRIGHT_RAW = 3800;
17
18// Eşikler (açma, kapama) / Thresholds (on, off)
19const float FAN_ON_C = 30, FAN_OFF_C = 27, HUM_ON = 85, HUM_OFF = 75;
20const float HEAT_ON_C = 16, HEAT_OFF_C = 19, SOIL_DRY = 35, SOIL_OK = 50;
21const float DARK_ON = 25, DARK_OFF = 35;
22const int LIGHT_FROM = 6, LIGHT_TO = 20;         // LED yalnız 06:00-20:00 / LEDs only 06:00-20:00
23
24const unsigned long READ_MS = 2500, PUMP_MS = 3000, SOAK_MS = 60000;
25const unsigned long EXTRA_LIGHT_MS = 4UL * 3600000UL;  // saat yoksa yedek kural / fallback without a clock
26const int MAX_PULSES = 6, LED_LEVEL = 200;
27const int RELAY_ON = LOW, RELAY_OFF = HIGH;      // aktif LOW röle / active-LOW relay
28const int TANK_OK = LOW;                         // şamandıra suyla kapanır / float closes with water
29
30DHT dht(DHT_PIN, DHT22);
31WebServer server(80);
32
33float tempC = NAN, hum = NAN, soil = 0, light = 0;
34int dhtErrors = 0, pulses = 0;
35bool fanByTemp = false, fanByHum = false, fanOn = false, heaterOn = false;
36bool needWater = false, pumpFault = false, isDark = false, ledOn = false, tankOk = true;
37unsigned long lastRead = 0, pumpAt = 0, darkSince = 0;
38
39enum PumpState { IDLE, PUMPING, SOAKING };
40PumpState pumpState = IDLE;
41
42bool hysteresis(bool state, float value, float onAt, float offAt) {
43  if (onAt > offAt) {                            // yükselince aç / turn on when rising
44    if (value >= onAt) return true;
45    if (value <= offAt) return false;
46  } else {                                       // düşünce aç / turn on when falling
47    if (value <= onAt) return true;
48    if (value >= offAt) return false;
49  }
50  return state;
51}
52
53void setRelay(int pin, bool on) {
54  digitalWrite(pin, on ? RELAY_ON : RELAY_OFF);
55}
56
57float readPercent(int pin, int raw0, int raw100) {
58  long sum = 0;
59  for (int i = 0; i < 16; i++) sum += analogRead(pin);    // 16 ölçüm ortalaması / average of 16
60  long pct = map(sum / 16, raw0, raw100, 0, 100);
61  return constrain(pct, 0, 100);
62}
63
64int hourNow() {
65  struct tm t;
66  if (!getLocalTime(&t, 0)) return -1;           // saat henüz yok / time not set yet
67  return t.tm_hour;
68}
69
70void readSensors() {
71  float t = dht.readTemperature();
72  float h = dht.readHumidity();
73  if (isnan(t) || isnan(h)) {
74    dhtErrors++;
75  } else {
76    tempC = t;
77    hum = h;
78    dhtErrors = 0;
79  }
80  soil = readPercent(SOIL_PIN, SOIL_DRY_RAW, SOIL_WET_RAW);
81  light = readPercent(LDR_PIN, LDR_DARK_RAW, LDR_BRIGHT_RAW);
82  tankOk = digitalRead(FLOAT_PIN) == TANK_OK;
83}
84
85void controlClimate() {
86  if (dhtErrors >= 3) {                          // sensör yok: güvenli durum / no sensor: safe state
87    heaterOn = false;
88    fanByTemp = true;
89  } else {
90    fanByTemp = hysteresis(fanByTemp, tempC, FAN_ON_C, FAN_OFF_C);
91    fanByHum = hysteresis(fanByHum, hum, HUM_ON, HUM_OFF);
92    heaterOn = hysteresis(heaterOn, tempC, HEAT_ON_C, HEAT_OFF_C);
93  }
94  fanOn = fanByTemp || fanByHum;
95  setRelay(FAN_RELAY, fanOn);
96  setRelay(HEATER_RELAY, heaterOn);
97}
98
99void controlLight(unsigned long now) {
100  bool wasDark = isDark;
101  isDark = hysteresis(isDark, light, DARK_ON, DARK_OFF);
102  if (isDark && !wasDark) darkSince = now;
103  int h = hourNow();
104  if (h >= 0) ledOn = isDark && h >= LIGHT_FROM && h < LIGHT_TO;   // saat kuralı / clock rule
105  else ledOn = isDark && (now - darkSince < EXTRA_LIGHT_MS);       // yedek kural / fallback rule
106  analogWrite(LED_PIN, ledOn ? LED_LEVEL : 0);
107}
108
109void controlPump(unsigned long now) {
110  needWater = hysteresis(needWater, soil, SOIL_DRY, SOIL_OK);
111  if (!needWater) {
112    pulses = 0;
113    pumpFault = false;
114  }
115  if (pumpState == IDLE && needWater && tankOk && !pumpFault) {
116    if (pulses >= MAX_PULSES) {
117      pumpFault = true;                          // nem yükselmiyor / moisture is not rising
118    } else {
119      pumpState = PUMPING;
120      pumpAt = now;
121      pulses++;
122    }
123  } else if (pumpState == PUMPING && (now - pumpAt >= PUMP_MS || !tankOk)) {
124    pumpState = SOAKING;
125    pumpAt = now;
126  } else if (pumpState == SOAKING && now - pumpAt >= SOAK_MS) {
127    pumpState = IDLE;
128  }
129  setRelay(PUMP_RELAY, pumpState == PUMPING);
130}
131
132String row(const char* name, const String& value) {
133  return String("<tr><td>") + name + "</td><td><b>" + value + "</b></td></tr>";
134}
135
136String onOff(bool on) {
137  return on ? "ON" : "OFF";
138}
139
140void handleRoot() {
141  String html = "<!DOCTYPE html><html><head><meta charset='utf-8'>"
142                "<meta name='viewport' content='width=device-width,initial-scale=1'>"
143                "<meta http-equiv='refresh' content='10'><title>BlueGrays Sera</title>"
144                "<style>body{font-family:sans-serif;max-width:420px;margin:auto;padding:12px}"
145                "td{padding:8px;border-bottom:1px solid #ddd}"
146                "a{display:block;margin-top:16px;padding:16px;border-radius:10px;background:#2e7d32;"
147                "color:#fff;text-align:center;text-decoration:none;font-size:18px}</style>"
148                "</head><body><h2>BlueGrays Sera</h2><table>";
149  html += row("Sıcaklık / Temperature", String(tempC, 1) + " °C");
150  html += row("Hava nemi / Humidity", "%" + String(hum, 0));
151  html += row("Toprak nemi / Soil", "%" + String(soil, 0));
152  html += row("Işık / Light", "%" + String(light, 0));
153  html += row("Fan", onOff(fanOn));
154  html += row("Isıtıcı / Heater", onOff(heaterOn));
155  html += row("Pompa / Pump", onOff(pumpState == PUMPING));
156  html += row("LED", onOff(ledOn));
157  html += row("Depo / Tank", tankOk ? "OK" : "BOŞ / EMPTY");
158  if (pumpFault) html += row("Uyarı / Warning", "Sulama hatası / Watering fault");
159  html += "</table><a href='/water'>Şimdi sula / Water now</a></body></html>";
160  server.send(200, "text/html", html);
161}
162
163void handleWater() {                             // elle tek darbe / one manual pulse
164  if (pumpState == IDLE && tankOk) {
165    pumpState = PUMPING;
166    pumpAt = millis();
167  }
168  server.sendHeader("Location", "/");
169  server.send(303);
170}
171
172void setup() {
173  Serial.begin(115200);
174  setRelay(PUMP_RELAY, false);   pinMode(PUMP_RELAY, OUTPUT);
175  setRelay(FAN_RELAY, false);    pinMode(FAN_RELAY, OUTPUT);
176  setRelay(HEATER_RELAY, false); pinMode(HEATER_RELAY, OUTPUT);
177  pinMode(LED_PIN, OUTPUT);
178  pinMode(FLOAT_PIN, INPUT_PULLUP);
179  dht.begin();
180  WiFi.begin(ssid, password);
181  while (WiFi.status() != WL_CONNECTED) {
182    delay(500);
183    Serial.print('.');
184  }
185  Serial.println();
186  Serial.println(WiFi.localIP());                // bu adresi telefonda aç / open this address on your phone
187  configTime(3 * 3600, 0, "pool.ntp.org");       // Türkiye UTC+3; kendi saat dilimini yaz / set your own time zone
188  server.on("/", handleRoot);
189  server.on("/water", handleWater);
190  server.begin();
191  readSensors();
192  lastRead = millis();
193}
194
195void loop() {
196  server.handleClient();
197  unsigned long now = millis();
198  if (now - lastRead >= READ_MS) {
199    lastRead = now;
200    readSensors();
201  }
202  controlClimate();
203  controlLight(now);
204  controlPump(now);
205}

Uno koduna göre değişenler şunlar: ESP32'nin ADC'si 12 bittir ve 0–4095 arasında değer verir, bu yüzden kalibrasyonu yeniden yapmalısın; sensörleri 3V3'ten beslediğin için ham değerler de farklı olur. Saat dilimi configTime() satırında ayarlanır; Türkiye için 3 × 3600 saniye yazdık. İnternet yoksa ya da saat henüz alınmadıysa LED kuralı Uno'daki "en fazla 4 saat" kuralına geri döner. Sayfa şifresizdir, yani ev ağındaki herkes pompayı çalıştırabilir; WebServer kütüphanesinin authenticate() fonksiyonuyla basit bir parola eklemek iyi bir alışkanlıktır. LCD'yi ESP32'de de kullanmak istersen Uno kodundaki updateLcd() fonksiyonunu olduğu gibi taşıyabilirsin; SDA GPIO 21, SCL GPIO 22'dir.

Okulda Wi-Fi yoksa WiFi.begin() satırı ve ardından gelen bekleme döngüsü yerine WiFi.softAP("BlueGrays-Sera", "12345678") yazarak ESP32'nin kendi ağını kurabilirsin; telefon bu ağa bağlanıp 192.168.4.1 adresini açar. Bu durumda internet olmadığı için saat alınamaz ve LED'ler yedek kuralla çalışır.
YöntemEvin dışından erişimZorlukEn uygun durum
ESP32 web sunucusu (bu rehberdeki kod)Hayır, yalnızca aynı ağOrtaOkul sunumu, internetsiz gösteri
Blynk IoTEvetKolayHazır göstergeler, grafik ve bildirim
Telegram botuEvetOrta"Depo boş" ve "sıcaklık çok yüksek" uyarıları
Google E-TablolarEvetOrtaHaftalarca veri kaydı ve grafik
MQTT ve Home AssistantEvet, ayar gerekirİleriGerçek ev ve bahçe otomasyonu

Okul sunumu için ESP32 web sunucusu en güvenli seçimdir: bir buluta bağımlı değildir ve salonda internet olmasa bile kendi ağıyla çalışır. Evin dışından da bakmak istersen hazır göstergeleri ve grafikleriyle Blynk IoT en kolay yoldur. Depo boşaldığında ya da sıcaklık tehlikeli seviyeye çıktığında telefona mesaj almak için ESP32 Telegram botu, TÜBİTAK raporun için haftalarca veri toplamak için ESP32 ile Google E-Tablolar, serayı gerçek bir ev otomasyonuna bağlamak için MQTT ve Home Assistant rehberlerine göz at.

Raspberry Pi Pico ile MicroPython sürümü

Aynı serayı Raspberry Pi Pico ile MicroPython'da da yönetebilirsin. Pico'nun MicroPython yazılımında DHT sürücüsü hazır gelir, ek dosya kopyalaman gerekmez. Analog girişler yalnızca GP26, GP27 ve GP28'dir ve read_u16() 0–65535 arası değer verir; kalibrasyon sayılarını buna göre ölç. Pico 3,3 V ile çalıştığı için sensörleri 3V3'ten, röle modülünü ise VBUS'tan (USB'nin 5 V'u) ya da LM2596 hattından besle. Aşağıdaki kod fan, ısıtıcı, LED ve sulama kurallarının tamamını içerir ve değerleri Thonny'nin kabuğuna yazar. Dosyayı Pico'ya main.py adıyla kaydedersen kart bilgisayara bağlı olmadan da çalışır. Wi-Fi'li Pico W kullanıyorsan değerleri telefondan izlemek için Pico W web sunucusu yazısındaki yöntemi ekleyebilirsin.

MicroPython
1from machine import Pin, ADC, PWM
2import dht
3import time
4
5sensor = dht.DHT22(Pin(15))              # GP15: DHT22 DATA
6soil_adc = ADC(26)                       # GP26: toprak nem AOUT / soil moisture AOUT
7ldr_adc = ADC(27)                        # GP27: LDR bölücü (3V3) / LDR divider (3V3)
8tank = Pin(14, Pin.IN, Pin.PULL_UP)      # şamandıra: suyla 0 / float switch: 0 with water
9fan = Pin(16, Pin.OUT, value=1)          # aktif LOW röleler kapalı başlar / active-LOW relays start off
10heater = Pin(17, Pin.OUT, value=1)
11pump = Pin(18, Pin.OUT, value=1)
12led = PWM(Pin(19))                       # MOSFET gate
13led.freq(1000)
14
15SOIL_DRY_RAW, SOIL_WET_RAW = 50000, 22000    # kendin ölç / measure your own
16LDR_DARK_RAW, LDR_BRIGHT_RAW = 2000, 60000
17EXTRA_LIGHT_MS = 4 * 3600 * 1000             # günü 4 saat uzat / extend the day by 4 h
18
19
20def percent(adc, raw0, raw100):
21    raw = sum(adc.read_u16() for _ in range(10)) // 10
22    pct = (raw - raw0) * 100 // (raw100 - raw0)
23    return max(0, min(100, pct))
24
25
26def hysteresis(state, value, on_at, off_at):
27    if on_at > off_at:                   # yükselince aç / turn on when rising
28        if value >= on_at:
29            return True
30        if value <= off_at:
31            return False
32    else:                                # düşünce aç / turn on when falling
33        if value <= on_at:
34            return True
35        if value >= off_at:
36            return False
37    return state                         # ölü bölge / dead band
38
39
40def relay(pin, on):
41    pin.value(0 if on else 1)
42
43
44t = h = None
45errors = pulses = 0
46fan_t = fan_h = heat_on = need_water = dark = led_on = False
47pump_state, pump_at, dark_since = "idle", 0, 0
48soil = light = 0
49tank_ok = True
50time.sleep(2)                            # DHT22 açılış süresi / DHT22 start-up time
51last_read = time.ticks_add(time.ticks_ms(), -2500)
52
53while True:
54    now = time.ticks_ms()
55    if time.ticks_diff(now, last_read) >= 2500:      # 2,5 sn'de bir ölç / measure every 2.5 s
56        last_read = now
57        try:
58            sensor.measure()
59            t, h = sensor.temperature(), sensor.humidity()
60            errors = 0
61        except OSError:
62            errors += 1                  # okuma hatası / read error
63        soil = percent(soil_adc, SOIL_DRY_RAW, SOIL_WET_RAW)
64        light = percent(ldr_adc, LDR_DARK_RAW, LDR_BRIGHT_RAW)
65        tank_ok = tank.value() == 0
66
67        if errors >= 3 or t is None:     # güvenli durum / safe state
68            heat_on, fan_t = False, True
69        else:
70            fan_t = hysteresis(fan_t, t, 30, 27)
71            fan_h = hysteresis(fan_h, h, 85, 75)
72            heat_on = hysteresis(heat_on, t, 16, 19)
73        relay(fan, fan_t or fan_h)
74        relay(heater, heat_on)
75
76        was_dark = dark
77        dark = hysteresis(dark, light, 25, 35)
78        if dark and not was_dark:
79            dark_since = now             # akşam oldu / dusk detected
80        led_on = dark and time.ticks_diff(now, dark_since) < EXTRA_LIGHT_MS
81        led.duty_u16(50000 if led_on else 0)
82
83        need_water = hysteresis(need_water, soil, 35, 50)
84        if not need_water:
85            pulses = 0
86        print("T", t, "N", h, "Toprak", soil, "Isik", light, "Pompa", pump_state,
87              "Depo OK" if tank_ok else "Depo BOS", "HATA" if pulses >= 6 else "")
88
89    # Sulama: 3 sn darbe, 60 sn bekleme / Watering: 3 s pulse, 60 s soak
90    if pump_state == "idle" and need_water and tank_ok and pulses < 6:
91        pump_state, pump_at = "pump", now
92        pulses += 1
93    elif pump_state == "pump" and (time.ticks_diff(now, pump_at) >= 3000 or not tank_ok):
94        pump_state, pump_at = "soak", now
95    elif pump_state == "soak" and time.ticks_diff(now, pump_at) >= 60000:
96        pump_state = "idle"
97    relay(pump, pump_state == "pump")
98    time.sleep_ms(100)

Okul ve TÜBİTAK sunumu için ipuçları

Akıllı sera çok sevilen bir konu olduğu için jüri onlarca benzer maket görür. Seni öne çıkaracak olan, sistemin çalıştığını göstermekten çok bir soruya ölçümle cevap vermendir. TÜBİTAK 4006 bilim fuarında amaç, yöntem ve beklenen sonuç net olmalıdır; 2204 araştırma projelerinde ise karşılaştırmalı bir deney ve veri beklenir. Bu sera için güzel bir araştırma sorusu şudur: "Toprak nemine göre yapılan sulama, her gün aynı saatte yapılan sulamaya göre ne kadar su tasarrufu sağlar ve bitkinin büyümesini nasıl etkiler?"

  • İki grup kur: Aynı türden ve aynı boydaki fideleri iki gruba ayır. Bir grubu sensörlü sistemle, diğerini her gün sabit miktarda elle sula; ışık ve sıcaklık iki grupta da aynı olsun.
  • Ölç ve kaydet: Haftalık su miktarını (depoyu ölçerek, mL), bitki boyunu (cm) ve yaprak sayısını bir tabloda tut. Koddaki CSV çıktısı ya da Google E-Tablolar kaydı sıcaklık ve nem grafiğini hazır verir.
  • Blok diyagram hazırla: Solda sensörler, ortada Arduino, sağda eylemciler olsun; okları kural cümleleriyle etiketle ("toprak < %35 → pompa"). Jüri kodu okumaz ama bu diyagramı hatırlar.
  • Histerezisi anlat: Tek eşikli ve histerezisli fanın bir saatte kaç kez açılıp kapandığını gösteren iki grafik, projenin mühendislik tarafını jüriye en iyi anlatan şeydir.
  • Canlı gösteri senaryosu yaz: DHT22'yi avucunla ısıtıp fanı çalıştır, toprak sensörünü kuru bir saksıya taşıyıp pompanın darbelerini göster, LDR'yi elinle kapatıp LED'lerin yandığını göster. Her gösteri 10–20 saniye sürsün.
  • Gerçek hayata bağla: Seralardaki su ve enerji tüketimi, aşırı nemin yol açtığı mantar hastalıkları ve üreticinin iş yükü gibi gerçek sorunlardan söz et; sisteminin hangisine cevap verdiğini sayılarla göster.
  • Yedek plan hazırla: Çalışan sistemin videosunu çek; yedek kablo, pompa ve adaptör götür; kalibrasyon değerlerini ve Wi-Fi ayarlarını bir kâğıda yaz.
  • Jüri sorularına hazırlan: "Sensör bozulursa ne olur?", "Elektrik kesilirse bitkilere ne olur?", "Gerçek bir serada nasıl büyütürsün?" sorularına kısa cevaplar hazırla. Koddaki güvenli durum ve taşma koruması bu soruların en güzel cevabıdır.
TÜBİTAK 4006 tematik konularından Tarım ve Hayvancılık Teknolojileri bu proje için en uygun başlıktır. Daha fazla fikir, maliyet tablosu ve değerlendirme ölçütleri için TÜBİTAK Arduino proje fikirleri yazısına göz at.

Sık yapılan hatalar ve çözümleri

BelirtiOlası sebepÇözüm
Pompa çalışınca Arduino resetleniyor ya da LCD bozuluyorPompa ve röleler Arduino'nun 5V pininden besleniyor, motor parazitiPompa ve röle bobinlerini LM2596'dan besle, GND'leri birleştir, pompaya ters diyot ve 470 µF kondansatör ekle
Röleler sürekli tık tık yapıyorTek eşik kullanılıyor ya da ölçüm gürültülüAçma ve kapama için ayrı eşik (histerezis) kullan, analog ölçümlerin ortalamasını al
Pompa durduktan sonra da su akıyorSifon etkisi: hortumun ucu depodaki su seviyesinden aşağıdaDepoyu alçağa koy ya da hortumun tepesine küçük bir hava deliği aç
Toprak nemi hep %0 ya da hep %100Kalibrasyon değerleri yanlış ya da AOUT yanlış pine bağlıSensörün havadaki ve sudaki ham değerini ölç, sabitlere yaz
LED'ler yanıp sönüyorLDR, LED'lerin ışığını görüyorLDR'yi seranın dışına, gökyüzüne bakacak şekilde taşı
DHT22 nan değeri veriyorYanlış pin, pull-up direnci yok ya da 2 saniyeden sık okunuyorPini kontrol et, modül kullan ya da DATA ile VCC arasına 10 kΩ ekle
Sıcaklık olması gerekenden yüksek görünüyorSensöre güneş ya da LED ışığı doğrudan vuruyorDelikli beyaz bir kapakla gölgele, ısıtıcıdan uzağa taşı
Duvarlarda su damlaları ve küfNem çok yüksek, havalandırma yetersizNem eşiğini düşür, hava giriş deliğini büyüt, sulamayı azalt
ESP32'de toprak değeri Wi-Fi açılınca bozuluyorSensör ADC2 pinine bağlıGPIO 32–39 arasındaki bir ADC1 pinine taşı
ESP32 ile röle hiç bırakmıyor3,3 V'luk HIGH sinyali aktif LOW 5 V modülü kapatamıyorJD-VCC ayrımı yap ya da 3,3 V tetiklemeli röle modülü kullan

Akıllı sera projesi; sensör okumayı, kalibrasyonu, histerezisle karar vermeyi, röle ve MOSFET sürmeyi, güç planlamayı ve kablosuz izlemeyi tek bir çalışmada birleştirir ve sonunda gerçekten yaşayan bir şeyi, bir bitkiyi büyütür. Önce sulama ve havalandırmayla başla, her parçayı tek tek test et, sonra ısıtıcıyı, LED'leri ve telefonu ekle. BlueGrays uygulamasında DHT11 ile sıcaklık ve nem ölçümünü, LDR ile ışık okumayı, akıllı sulama istasyonunu ve DHT22'li sıcaklık kaydediciyi devre şemaları ve kodlarıyla adım adım bulabilirsin.

Sıkça sorulan sorular

Akıllı sera projesi için hangi malzemeler gerekir?

Temel bir akıllı sera için Arduino Uno ya da ESP32, DHT22 sıcaklık ve nem sensörü, kapasitif toprak nem sensörü, LDR ve 10 kΩ direnç, röle modülü, mini dalgıç pompa ve bir fan yeterlidir. Tam sürüme 12 V PTC ısıtıcı, MOSFET ile sürülen LED şerit, I2C LCD, şamandıralı seviye sensörü, 12 V 5 A adaptör ve LM2596 eklenir. Gövde için kapaklı şeffaf bir saklama kutusu en kolay ve en ucuz çözümdür.

Akıllı sera nasıl çalışır?

Akıllı sera ölç, karar ver, uygula, göster döngüsüyle çalışır. Sensörler sıcaklığı, nemi, toprak nemini ve ışığı ölçer; Arduino bu değerleri eşiklerle karşılaştırır ve röle ya da MOSFET üzerinden fanı, ısıtıcıyı, pompayı ve LED'leri açıp kapatır. Sonuçlar LCD ekranda ve ESP32 kullanılıyorsa telefonda gösterilir.

Sera için DHT11 mi DHT22 mi kullanmalıyım?

DHT22 seç. DHT11 yalnızca 0–50 °C aralığında ±2 °C doğrulukla ölçer ve %90'ın üstündeki nemi göremez; seralarda ise sabahları nem %90'ı aşabilir, kışın sıcaklık sıfırın altına düşebilir. DHT22 −40 ile 80 °C arasında ±0,5 °C, nemde yaklaşık ±%2 doğrulukla ölçer ve kodu DHT11 ile neredeyse aynıdır.

Akıllı sera projesi kaç TL'ye mal olur?

Fiyatlar satıcıya ve kura göre değişse de kart hariç temel sürüm (DHT22, toprak nem sensörü, LDR, röle, pompa ve fan) genellikle 400–700 TL arasındadır. Isıtıcı, LED şerit, LCD, 12 V adaptör ve gövdeyle tam sürüm 1.200–2.000 TL civarına çıkar. Elinde bir Arduino başlangıç seti varsa maliyet belirgin şekilde düşer.

Akıllı serayı telefondan nasıl izlerim?

En kolay yol beyni ESP32 ile değiştirip bir web sunucusu kurmaktır; aynı Wi-Fi ağındaki telefonun tarayıcısından değerleri görür ve pompayı çalıştırırsın. Evin dışından erişmek için Blynk IoT, uyarı mesajları için Telegram botu, uzun süreli veri kaydı için Google E-Tablolar kullanabilirsin.

Akıllı sera TÜBİTAK projesi olarak nasıl sunulur?

Yalnızca çalışan bir maket göstermek yerine ölçülebilir bir araştırma sorusu kur; örneğin sensörlü sulamanın saatli sulamaya göre ne kadar su tasarrufu sağladığını iki grup bitkiyle haftalarca ölç. Su miktarını, bitki boyunu ve sıcaklık-nem grafiklerini tablo ve grafikle sun, sistemi bir blok diyagramla anlat ve canlı gösteri için kısa bir senaryo hazırla.

Tüm projeleri gör
DHT11 İle Sıcaklık Ve Nem
#55Orta

DHT11 İle Sıcaklık Ve Nem

Odan kaç derece, hava nemli mi, kuru mu? DHT11 sensörü sıcaklığı ve nemi ölçer, Arduino da bu değerleri iki satırlık LCD ekrana yazar ve birkaç saniyede bir yeniler. Sensöre bir şey olursa ekranda hat

4.7(47)
73
Ldr İle Işık Şiddeti Okuma
#11Başlangıç

Ldr İle Işık Şiddeti Okuma

Odanın ne kadar aydınlık olduğunu sayıyla görmek ister misin? Işığa duyarlı küçük bir parça olan LDR ortam ışığını ölçer ve Arduino bu değeri yarım saniyede bir bilgisayar ekranına yazar. Elinle üstün

4.6(81)
139
ESP32 LDR Modülü ile Işık Şiddeti Okuma
#113Başlangıç

ESP32 LDR Modülü ile Işık Şiddeti Okuma

LDR modülünün ham ADC değerini ve karanlık/aydınlık referanslarına göre hesaplanan göreli ışık yüzdesini Serial Monitor'da gerçek zamanlı izleme. Bu yüzde lux ölçümü değildir. Modülün kalibrasyon mantığını öğretir. Proje 10'un öncesinde yapılması ideal; çünkü eşik değerini belirlemek için kullanılır.

4.6(36)
55
Akıllı Sulama İstasyonu
#83İleri
Premium

Akıllı Sulama İstasyonu

Tatile gidince çiçeklerin kurumasın diye kendi kendine sulayan bir bahçıvan. Toprak nem sensörü toprağın ne kadar ıslak olduğunu ölçer; toprak kuruyunca Arduino su pompasını birkaç saniye çalıştırır v

5.0(42)
57
ESP32 DHT22 Sıcaklık ve Nem (LCD Ekranlı)
#117Orta

ESP32 DHT22 Sıcaklık ve Nem (LCD Ekranlı)

DHT22 sensörü ile ortam sıcaklığını ve nem oranını ölçüp 16x2 I2C LCD ekranda gerçek zamanlı olarak gösteren bir projedir. Adafruit DHT kütüphanesi kullanılarak tek kablo (one-wire) protokolü ile sensörden veri okunur. Bu proje, IoT hava istasyonu, akıllı ev otomasyonu veya seralarda ortam takip sistemlerinin temelini oluşturur. ESP32'nin GPIO 4 pini üzerinden DHT22 ile haberleşme sağlanır.

4.8(38)
56
ESP32 Sıcaklık Loglayıcı (DHT22 + DS1307 RTC + microSD + OLED)
#144İleri
Premium

ESP32 Sıcaklık Loglayıcı (DHT22 + DS1307 RTC + microSD + OLED)

ESP32 ile zamanlı sıcaklık ve nem kayıt sistemi kur! Bu projede DHT22 sensörü ile dakikada bir sıcaklık/nem okuyup DS1307 RTC modülünden aldığın gerçek zaman etiketiyle microSD karta CSV formatında kaydediyoruz. OLED ekranda büyük font ile son sıcaklık değeri, nem yüzdesi, timestamp ve toplam kayıt sayısı canlı gösterilir. SD kart üzerindeki /temp_log.csv dosyası Excel/Google Sheets/Python pandas ile açılıp analiz edilebilir — sera monitörü, ev/oda sıcaklık takibi, laboratuvar veri toplama,

4.7(7)
12
ESP32 Akıllı Aydınlatma (PIR + LDR + Röle + OLED)
#141İleri
Premium

ESP32 Akıllı Aydınlatma (PIR + LDR + Röle + OLED)

ESP32, PIR hareket sensörü, LDR ışık sensörü ve röle modülü ile evinin koridorunu, tuvaletini veya kilerini akıllı aydınlatmaya dönüştürüyoruz. Klasik "karanlıkta hareket algılanınca ışık yansın" senaryosunu inşa ediyoruz — ortam aydınlıksa hareket olsa bile ışık yanmaz, böylece gündüz gereksiz yere yanmaz ve enerji tasarrufu sağlanır. Işık 30 saniye yanık kalır; hareket devam ederse timer otomatik sıfırlanır ve süre uzar. SSD1306 OLED ekranda büyük fontlarla durum (AÇIK / GÜNDÜZ / BEKLE), geri

4.3(6)
11