MQTT ile çalışan bir toprak nem sensörü, sabit bir takvime göre sulamak yerine bir tarhın, saksının veya tarla bölgesinin gerçekten ne zaman suya ihtiyaç duyduğunu size söyler. Bu eğitimde kapasitif bir probu ESP32'ye bağlayacak, onu kuru ve doymuş toprağa göre kalibre edecek, yüzde nem değerini deep sleep döngüsüyle bir MQTT broker'ına yayınlayacak ve panellerin ve otomasyonların harekete geçebileceği titreşimsiz (debounced) bir sulama uyarısı oluşturacaksınız.
Neden Kapasitif Prob?
Başlangıç kitlerindeki ucuz, iki çatallı rezistif problar toprağın içinden akım geçirir. Birkaç hafta içinde açıkta kalan elektrotlar korozyona uğrar, okumalar kayar ve metal toprağa karışır. Kapasitif problar ise toprağın dielektrik geçirgenliğini kaplamalı bir devre kartı üzerinden ölçer; böylece toprağa iletken hiçbir şey temas etmez. Bir sezon dayanması gereken her şey için makul asgari seçenek bunlardır.
| Prob türü | Topraktaki ömrü | Doğruluk | Notlar |
|---|---|---|---|
| Rezistif çatal | Haftalar | Zayıf, kayar | Yalnızca bir günlük demo için uygun |
| Kapasitif (v1.2 / v2.0 kartlar) | Kenarı yalıtılırsa sezonlarca | Göreli, kalibrasyon gerekir | Hobi ve küçük çiftlik kullanımı için en iyi fiyat/performans |
| Profesyonel FDR/TDR problar | Yıllar | İyi, çoğunlukla hacimsel | SDI-12 veya RS485 çıkışı, daha yüksek maliyet |
Kapasitif kartlar hacimsel su içeriği değil, göreli bir okuma verir. Her probu içinde yaşayacağı toprakta kalibre ettiğiniz sürece, ne zaman sulanacağına karar vermek için bu yeterlidir.
Parçalar ve Bağlantılar
| Parça | Amaç |
|---|---|
| ESP32 geliştirme kartı (veya piller için düşük bekleme akımlı bir kart) | Probu okur, Wi-Fi'ye ve MQTT'ye bağlanır |
| Kapasitif toprak nem probu | Nemi ölçer |
| 3 jumper kablo | Güç, toprak, sinyal |
| İsteğe bağlı: 18650 pil, tutucu ve küçük güneş paneli | Şebekeden bağımsız güç |
Bağlantılar:
| Prob pini | ESP32 pini |
|---|---|
| VCC | GPIO 25 (anahtarlamalı güç) |
| GND | GND |
| AOUT | GPIO 34 (ADC1) |
İki ayrıntı önemlidir. Birincisi, bir ADC1 pini (GPIO 32 ila 39) kullanın. Wi-Fi etkinken ADC2 pinleri okunamaz. İkincisi, probu 3,3 V hattından değil bir GPIO'dan besleyin; böylece ESP32 uyurken hiç akım çekmez. Kapasitif problar yalnızca birkaç miliamper çeker; bu da bir GPIO'nun sağlayabileceği değerin oldukça altındadır. Bazı ucuz kartlar 3,3 V'ta sorun çıkaran bir regülatörle gelir; okumalar düzensizse kart revizyonunu kontrol edin.
Probun üst kenarını ve açıkta kalan bileşenleri oje, konformal kaplama veya ısıyla daralan makaron ile yalıtın. PCB'nin kesik kenarından içeri sızan su, prob arızalarının en yaygın nedenidir.
Probu Kalibre Etme
ESP32, 0 ile 4095 arasında ham bir değer döndürür. Kapasitif problar kuruyken yüksek, ıslakken düşük okur. Aşağıdaki sketch'i CALIBRATION_MODE değeri true olacak şekilde yükleyin, seri monitörü 115200 baud ile açın ve iki değeri not edin:
- Kuru: prob aynı tarhtan alınmış tamamen kuru toprakta (veya kaba bir yedek olarak havada).
- Islak: prob aynı toprakta, su ile doyurulmuş ve birkaç dakika oturmaya bırakılmış halde.
Probu her seferinde aynı derinliğe, kart üzerinde işaretli çizgiye kadar sokun; asla daha derine değil. Tipik değerler kuru için yaklaşık 2.600 ila 3.000, ıslak için 1.000 ila 1.400 civarındadır, ancak her prob farklıdır; bu yüzden kopyalamak yerine ölçersiniz.
ESP32 Toprak Nem Sensörü MQTT Sketch'i
Sketch uyanır, probu besler, birkaç okumanın medyanını alır, bunu yüzdeye çevirir, Wi-Fi'ye ve broker'a bağlanır, retained bir telemetri mesajı ve bir uyarı durumu yayınlar ve yeniden deep sleep'e geçer. PubSubClient kütüphanesini kullanır. Herkese açık test alanı herkes tarafından okunabildiği için s5d1v8 değerini kendi rastgele dizenizle değiştirin.
#include <WiFi.h>
#include <PubSubClient.h>
#define CALIBRATION_MODE false
const char* WIFI_SSID = "YOUR_WIFI";
const char* WIFI_PASS = "YOUR_WIFI_PASSWORD";
const char* MQTT_HOST = "broker.connectmq.com";
const uint16_t MQTT_PORT = 1883;
const char* CLIENT_ID = "soil-bed1-s5d1v8";
const char* TOPIC_TELE = "connectmq/demo/s5d1v8/garden/bed1/telemetry";
const char* TOPIC_ALERT = "connectmq/demo/s5d1v8/garden/bed1/alert";
const char* TOPIC_STATUS = "connectmq/demo/s5d1v8/garden/bed1/status";
const int PIN_PROBE_PWR = 25;
const int PIN_PROBE_ADC = 34;
const int RAW_DRY = 2850; // kalibrasyondan
const int RAW_WET = 1180; // kalibrasyondan
const float ALERT_ON_PCT = 25.0; // bunun altında uyarıyı başlat
const float ALERT_OFF_PCT = 35.0; // bunun üstünde uyarıyı temizle
const uint64_t SLEEP_MIN = 15;
RTC_DATA_ATTR bool alertActive = false;
RTC_DATA_ATTR uint32_t bootCount = 0;
WiFiClient net;
PubSubClient mqtt(net);
int readRawMedian() {
digitalWrite(PIN_PROBE_PWR, HIGH);
delay(300); // prob çıkışının oturmasını bekle
int v[9];
for (int i = 0; i < 9; i++) {
v[i] = analogRead(PIN_PROBE_ADC);
delay(20);
}
digitalWrite(PIN_PROBE_PWR, LOW);
for (int i = 1; i < 9; i++) { // eklemeli sıralama
int k = v[i], j = i - 1;
while (j >= 0 && v[j] > k) { v[j + 1] = v[j]; j--; }
v[j + 1] = k;
}
return v[4];
}
float rawToPercent(int raw) {
float pct = 100.0f * (RAW_DRY - raw) / (float)(RAW_DRY - RAW_WET);
if (pct < 0) pct = 0;
if (pct > 100) pct = 100;
return pct;
}
bool connectWifi() {
WiFi.mode(WIFI_STA);
WiFi.begin(WIFI_SSID, WIFI_PASS);
for (int i = 0; i < 40 && WiFi.status() != WL_CONNECTED; i++) delay(250);
return WiFi.status() == WL_CONNECTED;
}
bool connectMqtt() {
mqtt.setServer(MQTT_HOST, MQTT_PORT);
for (int i = 0; i < 3; i++) {
if (mqtt.connect(CLIENT_ID, TOPIC_STATUS, 1, true, "offline")) return true;
delay(1000);
}
return false;
}
void goToSleep() {
esp_sleep_enable_timer_wakeup(SLEEP_MIN * 60ULL * 1000000ULL);
esp_deep_sleep_start();
}
void setup() {
Serial.begin(115200);
pinMode(PIN_PROBE_PWR, OUTPUT);
analogSetPinAttenuation(PIN_PROBE_ADC, ADC_11db);
bootCount++;
int raw = readRawMedian();
if (CALIBRATION_MODE) {
while (true) {
Serial.printf("raw=%d\n", readRawMedian());
delay(1000);
}
}
float pct = rawToPercent(raw);
bool changed = false;
if (!alertActive && pct < ALERT_ON_PCT) { alertActive = true; changed = true; }
if (alertActive && pct > ALERT_OFF_PCT) { alertActive = false; changed = true; }
if (connectWifi() && connectMqtt()) {
char buf[160];
snprintf(buf, sizeof(buf),
"{\"moisture_pct\":%.1f,\"raw\":%d,\"rssi\":%d,\"boot\":%lu}",
pct, raw, WiFi.RSSI(), (unsigned long)bootCount);
mqtt.publish(TOPIC_STATUS, "online", true);
mqtt.publish(TOPIC_TELE, buf, true);
snprintf(buf, sizeof(buf), "{\"active\":%s,\"moisture_pct\":%.1f}",
alertActive ? "true" : "false", pct);
mqtt.publish(TOPIC_ALERT, buf, true);
if (changed) Serial.println(alertActive ? "ALERT raised" : "ALERT cleared");
mqtt.loop();
delay(200); // TCP yığınının veriyi göndermesi için zaman tanı
mqtt.publish(TOPIC_STATUS, "sleeping", true);
mqtt.disconnect();
}
goToSleep();
}
void loop() {}
Okumaları izleme
mosquitto_sub -h broker.connectmq.com -p 1883 -i watch-s5d1v8 \
-t 'connectmq/demo/s5d1v8/garden/#' -v
Telemetri retained olduğu için, cihaz zamanının neredeyse tamamını uykuda geçirse bile abone en son okumayı hemen gösterir. Status topic'i düğümün online mı, sleeping mi olduğunu ya da beklenmedik şekilde düşüp düşmediğini (offline, last will'den) söyler.
Sulama Uyarısı Nasıl Çalışır?
Tek bir eşik, okumalar özellikle hafif bir yağmurdan hemen sonra veya güneş toprağı ısıttığında eşiğin etrafında gezindikçe uyarının sürekli açılıp kapanmasına neden olur. Sketch histerezis kullanır: uyarı yüzde 25'in altında açılır ve ancak nem yüzde 35'in üzerine çıktığında temizlenir. alertActive bayrağı RTC belleğinde (RTC_DATA_ATTR) tutulur; böylece deep sleep'ten etkilenmez.
Uyarı topic'i retained'dir ve her zaman mevcut durumu taşır; böylece herhangi bir tüketici buna göre hareket edebilir:
- Home Assistant MQTT otomasyonu rehberinde gösterildiği gibi telefonunuza bildirim gönderen bir Home Assistant otomasyonu;
- otomatik sulama sistemi eğitiminde ele alınan, vana açan bir Node-RED akışı veya Python denetleyicisi;
- ConnectMQ portalında
moisture_pctüzerinde, ev sunucunuz çevrimdışı olsa bile uyarıları kaydeden bir eşik uyarı kuralı.
Doğruluk ve Güvenilirlik İpuçları
- Gerçek toprakta kalibre edin. Kumlu ve killi topraklar aynı su içeriği için çok farklı okumalar verir.
- Batırma derinliğini sabit tutun. Probun etrafındaki hava boşlukları okumaların keskin şekilde düşmesine neden olur; probu soktuktan sonra etrafındaki toprağı sıkıştırın.
- Tek değerlere değil, eğilime bakın. İki gün boyunca düşen bir eğri, tek bir okumadan daha anlamlıdır.
- ADC uç değerlerinden kaçının. ESP32 ADC'si 0 ve 4095 yakınında doğrusal değildir. 11 dB zayıflatma ile kullanışlı aralık kapasitif bir probu rahatça kapsar.
- Pili takip edin. Başka bir ADC1 pinine bir gerilim bölücü ekleyin ve payload'a
battery_vekleyin; ayrıntılar pille çalışan ESP32 sensörü yazısında.
Pil Ömrü
15 dakikalık uyanmalarla düğüm her döngüde yalnızca birkaç saniye uyanık kalır ve bu sürenin çoğu Wi-Fi ilişkilendirmesini beklemekle geçer. Statik IP ve router'ın BSSID'si ile kanalını kullanmak bunu belirgin şekilde kısaltabilir. Düşük bekleme akımlı regülatöre sahip, sürekli açık USB çipi ve LED'i olmayan bir kart seçin; çünkü birçok geliştirme kartı "uykudayken" ESP32'nin kendisinden daha fazla akım çeker. Wi-Fi'den uzak tarlalar için aynı probu kullanan bir LoRaWAN düğümü ve bir ağ sunucusu köprüsü daha iyi bir tasarımdır; ödünleşimler için akıllı tarım IoT rehberine bakın.
Üretim Kurulumu
Ücretsiz herkese açık MQTT broker'ı alanı geliştirme ve test için idealdir, ancak paylaşımlıdır ve herkese açıktır. Kalıcı bir kurulum için özel bir broker oluşturun ve TLS'ye geçin:
WiFiClientSecure.hdosyasını ekleyin, ISRG Root X1 sertifikasıylaWiFiClientSecure net;venet.setCACert(ISRG_ROOT_X1);kullanın;- portu 8883 olarak değiştirin;
mqtt.connect("YOUR_CLIENT_ID", "YOUR_USERNAME", "YOUR_PASSWORD", TOPIC_STATUS, 1, true, "offline")ile bağlanın;- topic'leri kendi önekinize taşıyın, örneğin
farm1/garden/bed1/telemetry.
TLS her uyanma döngüsüne bir iki saniye ekler; verilerinizi gizli tutmak için küçük bir bedel. Barındırılan bir MQTT broker'ı ayrıca sensörlerin bağlı olduğu ağda bir broker çalıştırma zahmetinden de kurtarır. Bunun gibi daha fazla proje IoT otomasyon rehberinde yer alıyor.
Toprağınızı ConnectMQ ile İzleyin
ConnectMQ, sensörlerinize canlı topic gezgini, panel ve kuru toprak uyarıları için eşik uyarı kuralları içeren özel, TLS ile korunan bir broker sunar. app.connectmq.com adresinde kredi kartı gerekmeden ücretsiz bir Serverless broker oluşturun ve canlıya geçmek için sketch'teki üç satırı değiştirin.
Sık Sorulan Sorular
Kapasitif toprak nem sensörüm neden toprak kuruyken daha yüksek değer okuyor?
Kapasitif problar böyle çalışır: dielektrik sabiti suyla birlikte arttıkça çıkış voltajı düşer. Sketch, yüzdeye dönüştürme sırasında ölçeği tersine çevirir.
Tek bir ESP32'de birden fazla prob kullanabilir miyim?
Evet. Diğer ADC1 pinlerini (GPIO 32, 33, 35, 36, 39) kullanın, her probu ayrı ayrı kalibre edin ve her birini kendi topic'ine veya tek bir JSON mesajında ayrı alanlar olarak yayınlayın.
Toprak nem sensörü ne kadar derine yerleştirilmeli?
Bitkinin kök bölgesine; sebzeler ve saksılar için genellikle 5 ila 15 cm. Elektroniğin toprağın üstünde kalması için yalnızca işaretli çizgiye kadar sokun.
Bir toprak nem sensörü MQTT üzerinden ne sıklıkla yayın yapmalı?
15 ila 60 dakikada bir fazlasıyla yeterlidir. Toprak nemi yavaş değişir ve daha uzun aralıklar pil ömrünü önemli ölçüde uzatır.



