Seri Protokoller
TEKNİK REHBER SERİ PROTOKOLLER 1-Wire 2026

1-Wire protokolü
ve DS18B20.

Tek telden onlarca sensör — hepsi seri, hepsi kendi 64-bit ROM koduyla ayrılmış. w1_gpio driver ve /sys/bus/w1/ ile sıcaklık okuma.

00 1-Wire protokolü temelleri

1-Wire — Dallas Semiconductor (şimdi Maxim/Analog Devices) tarafından geliştirilen, tek tel üzerinden hem güç hem de veri taşıyan seri protokol.

  SoC GPIO pin              1-Wire Bus (DQ)
       │                         │
       ├── 4.7 kΩ ──── VCC      ─┤─ DS18B20 (0x28-XXXXXXXXXXXX)
       │                         │─ DS18B20 (0x28-YYYYYYYYYYYY)
       │                         │─ DS18B20 (0x28-ZZZZZZZZZZZZ)
       │                         │
       GND ─────────────────────── GND (tüm sensörler)
    

Temel özellikler

Tek tel (DQ)Veri ve optionally güç aynı hattan taşınır. Ground hattı hariç sadece bir sinyal teli gerekir.
Parasite powerSensörler harici güç kaynağı olmadan DQ hattının pull-up kapasitöründen beslenebilir. Ayrı VCC bağlantısı olmadan çalışır, fakat bazı kısıtlamalar getirir.
ROM kod (64-bit)Her cihazın fabrikada programlanan benzersiz 64-bit tanımlayıcısı. 8-bit family code + 48-bit serial number + 8-bit CRC.
Reset/presence pulseHer transaction reset pulse ile başlar: master DQ'yu 480µs düşürür, bırakır. Cihazlar 15-60µs sonra presence pulse göndererek varlıklarını bildirir.
HızStandard: ~15 kbps. Overdrive mode: ~125 kbps. Uzun kablo için standard mod kullanılır.

ROM kod yapısı

BitAlanAçıklama
[7:0]Family codeCihaz tipi. DS18B20 = 0x28, DS18S20 = 0x10, DS2431 (EEPROM) = 0x2D
[55:8]Serial number48-bit benzersiz seri numara
[63:56]CRCİlk 56 bitin CRC-8 doğrulama değeri

Temel komutlar

KomutHexAçıklama
Search ROM0xF0Bus'taki tüm cihazların ROM kodlarını keşfet
Read ROM0x33Tek cihaz varsa ROM kodunu oku (multi-drop'ta kullanılmaz)
Match ROM0x5564-bit ROM kodu ile belirli bir cihazı seç
Skip ROM0xCCTüm cihazlara broadcast. Tek cihaz veya eş zamanlı dönüşüm için.
Convert T0x44DS18B20: sıcaklık dönüşümünü başlat
Read Scratchpad0xBEDS18B20: 9-byte scratchpad belleği oku

01 Linux w1 subsystem

Linux'ta 1-Wire desteği w1 (wire-one) subsystem üzerinden sağlanır. w1_gpio driver, herhangi bir GPIO pinini 1-Wire bus master olarak kullanır.

  Userspace      /sys/bus/w1/devices/28-xxxxxxxxxxxx/w1_slave
                              │
  Kernel         w1_therm driver   (DS18B20 family)
                              │
                     w1 bus master (wire1.c)
                              │
                      w1_gpio driver
                              │
                    GPIO pin (kernel GPIO API)
    

Kernel yapılandırması

kernel config
CONFIG_W1=y                   # 1-Wire subsystem
CONFIG_W1_MASTER_GPIO=y       # GPIO tabanlı master
CONFIG_W1_SLAVE_THERM=y       # DS18B20 / DS18S20 / DS1822 / DS28EA00
CONFIG_W1_SLAVE_DS2431=m      # DS2431 EEPROM (opsiyonel)

Device Tree tanımı

device-tree.dts
/ {
    onewire: w1 {
        compatible = "w1-gpio";
        gpios = <&gpio 4 0>;         /* GPIO4, active-high */
        pinctrl-names = "default";
        pinctrl-0 = <&w1_pins>;
    };
};

&gpio {
    w1_pins: w1_pins {
        brcm,pins = <4>;
        brcm,function = <0>;         /* GPIO input */
        brcm,pull = <0>;             # pull none (harici 4.7kΩ var) */
    };
};

Raspberry Pi'da etkinleştirme

/boot/config.txt (Raspberry Pi)
# 1-Wire GPIO4 üzerinde etkinleştir:
dtoverlay=w1-gpio

# Farklı pin (GPIO2) kullanmak için:
dtoverlay=w1-gpio,gpiopin=2

# Parasite power desteği:
dtoverlay=w1-gpio,pullup=on
bash — modül yükleme ve kontrol
# Modülleri yükle (=m ise):
sudo modprobe w1-gpio
sudo modprobe w1-therm

# Yüklenen modülleri kontrol et:
lsmod | grep w1

# Kernel mesajlarını izle:
dmesg | grep w1
# [ 5.2] Driver for 1-wire Dallas network protocol.
# [ 5.3] gpio-4 (w1): device address: 28-00000xxxxxx

# w1 bus master durumu:
ls /sys/bus/w1/devices/
# 28-00000xxxxxxx  w1_bus_master1

02 /sys/bus/w1/devices/ arayüzü

Kernel, 1-Wire cihazlarını /sys/bus/w1/devices/ altında ROM kodu ile adlandırarak gösterir.

bash
# Tüm 1-Wire cihazlarını listele:
ls /sys/bus/w1/devices/
# 28-00000a123456  28-00000b789abc  w1_bus_master1

# ROM kodu formatı: {family_code}-{48bit_serial}
# 28 → DS18B20 family code
# 00000a123456 → 48-bit seri numarası (hex, 6 bayt)

# Belirli cihazın dosyalarını gör:
ls /sys/bus/w1/devices/28-00000a123456/
# driver  id  name  power  subsystem  uevent  w1_slave

# Cihaz adı (family):
cat /sys/bus/w1/devices/28-00000a123456/name
# 28-00000a123456

# w1_bus_master1 altında tarama ayarları:
ls /sys/bus/w1/devices/w1_bus_master1/
# max_slave_count  search_count  slave_count  timeout  w1_master_name

# Bağlı cihaz sayısı:
cat /sys/bus/w1/devices/w1_bus_master1/slave_count
# 2
NOT

w1 driver, bağlı cihazları otomatik olarak yaklaşık her 10 saniyede bir tarar. Yeni bir sensör takıldığında /sys/bus/w1/devices/ altında otomatik olarak görünür. Tarama sıklığını /sys/bus/w1/devices/w1_bus_master1/timeout dosyasına yazarak değiştirebilirsin (saniye cinsinden).

03 DS18B20 okuma — w1_slave dosyası

w1_therm driver, sıcaklık ölçümü ve ham veriyi w1_slave dosyası üzerinden sunar.

bash
# w1_slave dosyasını oku:
cat /sys/bus/w1/devices/28-00000a123456/w1_slave
w1_slave dosyası çıktısı
50 05 4b 46 7f ff 0c 10 1c : crc=1c YES
50 05 4b 46 7f ff 0c 10 1c t=21312

Çıktı formatını yorumlayalım:

50 05 4b 46 7f ff 0c 10 1cDS18B20 scratchpad belleğinin 9 baytı (hex). Byte0-1: sıcaklık, Byte2-3: alarm eşiği, Byte4: configuration, Byte5-7: reserved, Byte8: CRC.
crc=1c YESCRC-8 hesaplanan değer ve doğrulama durumu. YES=CRC doğru, NO=veri bozuk. NO ise okumayı tekrarla.
t=21312Sıcaklık değeri: 1/1000 °C cinsinden. 21312 → 21.312 °C. Doğrudan kullanılabilir.
bash — sıcaklık oku
# Sıcaklığı tek satırda oku:
awk '/YES/{found=1} found{match($0,/t=([0-9-]+)/,a); if(a[1]!="") printf "%.3f C\n", a[1]/1000; exit}' \
  /sys/bus/w1/devices/28-00000a123456/w1_slave
# 21.312 C

# CRC hatasını filtrele:
awk '/YES/{found=1} found{match($0,/t=([0-9-]+)/,a); if(a[1]!="") printf "%.3f\n", a[1]/1000}' \
  /sys/bus/w1/devices/28-00000a123456/w1_slave

# Sürekli izleme (her 2 saniye):
while true; do
  cat /sys/bus/w1/devices/28-00000a123456/w1_slave | \
    grep 't=' | awk -F'=' '{printf "%.3f C\n", $2/1000}'
  sleep 2
done

temperature dosyası (daha yeni kernel'lar)

Linux 5.0+ kernel'larda w1_therm driver, temperature adında ek bir sysfs dosyası sunar:

bash
# Doğrudan sıcaklık (millidegree Celsius):
cat /sys/bus/w1/devices/28-00000a123456/temperature
# 21312

# Python tarzı hesap:
echo "$(cat /sys/bus/w1/devices/28-00000a123456/temperature) / 1000" | bc -l
# 21.312

04 Birden fazla sensör

1-Wire'ın en güçlü özelliği: tüm sensörler aynı iki teli (DQ + GND) paylaşır, her biri ROM kodu ile ayrılır.

bash — tüm sensörleri tara ve oku
# Tüm DS18B20 sensörlerini bul ve oku:
for sensor in /sys/bus/w1/devices/28-*/; do
    id=$(basename "$sensor")
    raw=$(cat "${sensor}w1_slave" 2>/dev/null)

    # CRC kontrolü:
    if echo "$raw" | grep -q "YES"; then
        temp=$(echo "$raw" | grep 't=' | awk -F'=' '{printf "%.3f", $2/1000}')
        echo "$id : ${temp} °C"
    else
        echo "$id : CRC HATASI"
    fi
done
# 28-00000a123456 : 21.312 °C
# 28-00000b789abc : 23.875 °C
# 28-00000c001122 : 19.500 °C

Parasite power ile 4.7 kΩ pull-up önemi

Parasite power modunda DS18B20, DQ hattının yüksek seviyesinden enerji depolar. Sıcaklık dönüşümü sırasında (~750ms) DQ hattından yüksek akım çekilir. Bu nedenle:

  • 4.7 kΩ pull-up direnci kesinlikle gereklidir. Daha büyük direnç (10 kΩ) yeterli akımı sağlayamaz ve dönüşüm başarısız olur.
  • Parasite power ile birden fazla sensör kullanırken güç yetersizliği daha belirgin olur. 3 veya daha fazla sensör için ayrı VCC bağlantısı önerilir.
  • Ayrı VCC kullanıldığında 4.7 kΩ pull-up hâlâ gereklidir (bus sinyalizasyonu için).
Bağlantı tipiSensör sayısıPull-upNot
Parasite power1-34.7 kΩ → 3.3V veya 5VSadece DQ + GND gerekir
Parasite power4+4.7 kΩ + güçlendirilmiş sürücüSorunlu, ayrı VCC önerilir
Ayrı VCC (3.3V)Sınırsız (pratikte 32)4.7 kΩ → 3.3VÖnerilen bağlantı

05 Python ile DS18B20 okuma

İki yöntem: hazır w1thermsensor kütüphanesi veya doğrudan dosya parse.

w1thermsensor kütüphanesi

bash — kurulum
pip3 install w1thermsensor
w1thermsensor_example.py
from w1thermsensor import W1ThermSensor, Sensor

# Tüm sensörleri bul:
for sensor in W1ThermSensor.get_available_sensors():
    print(f"ID: {sensor.id}  Tip: {sensor.name}")
    print(f"  Sıcaklık: {sensor.get_temperature():.3f} °C")
    print(f"  Fahrenheit: {sensor.get_temperature(W1ThermSensor.DEGREES_F):.3f} °F")

# Belirli bir sensörü ID ile bul:
sensor = W1ThermSensor(sensor_type=Sensor.DS18B20, sensor_id="00000a123456")
temp = sensor.get_temperature()
print(f"Belirli sensör: {temp:.2f} °C")

# Çözünürlük ayarı (9, 10, 11, 12 bit):
sensor.set_precision(12)
print(f"12-bit çözünürlük: {sensor.get_temperature():.4f} °C")

Ham dosya parse (kütüphanesiz)

ds18b20_raw.py
import os
import glob
import time

W1_BASE = "/sys/bus/w1/devices"

def find_sensors():
    """28-* ile başlayan tüm cihaz dizinlerini bul."""
    return glob.glob(os.path.join(W1_BASE, "28-*"))

def read_temp(device_path, retries=3):
    """w1_slave dosyasını parse et, CRC hatasında tekrar dene."""
    w1_file = os.path.join(device_path, "w1_slave")

    for attempt in range(retries):
        try:
            with open(w1_file, "r") as f:
                lines = f.readlines()

            if len(lines) < 2:
                raise ValueError("Yetersiz satır")

            # Satır 1: "xx xx xx ... : crc=xx YES/NO"
            if "YES" not in lines[0]:
                if attempt < retries - 1:
                    time.sleep(0.1)
                    continue
                raise ValueError(f"CRC hatası (deneme {attempt+1}/{retries})")

            # Satır 2: "xx xx ... t=NNNNN"
            pos = lines[1].find("t=")
            if pos == -1:
                raise ValueError("t= bulunamadı")

            raw_temp = int(lines[1][pos+2:].strip())
            return raw_temp / 1000.0   # °C

        except OSError as e:
            raise IOError(f"Dosya okuma hatası: {e}")

    raise ValueError("Tüm denemeler başarısız")

sensors = find_sensors()
if not sensors:
    print("Hiç DS18B20 bulunamadı. Bağlantı ve modül yüklemesini kontrol et.")
else:
    for s in sensors:
        name = os.path.basename(s)
        try:
            temp = read_temp(s)
            print(f"{name}: {temp:.3f} °C")
        except (ValueError, IOError) as e:
            print(f"{name}: HATA — {e}")

06 Dönüşüm hesaplama

w1_slave dosyasındaki t= değeri kernel tarafından hesaplanmış °C×1000 değeridir. Ancak ham scratchpad verisini kendin parse etmek istersen dönüşüm formülü şöyledir.

DS18B20 çözünürlük ve dönüşüm süresi

ÇözünürlükBitAdım (°C)Dönüşüm süresi (maks.)
9-bitConfiguration=0x1F0.5 °C93.75 ms
10-bitConfiguration=0x3F0.25 °C187.5 ms
11-bitConfiguration=0x5F0.125 °C375 ms
12-bit (varsayılan)Configuration=0x7F0.0625 °C750 ms
ds18b20_manual.py — scratchpad parse
def parse_scratchpad(hex_bytes_str):
    """
    w1_slave'nin birinci satırındaki hex baytlarını parse et.
    Örnek: "50 05 4b 46 7f ff 0c 10 1c"
    """
    raw = [int(x, 16) for x in hex_bytes_str.strip().split()]
    if len(raw) != 9:
        raise ValueError(f"Beklenen 9 bayt, alınan {len(raw)}")

    # CRC-8 doğrulama (Dallas/Maxim CRC8):
    crc = 0
    for byte in raw[:8]:
        for _ in range(8):
            bit = (crc ^ byte) & 1
            crc >>= 1
            if bit:
                crc ^= 0x8C
            byte >>= 1
    if crc != raw[8]:
        raise ValueError(f"CRC hatası: hesaplanan=0x{crc:02X} beklenen=0x{raw[8]:02X}")

    # Sıcaklık hesabı (Byte0=LSB, Byte1=MSB):
    temp_raw = (raw[1] << 8) | raw[0]

    # İşaretli 16-bit integer (two's complement):
    if temp_raw > 32767:
        temp_raw -= 65536

    temp_c = temp_raw / 16.0   # 12-bit için ÷16 (0.0625°C adım)

    # Yapılandırma register'dan çözünürlük al:
    resolution_bits = 9 + ((raw[4] >> 5) & 0x03)
    # Byte4[6:5]: 00=9bit, 01=10bit, 10=11bit, 11=12bit

    # Düşük bitler çözünürlüğe göre anlamsızdır, maskele:
    mask = {9: 0xFFF8, 10: 0xFFFC, 11: 0xFFFE, 12: 0xFFFF}
    temp_raw_masked = temp_raw & mask[resolution_bits]
    temp_c_final = temp_raw_masked / 16.0

    return {
        "temperature_c"  : temp_c_final,
        "resolution_bits": resolution_bits,
        "alarm_high"     : raw[2],
        "alarm_low"      : raw[3],
    }

# Örnek kullanım:
result = parse_scratchpad("50 05 4b 46 7f ff 0c 10 1c")
print(f"Sıcaklık  : {result['temperature_c']:.4f} °C")
print(f"Çözünürlük: {result['resolution_bits']}-bit")
# Sıcaklık  : 21.3125 °C
# Çözünürlük: 12-bit
NOT

Scratchpad bayt 0-1: 12-bit çözünürlükte 4 bit kesirli kısım içerir (0.0625°C hassasiyet). 9-bit çözünürlükte yalnızca 1 kesirli bit anlamlıdır; kalan 3 bit belirsizdir ve maskelenmelidir. Kernel w1_therm driver her zaman 12-bit varsayılan hassasiyetle okur (yapılandırılmadıkça).

07 Troubleshooting

1-Wire sorunlarının büyük çoğunluğu pull-up eksikliği veya yanlış değeri, parasite power yetersizliği ve CRC hatalarından kaynaklanır.

Hata teşhis adımları

bash — teşhis
# 1) w1 modüllerinin yüklü olduğunu kontrol et:
lsmod | grep w1
# w1_therm    24576  0
# w1_gpio     16384  0
# wire        36864  2 w1_therm,w1_gpio

# 2) Kernel mesajlarını kontrol et:
dmesg | grep -i 'w1\|wire'

# 3) Bus master var mı?
ls /sys/bus/w1/devices/
# Sadece w1_bus_master1 görünüyorsa sensör bulunamıyor demektir.

# 4) Manuel bus tarama zorla:
echo 1 | sudo tee /sys/bus/w1/devices/w1_bus_master1/search

# 5) CRC hata sayısını izle:
while true; do
  result=$(cat /sys/bus/w1/devices/28-*/w1_slave 2>/dev/null | grep 'NO\|YES')
  echo "$(date): $result"
  sleep 1
done
BelirtiOlası nedenÇözüm
/sys/bus/w1/devices/ boş (sadece bus_master)Pull-up eksik veya çok büyük, sensör beslenmiyor4.7 kΩ pull-up ekle; VCC bağlantısını kontrol et
Aralıklı CRC hatası (bazen YES, bazen NO)Pull-up yetersiz, kablo çok uzun, EMI4.7 kΩ → 3.3 kΩ değiştir; kablo uzunluğunu kıs
t=85000 (85°C) sabitDönüşüm başlamadı; Convert T komutu verilmediw1_therm modülü sorunlu; modprobe w1_therm tekrar yükle
t=-4096 veya saçma değerParasite power yetersiz akımAyrı VCC bağla; parasite güç kaldır
Birden fazla sensör ama sadece biri görünürAdres çakışması (çok nadir) veya yetersiz pull-upPull-up direncini küçült; timeout süresini artır
UYARI

t=85000 değeri (85°C) DS18B20'nin power-on reset değeridir ve sensörün dönüşüm yapmadan okunduğunu gösterir. Bu değeri gerçek sıcaklık olarak işleme alma. Sürekli 85°C görmek, Convert T komutunun gitmediğine veya parasite power sorununun olduğuna işaret eder.

Parasite power sorunları

Parasite power modunda dönüşüm sırasında (~750ms) DQ hattından tipik olarak 1.5mA'e kadar akım çekilir. DQ hattının 4.7kΩ pull-up ile VCC'den sağlayabileceği akım: (3.3V - 1.2V) / 4700Ω ≈ 450µA. Bu yeterli değildir.

Çözüm: Dönüşüm sırasında DQ hattını güçlü pull-up ile sür. Bazı SoC'lerin GPIO'su push-pull çıkış olarak yapılandırılabilir; bu durumda DQ dönüşüm süresince yüksek tutulabilir. Alternatif olarak harici MOSFET veya doğrudan VCC bağlantısı kullan.