Su Seviye Sensörü Arduino: Kalibrasyon, Taşma Alarmı ve Pompa
Su seviye sensörü Arduino'ya nasıl bağlanır? Boş/yarım/dolu kalibrasyonu, korozyonu önleyen pinden besleme, buzzer'lı taşma alarmı, pompa ve ESP32/Pico kodu.
Su seviye sensörü, Arduino ile bir bardaktaki, akvaryumdaki, saksı tabağındaki ya da küçük bir depodaki suyun ne kadar yükseldiğini algılamanın en ucuz ve en kolay yoludur. Kartın üzerindeki açık iletken izler suya battıkça analog çıkıştaki gerilim yükselir; Arduino bu gerilimi analogRead() ile okuyup suyun “boş”, “yarım” ya da “dolu” olduğuna karar verir. Üç kabloyla bağlanır, birkaç satır kodla çalışır ve taşma alarmından otomatik pompa kontrolüne kadar pek çok projenin temelini oluşturur.
Bu rehberde modülün içinde ne olduğunu, okunan değerin neden hiçbir zaman 1023'e ulaşmadığını, boş/yarım/dolu kalibrasyonunu nasıl yapacağını ve sensörü birkaç haftada çürüten korozyonu nasıl önleyeceğini öğreneceksin. Ardından buzzer'lı bir taşma alarmı ve depoyu kendiliğinden dolduran bir pompa kontrolü kuracak, şamandıralı switch ve temassız XKC-Y25 ile kısa bir karşılaştırma yapacak, son olarak aynı işi ESP32 ve Raspberry Pi Pico ile nasıl yapacağını göreceksin.

Su seviye sensörü nedir, nasıl çalışır?
Modülün alt kısmında birbirine değmeyen, tarak dişleri gibi iç içe geçmiş on iletken iz bulunur. Bunların beşi + beslemeye bağlı güç izleri, diğer beşi ise kartın üstündeki S8050 NPN transistörün beyzine giden algılama izleridir. Kart kuruyken izlerin arasında yalnızca hava vardır, transistör kapalıdır ve S pini 0 V'a yakındır. Kart suya battığında su, güç izleriyle algılama izleri arasında köprü kurar; transistörün beyzine küçük bir akım akar, transistör iletime geçer ve emiterden alınan S çıkışının gerilimi yükselir. Su ne kadar yükselirse ıslanan iz uzunluğu o kadar artar, izler arasındaki direnç düşer ve çıkış gerilimi büyür.
Bu çalışma biçiminin üç önemli sonucu var. Birincisi, sensör aslında suyu değil suyun iletkenliğini ölçer: musluk suyundaki çözünmüş mineraller okunan değeri yükseltir, saf (distile) su ise neredeyse hiç değer vermez. İkincisi, çıkış emiter izleyici (emitter follower) olarak çalışan bir transistörden alındığı için gerilim hiçbir zaman beslemeye ulaşmaz; 5 V ile beslenen ve tamamen ıslak bir sensör Arduino Uno'da genellikle 500–650 civarında okunur, 1023'e asla yaklaşmaz. Üçüncüsü, ilişki doğrusal değildir: değer ilk birkaç milimetrede hızla yükselir, sonra giderek yavaşlar. Bu yüzden bu sensör milimetre hassasiyetinde bir cetvel değil, birkaç seviyeyi güvenle ayırt eden pratik bir göstergedir.
| Özellik | Değer |
|---|---|
| Çalışma gerilimi | 3,3–5 V DC |
| Çalışma akımı | 20 mA'den az (en yüksek değer tamamen ıslakken) |
| Çıkış | Analog gerilim (S pini), su yükseldikçe artar |
| Algılama alanı | Yaklaşık 40 × 16 mm, yani en fazla yaklaşık 4 cm su yüksekliği |
| Kart boyutu | Yaklaşık 62 × 20 mm |
| Çalışma sıcaklığı | 10–30 °C (üretici değeri) |
| Pinler | S (sinyal), + (VCC), − (GND) |
Su seviye sensörü bağlantısı: Arduino Uno, ESP32 ve Pico
| Sensör pini | Arduino Uno | ESP32 | Raspberry Pi Pico |
|---|---|---|---|
| S (sinyal) | A0 | GPIO 34 (ADC1) | GP26 (ADC0) |
| + (VCC) | D7 (yalnızca ölçerken besler) | GPIO 25 | GP15 |
| − (GND) | GND | GND | GND |
Korozyonu önlemenin en kolay yolu, tabloda gördüğün gibi sensörü bir dijital pinden beslemektir: kod ölçümden hemen önce pini HIGH yapar, 10 ms bekler, değeri okur ve pini yeniden LOW yapar. Saniyede bir ölçüm yapan bir sistemde izler zamanın yalnızca yüzde 1'inde enerjili kalır; bu da aşınmayı kabaca yüz kat yavaşlatır. Modül tamamen ıslakken en fazla 20 mA civarında akım çeker. Arduino Uno pini için önerilen sınır 20 mA, mutlak sınır 40 mA olduğundan ve pin yalnızca birkaç milisaniye açık kaldığından bu bağlantı güvenlidir; ESP32 pinleri de bu akımı rahatça verir. Pico'nun pinleri ise varsayılan olarak daha düşük bir akım ayarıyla çalışır, bu yüzden sensör tamamen ıslakken pin gerilimi biraz düşer ve okumalar küçülür. Kalibrasyonu aynı bağlantıyla yaptığın sürece bu bir sorun değildir; daha kararlı değerler istersen sensörün + ucunu BC557 gibi küçük bir PNP transistörle anahtarlayabilirsin: emiter kartın 3V3 pinine, kollektör sensörün + ucuna, beyz 1 kΩ'luk bir dirençle GPIO pinine bağlanır ve bu durumda pin LOW olduğunda sensör açılır. Uygun transistörü seçmek için transistör aracına göz atabilirsin.
Adım adım: Arduino ile ilk okuma
- Sensörün S pinini A0'a, + pinini D7'ye, − pinini GND'ye bağla. Kartı, izler aşağı bakacak şekilde dik tut.
- Aşağıdaki kodu Arduino IDE'de aç, kart olarak Arduino Uno'yu ve doğru portu seçip yükle.
- Seri Monitör'ü aç ve hızı 9600 baud yap. Sensör kuruyken değerin 0'a yakın olduğunu gör.
- Sensörü bir bardak suya yavaş yavaş batır: önce yalnızca ucunu, sonra yarısını, sonra izlerin bittiği çizgiye kadar. Her adımda birkaç saniye bekleyip değeri not al.
1const int SENSOR_PIN = A0; // S → A0
2const int POWER_PIN = 7; // + → D7 (yalnızca ölçerken besle / power only while measuring)
3
4int readSensor() {
5 digitalWrite(POWER_PIN, HIGH); // sensörü aç / power the sensor
6 delay(10); // değerin oturmasını bekle / let the reading settle
7 long sum = 0;
8 for (int i = 0; i < 8; i++) { // 8 ölçümün ortalaması / average of 8 readings
9 sum += analogRead(SENSOR_PIN);
10 }
11 digitalWrite(POWER_PIN, LOW); // sensörü kapat / power off
12 return sum / 8;
13}
14
15void setup() {
16 pinMode(POWER_PIN, OUTPUT);
17 digitalWrite(POWER_PIN, LOW); // kapalı başla / start powered off
18 Serial.begin(9600);
19}
20
21void loop() {
22 int raw = readSensor();
23 Serial.print("Ham deger / Raw value: ");
24 Serial.println(raw);
25 delay(1000); // saniyede bir ölç / measure once a second
26}readSensor() fonksiyonu sensörü her ölçümde yalnızca 11 ms kadar açık tutar. 10 ms'lik bekleme, transistörün ve izler arasındaki suyun kararlı bir değere oturmasını sağlar; ardından alınan 8 ölçümün ortalaması tek tek okumalardaki küçük dalgalanmaları törpüler. Uno'da her analogRead() yaklaşık 0,1 ms sürdüğü için 8 ölçüm 1 ms'den kısa sürer. Seri Monitör'de suyu karıştırdığında ya da bardağı salladığında değerlerin oynadığını göreceksin; bu normaldir, çünkü dalgalanan su yüzeyi ıslanan iz uzunluğunu sürekli değiştirir.
Boş, yarım, dolu: kalibrasyon nasıl yapılır?
İnternette bulduğun kodlardaki eşik değerlerini olduğu gibi kullanma; her sensörün, her suyun ve her besleme geriliminin değerleri farklıdır. Kalibrasyonu sensörün gerçekten kullanılacağı kapta ve aynı suyla yap: akvaryum için akvaryum suyu, gübreli bir sulama deposu için gübreli su. Sensörün üzerine bir kalemle 0, 10, 20, 30 ve 40 mm çizgileri çiz, kartı her çizgiye kadar batır, değerin oturması için 3–4 saniye bekle ve Seri Monitör'deki sayıyı yaz. Aşağıdaki tablo musluk suyu ve 5 V besleme için tipik aralıkları gösterir; kendi değerlerini yanına not et.
| Seviye | Batma derinliği | Tipik Uno değeri (5 V, musluk suyu) |
|---|---|---|
| Boş | 0 mm (kuru) | 0–20 |
| Az | Yaklaşık 5–10 mm | 250–400 |
| Yarım | Yaklaşık 20 mm | 400–480 |
| Dolu | Yaklaşık 40 mm (izlerin bittiği çizgi) | 480–650 |
Tabloda dikkat çeken şey, değerlerin ilk santimetrede hızla yükselip sonra sıkışmasıdır: 0 ile 10 mm arasında birkaç yüz birimlik fark varken 20 ile 40 mm arasında yalnızca birkaç on birimlik fark kalabilir. Bu yüzden map() ile tek bir doğru çizmek yerine her iki ölçüm noktası arasında ayrı bir oran kuran parçalı doğrusal ara değerleme (piecewise linear interpolation) çok daha doğru sonuç verir. Aşağıdaki kod senin ölçtüğün beş noktayı iki dizide tutar, ham değeri milimetreye çevirir ve seviyeyi adıyla yazar. RAW dizisine kendi ölçümlerini küçükten büyüğe sırayla yazman yeterlidir.
1const int SENSOR_PIN = A0;
2const int POWER_PIN = 7;
3
4// Kendi kalibrasyon ölçümlerin / your own calibration readings
5const int N = 5;
6const int RAW[N] = {0, 330, 440, 490, 520}; // ham değer, küçükten büyüğe / raw value, ascending
7const int MM[N] = {0, 10, 20, 30, 40}; // batma derinliği (mm) / immersion depth (mm)
8
9int readSensor() {
10 digitalWrite(POWER_PIN, HIGH);
11 delay(10);
12 long sum = 0;
13 for (int i = 0; i < 8; i++) sum += analogRead(SENSOR_PIN);
14 digitalWrite(POWER_PIN, LOW);
15 return sum / 8;
16}
17
18int rawToMm(int raw) {
19 if (raw <= RAW[0]) return MM[0];
20 for (int i = 1; i < N; i++) {
21 if (raw <= RAW[i]) { // iki nokta arasında oran kur / interpolate between two points
22 return map(raw, RAW[i - 1], RAW[i], MM[i - 1], MM[i]);
23 }
24 }
25 return MM[N - 1]; // en üst noktanın üstü / above the top point
26}
27
28const char* levelName(int mm) {
29 if (mm < 3) return "Bos / Empty";
30 if (mm < 15) return "Az / Low";
31 if (mm < 30) return "Yarim / Half";
32 return "Dolu / Full";
33}
34
35void setup() {
36 pinMode(POWER_PIN, OUTPUT);
37 digitalWrite(POWER_PIN, LOW);
38 Serial.begin(9600);
39}
40
41void loop() {
42 int raw = readSensor();
43 int mm = rawToMm(raw);
44 Serial.print(raw);
45 Serial.print(" -> ");
46 Serial.print(mm);
47 Serial.print(" mm, ");
48 Serial.println(levelName(mm));
49 delay(1000);
50}Buzzer'lı taşma alarmı
Su seviye sensörünün en kullanışlı işlerinden biri taşmayı haber vermektir: çamaşır makinesinin ya da kombinin altına, saksı tabağına, klimanın drenaj kabına veya dolmakta olan bir kovanın kenarına yerleştirdiğin sensör, su ucuna değdiği anda alarmı başlatır. Bunun için kalibrasyon tablosundaki “az” seviyesi bile yeterlidir. Aşağıdaki kod aktif bir buzzer ve Uno'nun dahili LED'ini kullanır; değer ALARM_ON'u geçince buzzer çeyrek saniye aralıklarla öter, değer ALARM_OFF'un altına inince susar. Bekleme için delay() yerine millis() kullanıldığından ölçüm ile buzzer birbirini durdurmaz. Buzzer çeşitleri için Buzzer Nedir?, millis() mantığı için millis() ve delay() yazılarına bakabilirsin.
1const int SENSOR_PIN = A0; // S → A0
2const int POWER_PIN = 7; // + → D7
3const int BUZZER_PIN = 8; // aktif buzzer + ucu / active buzzer +
4const int LED_PIN = 13; // Uno'nun dahili LED'i / Uno's built-in LED
5
6const int ALARM_ON = 200; // bu değer ve üstü taşma / at or above: overflow (kendin ölç / measure yours)
7const int ALARM_OFF = 100; // bunun altına inince alarm biter / alarm clears below this
8
9bool alarmActive = false;
10bool buzzerOn = false;
11unsigned long lastRead = 0;
12unsigned long lastBeep = 0;
13
14int readSensor() {
15 digitalWrite(POWER_PIN, HIGH);
16 delay(10);
17 long sum = 0;
18 for (int i = 0; i < 8; i++) sum += analogRead(SENSOR_PIN);
19 digitalWrite(POWER_PIN, LOW);
20 return sum / 8;
21}
22
23void setup() {
24 pinMode(POWER_PIN, OUTPUT);
25 pinMode(BUZZER_PIN, OUTPUT);
26 pinMode(LED_PIN, OUTPUT);
27 digitalWrite(POWER_PIN, LOW);
28 Serial.begin(9600);
29}
30
31void loop() {
32 unsigned long now = millis();
33
34 if (now - lastRead >= 1000) { // saniyede bir ölç / measure once a second
35 lastRead = now;
36 int level = readSensor();
37 if (!alarmActive && level >= ALARM_ON) alarmActive = true; // taşma başladı / overflow started
38 if (alarmActive && level < ALARM_OFF) alarmActive = false; // su çekildi / water receded
39 Serial.print("Seviye / Level: ");
40 Serial.println(level);
41 }
42
43 if (alarmActive) {
44 if (now - lastBeep >= 250) { // 250 ms öt, 250 ms sus / 250 ms on, 250 ms off
45 lastBeep = now;
46 buzzerOn = !buzzerOn;
47 digitalWrite(BUZZER_PIN, buzzerOn ? HIGH : LOW);
48 }
49 } else if (buzzerOn) {
50 buzzerOn = false;
51 digitalWrite(BUZZER_PIN, LOW);
52 }
53 digitalWrite(LED_PIN, alarmActive ? HIGH : LOW);
54}Pompa kontrolü: depoyu kendiliğinden doldurmak
İkinci klasik uygulama, seviyeyi belirli bir aralıkta tutan otomatik doldurmadır. Akvaryumda buharlaşan suyu yedek bir kovadan tamamlamak, evcil hayvanının suluğunu dolu tutmak ya da bir sera deposunu beslemek isteyebilirsin. Mantık basittir: seviye START_BELOW değerinin altına düşünce pompa çalışır, STOP_ABOVE değerine ulaşınca durur. Bu iki eşik arasındaki boşluk, pompanın sürekli açılıp kapanmasını önleyen histerezistir. Sensörün yalnızca yaklaşık 4 cm'lik bir algılama alanı olduğunu unutma; kartı, korumak istediğin su bandı bu 4 cm'nin içine düşecek yükseklikte sabitle.

Pompa, Arduino pininin verebileceğinden çok daha fazla akım çeker; bu yüzden onu bir röle modülüyle ya da lojik seviye bir MOSFET ve ters diyotla sür, pompayı ayrı bir güç kaynağından besle ve iki kaynağın GND'sini birleştir. Ayrıntılar için Röle Modülü Nedir?, MOSFET kullanımı ve mini su pompası yazılarına bakabilirsin. Koddaki en önemli kısım bir güvenlik önlemidir: pompa MAX_RUN_MS süresi boyunca çalıştığı hâlde seviye istenen değere ulaşmazsa sistem pompayı kilitler ve kesik kesik öterek seni uyarır. Hortum çıkmış, yedek kova boşalmış ya da sensör yerinden kaymış olabilir; bu kilit olmadan pompa saatlerce susuz çalışabilir ya da her yeri su basabilir.
1const int SENSOR_PIN = A0;
2const int POWER_PIN = 7;
3const int PUMP_PIN = 8; // röle IN / relay IN
4const int BUZZER_PIN = 9; // aktif buzzer / active buzzer
5const bool RELAY_ACTIVE_LOW = true; // çoğu röle modülü LOW ile çeker / most relay modules switch on LOW
6
7const int START_BELOW = 300; // bunun altında doldur / start filling below this (kendin ölç / measure yours)
8const int STOP_ABOVE = 480; // bu değerde dur / stop at this value
9const unsigned long MAX_RUN_MS = 30000; // en uzun çalışma 30 sn / max run time 30 s
10
11bool pumpOn = false;
12bool fault = false;
13unsigned long pumpStart = 0;
14
15int readSensor() {
16 digitalWrite(POWER_PIN, HIGH);
17 delay(10);
18 long sum = 0;
19 for (int i = 0; i < 8; i++) sum += analogRead(SENSOR_PIN);
20 digitalWrite(POWER_PIN, LOW);
21 return sum / 8;
22}
23
24void setPump(bool on) {
25 pumpOn = on;
26 bool pinHigh = RELAY_ACTIVE_LOW ? !on : on;
27 digitalWrite(PUMP_PIN, pinHigh ? HIGH : LOW);
28}
29
30void setup() {
31 setPump(false); // pin çıkış olmadan önce kapalı konuma al / set off before the pin becomes an output
32 pinMode(PUMP_PIN, OUTPUT);
33 pinMode(POWER_PIN, OUTPUT);
34 pinMode(BUZZER_PIN, OUTPUT);
35 digitalWrite(POWER_PIN, LOW);
36 Serial.begin(9600);
37}
38
39void loop() {
40 if (fault) { // arıza: pompa kilitli, kesik kesik öt / fault: pump locked out, beep
41 digitalWrite(BUZZER_PIN, HIGH);
42 delay(200);
43 digitalWrite(BUZZER_PIN, LOW);
44 delay(1800);
45 return; // yeniden başlatmak için reset / press reset to restart
46 }
47
48 int level = readSensor();
49
50 if (!pumpOn && level < START_BELOW) {
51 setPump(true); // seviye düştü, doldur / level low, start filling
52 pumpStart = millis();
53 } else if (pumpOn && level >= STOP_ABOVE) {
54 setPump(false); // istenen seviyeye ulaşıldı / target level reached
55 } else if (pumpOn && millis() - pumpStart > MAX_RUN_MS) {
56 setPump(false); // süre doldu, seviye yükselmedi / timed out, level did not rise
57 fault = true;
58 }
59
60 Serial.print("Seviye / Level: ");
61 Serial.print(level);
62 Serial.println(pumpOn ? " pompa / pump ON" : " pompa / pump OFF");
63 delay(500);
64}Su seviye sensörü, şamandıralı switch ve XKC-Y25 karşılaştırması
| Özellik | Su seviye sensörü (iletken izli) | Şamandıralı switch (float) | XKC-Y25 (temassız) |
|---|---|---|---|
| Algılama yöntemi | Suyun iletkenliği | Yüzen mıknatıs ve reed kontak | Kap duvarının arkasındaki kapasitans değişimi |
| Çıkış | Analog (birkaç seviye) | Açık ya da kapalı kontak | Dijital (sıvı var ya da yok) |
| Ölçüm aralığı | Yaklaşık 0–4 cm | Tek nokta (montaj yüksekliği) | Tek nokta (montaj yüksekliği) |
| Suya temas | Var, izler suyun içinde | Var, gövde suyun içinde | Yok, kabın dışına yapışır |
| Korozyon | Var; pinden beslemek şart | Yok denecek kadar az | Yok |
| Besleme | 3,3–5 V | Gerekmez (pasif kontak) | 5–24 V, yaklaşık 5 mA |
| En uygun kullanım | Deney, taşma alarmı, küçük kaplar | Kalıcı depo, pompa koruması | Kapalı plastik ya da cam depo, aşındırıcı sıvılar |
| Fiyat | En ucuz | Ucuz | Diğerlerinden pahalı |
Şamandıralı switch, içinde reed kontak bulunan bir gövde ile bu gövde üzerinde kayan mıknatıslı bir şamandıradan oluşur. Su yükseldikçe şamandıra yukarı kalkar, mıknatıs reed kontağın hizasına gelir ve kontak kapanır ya da açılır. Şamandırayı gövde üzerinde ters takarak normalde açık (NO) ve normalde kapalı (NC) davranışını değiştirebilirsin. Arduino'ya bağlamak için bir kabloyu dijital pine, diğerini GND'ye bağlayıp pini INPUT_PULLUP yapman yeterlidir; elektrolizle aşınma sorunu olmadığından kalıcı kurulumlarda çok daha uzun ömürlüdür. Küçük modellerin kontakları genellikle 0,5 A ve 10 W civarıyla sınırlıdır, bu yüzden pompayı doğrudan değil röle üzerinden sür. Reed kontağın çalışma mantığı için Reed Röle yazısına bakabilirsin.

1const int FLOAT_PIN = 2; // bir kablo D2'ye, diğeri GND'ye / one wire to D2, the other to GND
2
3void setup() {
4 pinMode(FLOAT_PIN, INPUT_PULLUP); // dahili pull-up direnci / internal pull-up resistor
5 Serial.begin(9600);
6}
7
8void loop() {
9 // Kontak kapalıyken pin LOW okunur / the pin reads LOW when the contact is closed
10 if (digitalRead(FLOAT_PIN) == LOW) {
11 Serial.println("Kontak kapali / Contact closed");
12 } else {
13 Serial.println("Kontak acik / Contact open");
14 }
15 delay(500);
16}XKC-Y25 ise suya hiç değmeyen kapasitif bir sensördür: plastik ya da cam bir deponun dış yüzüne yapıştırılır ve duvarın arkasında sıvı olup olmadığını algılar. Üretici değerlerine göre 5–24 V ile çalışır, yaklaşık 5 mA çeker, metal olmayan ve 13 mm'ye kadar kalınlıktaki duvarların arkasını algılayabilir ve yaklaşık 500 ms'de tepki verir. Çıkışın yüksek seviyesi besleme gerilimine eşittir; bu yüzden 5 V ile beslediğin bir XKC-Y25'i ESP32 ya da Pico'ya bağlarken bir gerilim bölücü kullanmalısın (gerilim bölücü aracı doğru dirençleri hesaplar). Hassasiyet ayarını ve farklı çıkışlı modelleri XKC-Y25 temassız seviye sensörü yazısında ayrıntılı anlatıyoruz.

ESP32 ile su seviyesini telefondan izlemek
ESP32 ile ölçümü Wi-Fi üzerinden telefonuna taşıyabilirsin. Sensörün S pinini mutlaka ADC1'e bağlı bir pine (GPIO 32–39) bağla; ADC2 pinleri Wi-Fi açıkken okunamaz. ESP32'nin ADC'si 12 bitlik olduğu için değerler 0–4095 arasındadır ve sensör 3,3 V ile beslendiğinden Uno'daki sayılarla karşılaştırılamaz; kalibrasyonu yeniden yapmalısın. ESP32'nin ADC'si 0 V'a ve üst sınıra yakın bölgelerde tam doğrusal değildir, ama burada mutlak gerilim değil yalnızca seviyeler arasındaki fark önemli olduğundan bu bir sorun yaratmaz. Aşağıdaki kod iki saniyede bir ölçüm yapar ve aynı ağdaki telefonundan açabileceğin, beş saniyede bir kendini yenileyen küçük bir web sayfası sunar.
1#include <WiFi.h>
2#include <WebServer.h>
3
4const char* WIFI_SSID = "WIFI_ADIN"; // ağ adın / your network name
5const char* WIFI_PASS = "WIFI_SIFREN"; // ağ şifren / your network password
6
7const int SENSOR_PIN = 34; // S → GPIO 34 (ADC1, Wi-Fi ile çalışır / works with Wi-Fi)
8const int POWER_PIN = 25; // + → GPIO 25
9const int HALF = 1500; // yarım eşiği / half threshold (kendin ölç / measure yours)
10const int FULL = 2000; // dolu eşiği / full threshold (kendin ölç / measure yours)
11
12WebServer server(80);
13int lastRaw = 0;
14unsigned long lastRead = 0;
15
16int readSensor() {
17 digitalWrite(POWER_PIN, HIGH);
18 delay(10);
19 long sum = 0;
20 for (int i = 0; i < 16; i++) sum += analogRead(SENSOR_PIN); // 0–4095
21 digitalWrite(POWER_PIN, LOW);
22 return sum / 16;
23}
24
25const char* levelName(int raw) {
26 if (raw < 100) return "Bos / Empty";
27 if (raw < HALF) return "Az / Low";
28 if (raw < FULL) return "Yarim / Half";
29 return "Dolu / Full";
30}
31
32void handleRoot() {
33 String html = "<!DOCTYPE html><html><head><meta charset='utf-8'>"
34 "<meta name='viewport' content='width=device-width'>"
35 "<meta http-equiv='refresh' content='5'></head><body>"
36 "<h1>Su seviyesi / Water level</h1><h2>";
37 html += levelName(lastRaw);
38 html += "</h2><p>Ham deger / Raw: ";
39 html += lastRaw;
40 html += "</p></body></html>";
41 server.send(200, "text/html", html);
42}
43
44void setup() {
45 Serial.begin(115200);
46 pinMode(POWER_PIN, OUTPUT);
47 digitalWrite(POWER_PIN, LOW);
48 WiFi.begin(WIFI_SSID, WIFI_PASS);
49 while (WiFi.status() != WL_CONNECTED) { // bağlanana kadar bekle / wait until connected
50 delay(500);
51 Serial.print(".");
52 }
53 Serial.println();
54 Serial.print("Adres / Address: http://");
55 Serial.println(WiFi.localIP());
56 server.on("/", handleRoot);
57 server.begin();
58}
59
60void loop() {
61 server.handleClient();
62 if (millis() - lastRead >= 2000) { // 2 sn'de bir ölç / measure every 2 s
63 lastRead = millis();
64 lastRaw = readSensor();
65 }
66}Kodu yüklemeden önce WIFI_SSID ve WIFI_PASS değerlerini kendi ağınla değiştir; ESP32 yalnızca 2,4 GHz ağlara bağlanır. Seri Monitör'ü 115200 baud ile açtığında görünen adresi telefonunun tarayıcısına yazman yeterlidir. Seviye “dolu” olduğunda telefonuna bildirim gelsin istersen aynı ölçümü ESP32 Telegram bot yazısındaki yöntemle bir mesaja çevirebilirsin.
Raspberry Pi Pico ve MicroPython ile taşma alarmı
Raspberry Pi Pico'da analog okuma için GP26, GP27 ve GP28 pinleri kullanılır. MicroPython'daki read_u16() fonksiyonu Pico'nun 12 bitlik ölçümünü 0–65535 aralığına ölçekleyerek verir, bu yüzden eşik değerlerin Uno'dakinden çok daha büyük sayılar olacaktır. Aşağıdaki kod sensörü GP15'ten besler, S çıkışını GP26'dan okur ve GP14'e bağlı aktif buzzer ile üç kısa bip sesiyle taşma uyarısı verir. Eşikleri yine ilk koddaki gibi kendi ölçümlerinle belirle.
1from machine import ADC, Pin
2import time
3
4sensor = ADC(26) # GP26 (ADC0) → S
5power = Pin(15, Pin.OUT, value=0) # GP15 → sensör + / sensor +
6buzzer = Pin(14, Pin.OUT, value=0) # GP14 → aktif buzzer / active buzzer
7
8ALARM_ON = 20000 # bu değer ve üstü taşma / at or above: overflow (kendin ölç / measure yours)
9ALARM_OFF = 10000 # bunun altında alarm biter / alarm clears below this
10
11def read_level(samples=8):
12 power.value(1)
13 time.sleep_ms(10) # değerin oturmasını bekle / let the reading settle
14 total = 0
15 for _ in range(samples):
16 total += sensor.read_u16() # 0–65535
17 power.value(0)
18 return total // samples
19
20alarm = False
21while True:
22 level = read_level()
23 if not alarm and level >= ALARM_ON:
24 alarm = True
25 elif alarm and level < ALARM_OFF:
26 alarm = False
27 print("Seviye / Level:", level, "ALARM" if alarm else "")
28 if alarm:
29 for _ in range(3): # üç kısa bip / three short beeps
30 buzzer.value(1)
31 time.sleep_ms(150)
32 buzzer.value(0)
33 time.sleep_ms(150)
34 else:
35 time.sleep(1)Su seviye sensörü ile proje fikirleri
- Saksı tabağı taşma uyarısı: Sulamadan sonra tabakta su birikince öten bir buzzer; toprak nem sensörüyle birleştirince tam bir sulama sistemi olur.
- Akvaryum otomatik su tamamlama: Buharlaşan suyu yedek kovadan mini pompayla tamamlayan, süre sınırlı bir doldurma sistemi.
- Evcil hayvan suluğu: Su kabı azalınca LED yakan ya da ESP32 ile telefona bildirim gönderen bir uyarıcı.
- Su baskını dedektörü: Çamaşır makinesinin, kombinin ya da bodrumun zeminine yatay yerleştirilen sensörle sızıntı alarmı.
- Akıllı sera deposu: Sulama deposunun seviyesini izleyen ve depo boşalınca pompayı kilitleyen bir koruma; akıllı sera projesine kolayca eklenir.
- Yağmur suyu kabı göstergesi: Seviyeyi bir I2C LCD ekranda boş, yarım ve dolu olarak gösteren bir panel; yağmurun başladığını yakalamak için bir yağmur sensörü de ekleyebilirsin.
Sık yapılan hatalar ve çözümleri
| Belirti | Olası sebep | Çözüm |
|---|---|---|
| Değer hep 0, suda da değişmiyor | + pini beslenmiyor (POWER_PIN HIGH yapılmıyor) ya da S yanlış pine bağlı | pinMode ve digitalWrite satırlarını, S'nin analog pine bağlı olduğunu kontrol et |
| Değer kuruyken bile rastgele oynuyor | S pini boşta ya da GND bağlantısı yok | Üç kabloyu da kontrol et; GND ortak olmalı |
| Tamamen suda bile 1023'e çıkmıyor | Bu normal; çıkış emiter izleyiciden alınır | Eşikleri kendi ölçtüğün en yüksek değere göre belirle |
| Saf suda hiçbir değer okunmuyor | Distile ya da arıtılmış suyun iletkenliği çok düşük | Bu suda XKC-Y25 ya da şamandıralı switch kullan |
| Değerler haftalar içinde düşüyor ya da kayıyor | İzlerde elektroliz ve tortu | Sensörü pinden besle, izleri yumuşak bir fırçayla temizle, gerekirse sensörü değiştir |
| Pompa ya da buzzer eşikte sürekli açılıp kapanıyor | Tek eşik kullanılmış; dalgalanan yüzey değeri oynatıyor | Açma ve kapama için iki ayrı eşik (histerezis) kullan, ortalama al |
| ESP32'de Wi-Fi bağlanınca değer okunmuyor | Sensör ADC2 pinine bağlı | S'yi GPIO 32–39 arasındaki bir ADC1 pinine taşı |
Su seviye sensörü; analog okumayı, kalibrasyonu, histerezisi ve korozyon gibi gerçek dünya sorunlarını tek bir ucuz modülle öğretir. Büyük bir deponun seviyesini santimetre santimetre ölçmen gerekiyorsa HC-SR04 mesafe sensörü gibi ultrasonik bir çözüme geçebilirsin. BlueGrays uygulamasında akıllı sulama istasyonu ve buzzer'lı alarm projelerini adım adım devre şemaları ve kodlarıyla bulabilir, su seviye sensörünü bu projelere kolayca ekleyebilirsin.
Sıkça sorulan sorular
Su seviye sensörü nasıl çalışır?
Kartın üzerindeki iç içe geçmiş iletken izler suya battıkça su, izler arasında köprü kurar ve kart üzerindeki S8050 transistörün beyzine akım akar. Transistör iletime geçtikçe S pinindeki gerilim yükselir; Arduino bu gerilimi analogRead() ile okuyarak suyun ne kadar yükseldiğini anlar.
Su seviye sensörü neden paslanıyor?
Islak izlerden sürekli doğru akım geçtiğinde elektroliz başlar ve + beslemeye bağlı izlerin kaplaması çözülür. Sensörü 5V yerine bir dijital pinden besleyip yalnızca ölçüm anında birkaç milisaniye açarsan aşınma büyük ölçüde yavaşlar ve sensör aylarca kullanılabilir.
Su seviye sensörü saf suda çalışır mı?
Pek çalışmaz. Sensör suyun iletkenliğini ölçtüğü için çözünmüş minerali olmayan distile ya da arıtılmış su çok düşük değerler verir. Bu tür sularda temassız XKC-Y25 ya da şamandıralı switch gibi iletkenlikten bağımsız sensörler tercih edilmelidir.
Su seviye sensörünün değeri neden 1023'e çıkmıyor?
S çıkışı transistörün emiterinden alındığı için gerilim beslemenin altında kalır ve beyz akımı suyun direnciyle sınırlanır. Arduino Uno'da 5 V ile tamamen ıslak bir sensör genellikle 500–650 civarında okunur; eşiklerini bu en yüksek değere göre belirlemelisin.
Su seviye sensörü suya tamamen batırılabilir mi?
Hayır. Yalnızca iletken izlerin bulunduğu alt kısım suya girmelidir; transistör, LED ve pinlerin bulunduğu üst kısım ıslanırsa kısa devre olur ve sensör yanlış okur ya da bozulur. Elektronik kısmı sıcak silikon veya vernikle korumak ömrünü uzatır.
Büyük bir su deposunun seviyesi nasıl ölçülür?
Bu sensör yalnızca yaklaşık 4 cm'lik bir aralığı ölçebildiği için büyük depolara uygun değildir. Seviyeyi sürekli ölçmek için depo kapağına takılan JSN-SR04T gibi su geçirmez ultrasonik sensörler, yalnızca birkaç kritik noktayı izlemek için farklı yüksekliklere yerleştirilen şamandıralı switch'ler kullanılır.
Bu yazıdan sonra yapabileceğin projeler
Tüm projeleri gör
Buzzer Kullanımı
Kapı zili ya da alarm sesi nasıl çıkar, hiç merak ettin mi? Arduino küçük bir buzzer'ı kısa aralıklarla öttürür: bip, sus, bip, sus. Sesin elektrikle nasıl üretildiğini görür, ileride melodi çalan pro

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

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.

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

Reed Röle Değer Okuma
Kapı ve pencere alarmlarındaki mıknatıslı anahtarı hiç merak ettin mi? Reed röle modülüne bir mıknatıs yaklaşınca içindeki minik anahtar kapanır; Arduino bunu saniyede bir okuyup bilgisayar ekranına 0

ESP32 Async Web Server (LCD'de IP Göstergeli)
Bu projede ESP32'yi aynı Wi-Fi ağındaki telefonunuzdan veya bilgisayarınızdan kontrol edebileceğiniz asenkron bir web sunucusuna dönüştürüyoruz. ESPAsyncWebServer kütüphanesi sayesinde sunucu birden fazla isteği aynı anda işleyebiliyor (klasik WebServer.h gibi tek istekte bloklamıyor). Tarayıcıdan ESP32'nin IP adresine bağlanıp ON/OFF butonlarına basarak (/on ve /off adresleri) GPIO 5'e bağlı LED'i açıp kapatabileceksiniz.

ESP32 Hareket Alarm Sistemi (PIR + Buzzer + LED + Telegram)
PIR sensörü hareket algıladığında buzzer ve LED'i aktif eden, aynı anda Telegram üzerinden sahibine anlık bildirim gönderen akıllı bir güvenlik alarm sistemidir. Tekrarlayan alarmların sıklığını sınırlamak için 30 saniyelik cooldown (bekleme süresi) mekanizması vardır; bu mekanizma PIR sensörünün yanlış algılamalarını doğrulamaz veya ortadan kaldırmaz. Ev güvenliği, garaj izleme, depo veya çalışma odası gibi alanlarda kullanılabilir. Telegram entegrasyonu sayesinde nerede olursanız olun anında h
Diğer yazılar
BlueGrays uygulaması
Bu devreyi telefonunda adım adım kur
Devre şeması, kod ve parça listesi tek ekranda. 200'den fazla Arduino, ESP32 ve Pico projesi seni bekliyor.
Telefonunla tara
Kamerayı koda tut; telefonunun uygulama mağazası açılır.
ya da mağazada aç

