Korábban már bemutattam egy módszert arra, hogy hogyan lehet a Raspberry Pi segítségével kiolvasni egy DS18B20 one wire szenzor jelét. Ebben a leírásban egy másik, egyszerűbb lehetőséget szeretnék bemutatni, amire az ad lehetőséget, hogy az eszközök kezelését végző library-k (pc-s világban úgy mondanánk, hogy driverek) száma hála a linux fejlesztőknek, folyamatosan bővül! Továbbá megnézünk egy módszert arra, hogy a mért érték ne csak a terminál ablakban jelenjen meg, hanem a Python grafikus felületén.

Mire lesz szükségünk?

  • Raspberry Pi
  • DS18B20 one wire szenzor
  • 4,7kΩ-os ún. felhúzó (pull-up) ellenállás
  • breadboard
  • összekötő ún. jumper kábelek

Bekötés

Az érzékelő és a GPIO port összekötése mindössze három vezetéket igényel. Akár a háromlábú tranzisztor tokozású, akár a vezetékes, vízálló verziót használjuk, a bekötés azonos. A szenzor két szélső lába a tápfeszültségre, a középső adat-láb pedig a Pi one wire bemenetére csatlakozik.

A bekötést segíti az alábbi két ábra:

DS18B20 bekötése

A 4,7kohm-os ellenállás az adatláb és a pozitív tápfeszültség közé kerül.

Az érzékelő lekérdezése

A szenzort először egy egyszerű Python kóddal fogjuk lekérdezni, ehhez a következő lépésekre van szükség:

  • a szükséges library letöltése, aminek segítségével lekérdezhetjük a szenzor értékét
  • – a one wire interfész engedélyezése

A w1thermsensor library letöltéséhez nyisd meg a terminál ablakot, majd gépeld be:

sudo pip3 install w1thermsensor

A telepítés után kiléphetsz a terminál ablakból.

Az interfész engedélyezése

A one wire interfészt engedélyezheted a grafikus felületen keresztül, vagy terminál ablakból a

sudo raspi-config

utasítás kiadása után. A grafikus felületen a „Start menü” Tulajdonságok menüpontjának Raspberry Pi Configuration almenüjével tudod beállítani, az itt felugró panel második, „Interfaces” lapfülén. A változtatások érvényesítéséhez újra kell indítani a Pi-t.

Tesztelés

Az összeállítást egy egyszerű tesztprogrammal próbálhatod ki. Ezt a Programozás menüpontban található bármelyik editorban megírhatod, illetve az oldal alján letöltheted.

Bármely Python program könyvtárakat használó projektjének első lépéseként importálnod kell azokat a library-kat, amelyek a program működéséhez szükségesek. Ebben az esetben a „time” könyvtár a szenzor lekérdezésének időzítése, a „w1thermsensor” könyvtár pedig az érzékelővel való kommunikáció működtetése miatt szükséges.

import time
from w1thermsensor import W1ThermSensor

A második lépés a „sensor” objektum létrehozása, így ha az érzékelő aktuális adatát le szeretnénk kérdezni, a W1ThermSensor() kifejezés helyett használhatjuk a „sensor” megnevezést.

sensor = W1ThermSensor()

A lekérdezést másodpercenként fogjuk elvégezni, ehhez ehhez egy „while” ciklust használunk, amit úgy állítunk be, hogy „örökké” fusson:

while True:

Azt ezt követő sorokat behúzással kell kezdeni, a Python értelmező ebből tudja, hogy ezek a sorok a ciklusmag részei. Az első sor lekérdezi a szenzor értékét, és azt egy változóban (temperature) tárolja:

temperature = sensor.get_temperature()

A változóban tárolt értéket a print() függvénnyel tudjuk kinyomtatni. Annak érdekében, hogy a kiírás formázottan jelenjen meg, a %s karakter kombinációt használjuk, hogy a hőfok értéket numerikusból string formátumba konvertáljuk.

print("A hőmérséklet: %s celsius" % temperature)

A program utolsó sora állítja be a kiolvasások közötti időtartamot. Az alábbi esetben ez 1 sec.

time.sleep(1)

A teljes kód:

import time
from w1thermsensor import W1ThermSensor
sensor = W1ThermSensor()

while True:
    temperature = sensor.get_temperature()
    print("A hőmérséklet: %s celsius" % temperature)
    time.sleep(1)

A hőmérséklet szenzor értékének megjelenítése grafikus felületen

Az előző program segítségével a terminál ablakban leolvasható a hőmérséklet. Sokkal elegánsabb azonban az értékeket egy grafikus felületen megjeleníteni. Ehhez a Python tkinter modulját használtam. A mintaprogram jobb megértéséhez előbb vizsgáljuk meg, hogy a Pi hogyan kommunikál a szenzorral!

A DS18B20 digitális hőmérséklet-érzékelők, gyárilag kalibrált szenzorok. Ez azt jelenti, hogy a 3 kivezetéses érzékelő rendelkezik egy beépített elektronikával, amely a tényleges érzékelő jelét (a DS18B20 chip belsejében lévőt) digitális adatokká konvertálja. A Pi az érzékelő adatait ezután az un. one-wire buszon keresztül olvassa le, egy kétirányú digitális kommunikációs buszon, amely csak egy vezetéket igényel. A számítógép parancsot küld a DS18B20-nak, és megmondja neki, hogy indítsa el a mérési ciklust. A DS18B20 ezután visszaküldi az adatokat. A Raspberry PI operációs rendszere tartalmazza azokat a Linux-kernelmodulokat, amelyek kezelik az one-wire protokollt. Egy vagy akár több érzékelő kiolvasásához nyissuk meg a “/ sys / bus / w1 / devices /” elérési út mentén található fájlt, a Raspberry PI ekkor ki tudja olvasni az érzékelő(k) értékét.

A mintaprogram az aktuális hőmérséklet érték mellett a rendszeridőt is megjeleníti a grafikus ablakban:

Hőmérséklet kijelzése grafikus ablakban

A mintaprogram:

#!/usr/bin/python3

#szükséges library-k beimportálása
from tkinter import *
import glob
import time
import datetime

time1 =''

# szenzor címének kiolvasása
sysDir = '/sys/bus/w1/devices/'
w1Device = glob.glob(sysDir + '28*')[0]
w1Slave = w1Device + '/w1_slave'

def readTempDev():
  f = open(w1Slave, 'r') # temperature device file megnyitása olvasásra
  lines = f.readlines() # sorok kiolvasása
  f.close() # file lezárása
  return lines

def readTemp():
  lines = readTempDev() # temperature 'device file' kiolvasása

  while lines[0].strip()[-3:] != 'YES':
    time.sleep(0.2)
    lines = readTempDev()

  tEquals = lines[1].find('t=')

  if tEquals != -1:
    tempValue = lines[1][tEquals+2:]
    #tempCelsius = float(tempValue) / 1000.0
    tempCelsius = round((float(tempValue) / 1000.0), 1)# kerekítés egy tizedesre
    return tempCelsius

# rendszerídő lekérdezése
def tick():
  global time1
  time2=datetime.datetime.now().strftime('%H:%M:%S')
  if time2 != time1:
    time1 = time2
    curTime.config(text=time2)
    curTemp.config(text=readTemp())
  curTime.after(200,tick)
  
# kilépés, ablak lezárása
def ki():
    ablak.destroy()

# grafikus ablak létrehozása
ablak = Tk()
ablak.title('DS18B20')
ablak.geometry("300x150")
time = Label(ablak, text='Idő: ').grid(row=1, column=0, sticky = W)
curTime = Label(ablak, font = ('fixed', 12),)
curTime.grid(sticky = N, row = 1, column = 1, padx = 5, pady = (10,10))
temp = Label(ablak, text='Hőmérséklet: ').grid(row=2, column=0, sticky = W)
curTemp = Label(ablak, font = ('fixed', 12),)
curTemp.grid(sticky = N, row = 2, column = 1, padx = 5, pady = (10,10))
button = Button(ablak, text = "EXIT", command = ki)
button.grid(sticky = N, row = 3, column = 1, padx = 5, pady = (10,10))

tick()
ablak.mainloop()

A fenti forráskód letölthető:

A cikkben használt DS18B20 érzékelő megvásárolható a MálnaPC Webshopjában!