RP–04 · Raspberry Pi başlangıç projesi

DS18B20 ile Sıcaklık Kaydedici

Bilim insanları gibi veri toplayalım! Bu projede DS18B20 sensörüyle sıcaklığı ölçecek, dakikada bir CSV dosyasına kaydedecek ve topladığımız verilerden matplotlib ile bir grafik çizeceğiz.

SeviyeBaşlangıç
Süre40 dk
Malzeme7 çeşit
1-WireDS18B20Dosya okumaCSVmatplotlibVeri kaydı

Proje hakkında

DS18B20, tek bir veri kablosu üzerinden haberleşen dijital bir sıcaklık sensörüdür. Raspberry Pi'nin analog girişi olmadığı için LM35 gibi analog sensörleri doğrudan okuyamayız; DS18B20 ise ölçümü sayı olarak gönderdiği için Pi'ye doğrudan bağlanabilir. Su geçirmez prob versiyonu akvaryum, toprak ve sıvı ölçümleri için idealdir.

Linux'ta neredeyse her şey bir dosyadır. Raspberry Pi'de 1-Wire arayüzünü açtığınızda sensörün ölçümü de sistemde bir dosya olarak görünür. Python ile bu dosyayı okuyacak, verileri zaman damgasıyla bir tabloya kaydedecek ve grafiğe dönüştüreceğiz. Bu, veri bilimi ve IoT projelerinin temel akışıdır.

  • 1-Wire protokolünü ve arayüzün açılmasını
  • Linux'ta sensör verisini dosyadan okumayı
  • Ölçümleri zaman damgasıyla CSV dosyasına yazmayı
  • matplotlib ile veriden grafik oluşturmayı

Malzeme listesi

Projeyi tamamlamak için aşağıdaki 7 çeşit malzemeye ihtiyacınız var. Raspberry Pi'niz hazırsa geri kalan parçaların çoğu elektronik başlangıç setlerinde bulunur.

Raspberry Pi 4 veya 5 1 adet

Raspberry Pi OS (Bookworm veya üstü) kurulu olmalı. Pi 3B+ ile de çalışır.

microSD kart 1 adet

En az 16 GB, Raspberry Pi OS yüklü.

Resmi güç adaptörü 1 adet

Pi 5 için 5V 5A USB-C, Pi 4 için 5V 3A USB-C.

Breadboard 1 adet

Yarım boy (400 delik) yeterlidir.

DS18B20 sıcaklık sensörü 1 adet

Su geçirmez prob veya transistör görünümlü TO-92 kılıf.

4,7 kΩ direnç 1 adet

Pull-up direnci. Renk kodu: sarı-mor-kırmızı.

Jumper kablo (dişi-erkek) 3 adet

Devre bağlantıları

Bağlantıları Raspberry Pi kapalıyken ve güç kablosu çıkarılmışken yapın. Her satırda önce GPIO (BCM) numarası, ardından kart üzerindeki fiziksel pin numarası yazar; çizgi rengi önerilen kablo rengidir.

DS18B20 VDD (kırmızı kablo)3,3V · pin 15V'a bağlamayın
DS18B20 DATA (sarı kablo)GPIO4 · pin 71-Wire varsayılan pini
DS18B20 GND (siyah kablo)GND · pin 6
4,7 kΩ dirençDATA ↔ 3,3VDATA ile VDD arasına
TO-92 kılıflı sensörü düz yüzü size bakacak şekilde tuttuğunuzda bacaklar soldan sağa GND – DATA – VDD sırasındadır. Ters bağlanırsa sensör birkaç saniyede çok ısınır; böyle bir durumda hemen gücü kesin.

Adım adım kurulum

  1. 1-Wire arayüzünü açın

    Terminale sudo raspi-config yazın. Interface Options › 1-Wire › Yes seçin ve Pi'yi kapatın.

  2. Sensörü bağlayın

    Güç kapalıyken VDD'yi pin 1'e, GND'yi pin 6'ya, DATA'yı pin 7'ye (GPIO4) bağlayın.

  3. Pull-up direncini ekleyin

    4,7 kΩ direnci breadboard üzerinde DATA hattı ile 3,3V hattı arasına takın. Bu direnç olmadan sensör algılanmaz.

  4. Sensörü bulun

    Pi'yi açıp ls /sys/bus/w1/devices/ komutunu çalıştırın. 28- ile başlayan bir klasör görüyorsanız sensör tanınmıştır.

  5. İlk ölçümü okuyun

    cat /sys/bus/w1/devices/28-*/w1_slave komutunu yazın. İkinci satırdaki t=23125 değeri 23,125 °C demektir.

  6. Kaydediciyi başlatın

    İkinci kodu çalıştırın. Her dakika sicaklik_kaydi.csv dosyasına yeni bir satır eklenecek. Birkaç saat çalışmaya bırakın.

  7. Grafiği çizin

    sudo apt install python3-matplotlib ile kütüphaneyi kurup üçüncü kodu çalıştırın; sicaklik_grafigi.png dosyası oluşacak.

Python kodu

Kodları Thonny editörüne yapıştırıp .py uzantısıyla kaydedin ve Run düğmesine basın ya da terminalden python3 dosya_adi.py komutuyla çalıştırın. Programı durdurmak için Ctrl+C tuşlarını kullanın.

Sensörü bulup her saniye sıcaklığı ekrana yazar.

sicaklik_oku.pyPython
# DS18B20 ile sıcaklık okuma
# RobotikHocasi.com

import glob
import time

def sensor_dosyasi():
    klasorler = glob.glob("/sys/bus/w1/devices/28-*")
    if not klasorler:
        raise RuntimeError("DS18B20 bulunamadi. 1-Wire acik mi, kablolar dogru mu?")
    return klasorler[0] + "/w1_slave"

def sicaklik_oku(dosya):
    while True:
        with open(dosya) as f:
            satirlar = f.readlines()
        if satirlar[0].strip().endswith("YES"):   # Veri doğrulaması başarılı
            break
        time.sleep(0.2)                           # Hatalı okumada tekrar dene
    konum = satirlar[1].find("t=")
    return int(satirlar[1][konum + 2:]) / 1000.0

dosya = sensor_dosyasi()
print("Sensor bulundu:", dosya)

while True:
    sicaklik = sicaklik_oku(dosya)
    print(f"Sicaklik: {sicaklik:.2f} C")
    time.sleep(1)

Dakikada bir ölçümü zaman damgasıyla CSV dosyasına ekler.

kaydedici.pyPython
# Sıcaklık kaydedici (data logger)
import csv
import glob
import time
from datetime import datetime
from pathlib import Path

DOSYA = Path("sicaklik_kaydi.csv")
ARALIK = 60      # saniye

def sicaklik_oku():
    yol = glob.glob("/sys/bus/w1/devices/28-*/w1_slave")[0]
    while True:
        with open(yol) as f:
            satirlar = f.readlines()
        if satirlar[0].strip().endswith("YES"):
            return int(satirlar[1].split("t=")[1]) / 1000.0
        time.sleep(0.2)

yeni_dosya = not DOSYA.exists()

with DOSYA.open("a", newline="") as f:
    yazici = csv.writer(f)
    if yeni_dosya:
        yazici.writerow(["zaman", "sicaklik_c"])   # Başlık satırı

    while True:
        zaman = datetime.now().isoformat(timespec="seconds")
        sicaklik = sicaklik_oku()
        yazici.writerow([zaman, f"{sicaklik:.2f}"])
        f.flush()                                   # Hemen diske yaz
        print(zaman, sicaklik)
        time.sleep(ARALIK)

CSV dosyasındaki verilerden sıcaklık grafiği oluşturur.

grafik.pyPython
# Kaydedilen verilerden grafik çizme
import csv
from datetime import datetime
import matplotlib.pyplot as plt

zamanlar = []
sicakliklar = []

with open("sicaklik_kaydi.csv") as f:
    for satir in csv.DictReader(f):
        zamanlar.append(datetime.fromisoformat(satir["zaman"]))
        sicakliklar.append(float(satir["sicaklik_c"]))

plt.figure(figsize=(10, 4))
plt.plot(zamanlar, sicakliklar, color="tab:red", linewidth=2)
plt.title("Oda sicakligi")
plt.xlabel("Zaman")
plt.ylabel("Sicaklik (C)")
plt.grid(alpha=0.3)
plt.tight_layout()
plt.savefig("sicaklik_grafigi.png", dpi=120)

print(f"{len(sicakliklar)} olcum cizildi.")
print(f"En dusuk: {min(sicakliklar):.2f} C  En yuksek: {max(sicakliklar):.2f} C")

Kod açıklaması

glob.glob("/sys/bus/w1/devices/28-*")

Adı 28- ile başlayan klasörleri bulur. DS18B20 sensörlerinin seri numarası her zaman 28 ile başlar.

satirlar[0].strip().endswith("YES")

Dosyanın ilk satırı, verinin hatasız gelip gelmediğini gösterir. YES değilse ölçüm bozuktur ve tekrar okunur.

int(...) / 1000.0

Sensör sıcaklığı binde bir derece cinsinden verir: 23125 değeri 23,125 °C demektir.

DOSYA.open("a", newline="")

"a" (append) kipi dosyanın sonuna ekleme yapar; program yeniden başlatılsa bile eski veriler silinmez.

f.flush()

Python veriyi önce bellekte biriktirir. flush() ile her ölçüm anında diske yazılır; elektrik kesilse bile veri kaybolmaz.

csv.DictReader(f)

CSV dosyasının her satırını başlık isimleriyle erişilebilen bir sözlüğe çevirir: satir["zaman"] gibi.

Nasıl çalışır?

1-Wire protokolünde tek bir veri hattı hem veri iletir hem de pull-up direnci sayesinde sensöre güç sağlayabilir. Her DS18B20'nin fabrikada yazılmış 64 bitlik benzersiz bir kimliği vardır; bu yüzden aynı üç kabloya çok sayıda sensör bağlayıp her birini ayrı ayrı okuyabilirsiniz. Sensör -10 ile +85 °C arasında yaklaşık ±0,5 °C hassasiyetle ölçer.

Raspberry Pi'de 1-Wire'ı açtığınızda Linux çekirdeği sensörle konuşma işini üstlenir ve sonucu /sys/bus/w1/devices/ altında sanal bir dosya olarak sunar. Python bu dosyayı okuduğunda çekirdek sensörden yeni bir ölçüm ister. Ölçüm yaklaşık 750 ms sürdüğü için her okuma kısa bir bekleme içerir.

Sorun giderme

28- ile başlayan klasör görünmüyor
1-Wire arayüzünün açık olduğunu ve Pi'yi yeniden başlattığınızı kontrol edin. 4,7 kΩ direnç eksikse sensör algılanmaz.
Sıcaklık sürekli 85.00 görünüyor
85 °C, sensörün açılıştaki varsayılan değeridir. Genellikle güç bağlantısının zayıf olduğunu gösterir; VDD kablosunu kontrol edin.
Sensör elle tutulamayacak kadar ısınıyor
Bacaklar ters bağlanmış. Gücü hemen kesin ve GND ile VDD'nin yerini kontrol edin.
Grafik kodu ModuleNotFoundError veriyor
matplotlib kurulu değil: sudo apt install python3-matplotlib komutunu çalıştırın.

Geliştirme fikirleri

Projeyi tamamladıysanız, aşağıdaki fikirlerle bir adım öteye taşıyabilirsiniz.

Çoklu sensör

İkinci bir DS18B20'yi aynı hatta bağlayıp iç ve dış sıcaklığı birlikte kaydedin.

Alarm

Sıcaklık belirli bir değeri geçince LED yakan veya buzzer öttüren bir uyarı ekleyin.

Akvaryum takibi

Su geçirmez probu akvaryuma yerleştirip suyun sıcaklığını günlerce izleyin.

Canlı web paneli

Flask ile son ölçümü ve grafiği telefondan görebileceğiniz bir sayfa yapın.

Sık sorulan sorular

DHT11 yerine neden DS18B20 kullandık?
DHT11 ve DHT22 sensörleri hassas zamanlama ister ve Raspberry Pi'de, özellikle Pi 5'te, kütüphane sorunlarına yol açabilir. DS18B20 ise Linux tarafından doğrudan desteklenir ve ek kütüphane gerektirmez.
Kaydediciyi kapattığımda veriler silinir mi?
Hayır. Dosya "a" kipinde açıldığı için her çalıştırmada yeni ölçümler mevcut verilerin sonuna eklenir.
CSV dosyasını Excel'de açabilir miyim?
Evet. Dosyayı bilgisayarınıza kopyalayıp Excel veya Google E-Tablolar ile açabilirsiniz. Türkçe Excel'de ondalık ayırıcı farkı nedeniyle Veri › Metin/CSV'den içe aktarmak daha sağlıklı sonuç verir.

Bir sonraki projeye hazır mısınız?

Raspberry Pi serisindeki 5 projeyi tamamladığınızda GPIO, kamera, sensör verisi ve web sunucusu ile çalışmanın temellerini öğrenmiş olursunuz.

Raspberry Pi projelerine dön