Přejít k hlavnímu obsahu

DS18B20 na Raspberry Pi 5: zapojení a čtení teploty

DS18B20 lze použít pro jednoduché čtení teploty přes rozhraní 1-Wire. Tento návod popisuje zapojení jednoho čidla k Raspberry Pi 5, kontrolu jeho detekce a Python, který při chybě nevydává neplatná data za naměřenou teplotu.

Rozsah ověření

Aktualizace 14. 10. 2026: zapojení a rozhraní jsou zkontrolované podle dokumentace výrobce a Linuxu. Python prošel syntaktickými a simulovanými testy platných dat, chybného CRC, chybějícího čidla a selhání čtení. Fyzické zapojení na Raspberry Pi 5 a skutečné měření tímto postupem zatím nebyly redakčně otestované. Nejde o praktickou recenzi ani o ověřený systém pro ochranu skladu.

Co budete potřebovat

  • Raspberry Pi 5 s podporovaným Raspberry Pi OS a přístupem do terminálu.
  • DS18B20 s dohledatelným označením vývodů, nepájivé pole a krátké propojovací vodiče.
  • Rezistor 4,7 kΩ pro pull-up datové linky.

Začněte instalací Raspberry Pi OS a bezpečným prvním spuštěním, pokud systém ještě nemáte. Tento příklad používá samostatně napájené třívodičové čidlo, nikoli parazitní napájení. U hotového modulu nejprve ověřte jeho schéma, požadované napětí a vestavěný rezistor; tabulku nelze slepě přenést na libovolný modul.

Zapojení na 3,3 V

Nejdřív Raspberry Pi vypněte a odpojte napájení. Zkontrolujte orientaci 40pinového konektoru. Číslo GPIO není číslo fyzického pinu. Níže uvedené zapojení je pro krátkou sběrnici s jedním externě napájeným čidlem.

Vývod čidla Připojení na Raspberry Pi 5
VDD 3,3 V, fyzický pin 1
GND Zem, fyzický pin 6
DQ GPIO4, fyzický pin 7
Pull-up rezistor 4,7 kΩ Mezi DQ a 3,3 V; ne do série s DQ
Tabulka zapojení, nikoli fotografie ověřené sestavy.

Datový GPIO nepřipojujte k 5 V a pull-up neveďte na 5 V. V tomto příkladu je napájení čidla i pull-up na 3,3 V. Vývody čidla ověřte v datasheetu pro konkrétní pouzdro; barvy kabelů zapouzdřených sond nejsou univerzální. Dlouhé kabely a více čidel vyžadují samostatné ověření sběrnice. Popis GPIO a napětí uvádí Raspberry Pi, napájení a pull-up datasheet DS18B20.

Zapnutí 1-Wire

  1. Po kontrole zapojení připojte napájení a spusťte sudo raspi-config.
  2. V nabídce rozhraní zapněte 1-Wire. V aktuální dokumentaci je to Interface Options → I7 1-Wire; položky se mohou mezi verzemi lišit.
  3. Ukončete nástroj a restartujte Raspberry Pi. Po restartu ověřte detekci níže.

Použijte jeden způsob konfigurace, nepřidávejte zároveň duplicitní overlay. Pokud kontrolujete soubor ručně, Raspberry Pi OS Bookworm a novější používá /boot/firmware/config.txt; starší návody s /boot/config.txt nelze přebírat bez ověření verze. Overlay w1-gpio standardně používá GPIO4. Firmware má pro Pi 5 vlastní variantu a mapování; při odlišné instalaci ověřte místní /boot/firmware/overlays/README. Python níže nepřepíná GPIO a nespouští modprobe přes shell.

Detekce a první čtení

ls /sys/bus/w1/devices/
python3 --version

Očekávejte adresář čidla s prefixem 28-. Samotný w1_bus_master1 potvrzuje sběrnici, nikoli přítomnost čidla. Skutečné ID použijte místo ukázkového 28-000000000001:

cat /sys/bus/w1/devices/28-000000000001/w1_slave

Ovladač w1_therm vrací dva řádky: první obsahuje výsledek CRC YES nebo NO, druhý údaj t= v tisícinách stupně Celsia. Například t=23125 odpovídá 23,125 °C. Při NO údaj neberte jako nové platné měření. Chování rozhraní popisuje dokumentace Linuxu.

Python s ošetřením chyb

Uložte celý následující kód jako ds18b20.py, včetně odsazení. Používá pouze standardní knihovnu Pythonu 3. Nic neinstaluje a pro běžné čtení nepoužívá sudo. Pokud jsou práva v systému jiná, zjistěte jejich příčinu; nedávejte plošná oprávnění 777.

#!/usr/bin/env python3
"""Read a DS18B20 via Linux w1_therm; no GPIO writes or module loading."""
import argparse
from pathlib import Path
import re
import sys
import time


class SensorError(Exception):
    pass


def select_sensor(base, sensor_id=None):
    if sensor_id is not None:
        if not re.fullmatch(r"28-[0-9a-fA-F]{12}", sensor_id):
            raise SensorError("ID musí mít tvar 28-xxxxxxxxxxxx (12 hex znaků).")
        device = base / sensor_id / "w1_slave"
        if not device.is_file():
            raise SensorError("Zvolený senzor nebyl nalezen.")
        return device
    devices = sorted(base.glob("28-*/w1_slave"))
    if not devices:
        raise SensorError("DS18B20 nebyl nalezen; ověřte zapojení a 1-Wire.")
    if len(devices) != 1:
        raise SensorError("Nalezeno více senzorů; zadejte ID konkrétního čidla.")
    return devices[0]


def parse_temperature(raw):
    lines = raw.splitlines()
    if len(lines) != 2 or not lines[0].split() or lines[0].split()[-1] != "YES":
        raise SensorError("Neúplná odpověď nebo nesouhlasí CRC.")
    octets = lines[0].split()[:9]
    if len(octets) != 9 or not all(re.fullmatch(r"[0-9a-fA-F]{2}", x) for x in octets):
        raise SensorError("Neplatná data senzoru.")
    if all(x.lower() == "00" for x in octets) or all(x.lower() == "ff" for x in octets):
        raise SensorError("Prázdná data senzoru.")
    match = re.search(r"(?:^|\s)t=(-?\d+)\s*$", lines[1])
    if match is None:
        raise SensorError("V odpovědi chybí platná teplota.")
    value = int(match.group(1)) / 1000
    if not -55 <= value <= 125:
        raise SensorError("Hodnota je mimo rozsah DS18B20.")
    return value


def read_temperature(device, attempts=3, delay=0.2):
    for attempt in range(attempts):
        try:
            return parse_temperature(device.read_text(encoding="ascii"))
        except (OSError, UnicodeError, SensorError) as error:
            if attempt == attempts - 1:
                raise SensorError("Čtení selhalo po třech pokusech: " + str(error)) from error
            time.sleep(delay)


def main():
    parser = argparse.ArgumentParser(description="Jedno čtení teploty DS18B20.")
    parser.add_argument("sensor_id", nargs="?", help="např. 28-000000000001")
    args = parser.parse_args()
    try:
        device = select_sensor(Path("/sys/bus/w1/devices"), args.sensor_id)
        value = read_temperature(device)
    except (OSError, SensorError) as error:
        print("Chyba: " + str(error), file=sys.stderr)
        return 2
    print(f"{device.parent.name}: {value:.3f} °C")
    return 0


if __name__ == "__main__":
    sys.exit(main())
python3 ds18b20.py
python3 ds18b20.py 28-000000000001

První příkaz vybere čidlo pouze tehdy, je-li nalezeno právě jedno. U více čidel druhým příkazem zadejte skutečné ID konkrétní sondy. Při neúspěchu skončí program s kódem 2 a zprávou na chybovém výstupu, bez teploty. Počet opakování čtení je omezen na tři; není zde nekonečná smyčka čekající na CRC. Tento limit neřeší případné zablokování uvnitř ovladače operačního systému.

Když čidlo nefunguje

  • Není adresář 28-: zkontrolujte zapnutí 1-Wire a restart. Před jakoukoli úpravou vodičů znovu vypněte a odpojte Raspberry Pi; ověřte GND, DQ, rezistor i orientaci čidla.
  • CRC je NO nebo čtení selže: neukládejte hodnotu jako platnou teplotu. Zkontrolujte kontakty a délku vodičů. Opakované chyby nejprve řešte na krátké sběrnici s jedním čidlem.
  • Opakovaných 85 °C po zapnutí: prověřte napájení a dokončení převodu. Je to také počáteční hodnota DS18B20; samotné číslo ale nedokazuje závadu, protože 85 °C může být skutečná teplota.
  • Více čidel: zapisujte si jejich ID a přiřazení k místu měření. Pořadí adresářů není identifikace místnosti.

Co tento příklad ještě nedělá

Program provede jedno čtení a výpis. Nevytváří upozornění, historii, ovládání topení ani vzdálený dohled. Rozlišení čísla na výstupu není zárukou přesnosti celé sestavy. Pro důležité sledování teploty potřebujete ověřit skutečnou sondu, umístění, výpadky napájení a chyby přenosu; tento výukový příklad nenahrazuje bezpečnostní ani certifikované měřicí zařízení.

Pro samostatný projekt chytré domácnosti pokračujte bezpečným začátkem s Home Assistantem. Tento skript není hotová integrace Home Assistantu. Další související texty najdete v rubrice Projekty.

Zdroje

Napsat komentář