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:
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:
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!