Měření teploty pomocí 1-wire teploměrů a RaspberryPi

Přestože návodů na zprovoznění 1-wire teploměrů založených na DS18B20 je plný internet, myslím si, že praktické zkušenosti s více teploměry a následným zpracování dat se mohou hodit.

Čip DS18B20

Teploměry založené na čipu DS18B20 jsou velice populární především kvůli možnosti zapojit na jeden datový vodič množství teploměrů a dalších čipů podporujících 1-wire. V praxi je sice možné použít parazitické napájení a tím pádem mít pouze datový vodič a zemní vodič (více třeba zde), ale toto zapojení není příliš spolehlivé.

Čidlo DS18B20 s konektorem RJ45

Já jsem ve své instalaci využil tato čidla dodávaná jako součást platformy UniPi. Jedná se o vodotěsné teploměry s kabelem a nakrimpovaným RJ45 konektorem. Přestože čidla jsou výrazně dražší než čínské sety 10 za 1$, ale všechna čidla, která mám při umístění na stejné místo ukáží na desetinu stejnou teplotu, což u čínských odpadů z výroby nemusí být pravda. Výhoda je, že čidla jsou zapojeny čtyřmi vodiči (+5V, GND, 2x data), přičemž oba datové vodiče (žlutý a černý) jsou v pouzdře propojeny:

Díky tomu je možné vytvořit 1-wire kruhovou topologii, přestože fyzicky se jedná o hvězdu. Při propojování sousedních čidel propojím pin 7 s pinem 6 následujícího čidla. Je také možné použít rovnou 1-wire hub, který toto projení zrealizuje. Kruhová topologie přináší vyšší spolehlivost oproti hvězdicové, ve které při delších vedená nastává množství odrazů a spolehlivost 1-wire komunikace jde rapidně dolů.

Připojení k RaspberryPi

Předpokládejme, že čidla máme propojena. Nyní jak vše připojit k RaspberryPi? Jedna z možností je použít dedikovaný I2C řadič, elegantnější cesta a pro připojení teploměrů zcela jistě vyhovující je však možnost připojit 1-wire přímo na GPIO piny našeho Raspberry:

 

Připojení čidel DS18B20 k RaspberryPi

Je vidět, že senzory jsou napájeny +5V, jeden konec logické kružnice je připojen na GPIO pin 4 (žlutý vodič z pinu 7 konektoru RJ45), druhý konec (černý vodič z pinu 5) pak přes pull-up rezistor na +5V. Hodnotu pull-up rezistoru je dobré určit experimentálně tak, aby byla spolehlivě čtena všechna čidla. U mě byla rozumná hodnota 4k7.

Software

Nyní již bychom měli být schopni přečíst teploty poskytované jednotlivými teploměry. Nejprve je nutné si nakonfigurovat Linux na vašem RaspberryPi. Do souboru /boot/config.txt přidáme řádek:

dtoverlay=w1-gpio

Dále načteme jaderné moduly pro 1-wire, buď z konzole, permanentně například přidáním následujících řádek do souboru /etc/rc.local (to můžeme vypustit sudo před příkazy):

sudo modprobe w1-gpio
sudo modprobe w1-therm

Nyní se přepneme do adresáře /sys/bus/w1/devices/, kde jsou pro každé 1-wire zařízení symlinky na adresáře ve tvaru:

28-0000074b914c
28-0000074bcf7a
28-0000074be7b1
28-0000074c293a
28-0000074c6fcd
28-0000074cd977
28-000007c22404
28-000007c2951b
w1_bus_master1

Název každého podadresáře (symlinku) obsahuje jednoznačný identifikátor vypálený v každém DS18B20. Data pak čteme z těchto podadresářů z textového souboru w1_slave, například pomocí následující dvojice Python funkcí:

def read_w1_temp(id):
    fn = '/sys/devices/w1_bus_master1/{}/w1_slave'.format(id)
    try:
        with file(fn) as fr:
            data = fr.read()
            return data
    except (OSError, IOError):
        return None

def parse_w1_temp(w1_data):
    w1_data = w1_data.splitlines()
    line0 = w1_data[0].strip()
    if not line0.endswith('YES'):
        return None

    line1 = w1_data[1].strip()
    temp = line1.split('t=')[1]
    temp = float(temp)/1000.
    return temp

První z funkcí přečte data pro dané ID teploměru, navrácená data pak zpracuje druhá funkce, která v případě, že přečtená data jsou platná vrátí výslednou teplotu jako float.

Závěr

Postavit síť 1-wire teploměrů není nic složitého, ale je třeba dbát na množství detailů – především dodržet kruhovou topologii sítě a použít kvalitní čidla.

Můžete si také přečíst můj předchozí příspěvek o chytře postaveném hloupém domu. A pokud máte další zkušenosti, podělte se o ně na Twitteru: