Temperaturövervakning med Raspberry Pi
När det här projektet är klart så har vi en Raspberry Pi som övervakar temperaturen via en DS18B20 temperaturprob (finns att köpa för runt 40-80 kr till varstans). För att larma användaren om att temperaturen har överstigit ett visst gradtal tänds en lysiod. Under tiden programmet körs kan man också se temperaturen direkt på skärmen.
Förberedelser
Vi behöver en Raspberry Pi av valfri version med Raspbian installerat. Raspbian version Jessie eller högre är att rekommendera. Sen behöver vi entrådig kopplingstråd av valfri längd, en lysdiod, två resistorer (en på 4,7 kOhm och en på 220 Ohm), en temperaturprob av modell DS18B20. En kopplingsplatta, eller experimentplatta som det också kallas, är att rekommendera för att koppla upp allting på.
Hårdvaran
Vi börjar med att koppla upp allting innan vi börjar på mjukvara. När vi väl kopplat in hårdvaran är det dags att leta upp temperaturproben i systemet. Så första steget blir att koppla in allting enligt kopplingsschemat här nedan. Här följer också en kort förklaring.
-
Börja med temperaturproben. Koppla ihop VDD och databenet (DQ) med en 4.7 kOhms resistor. Om du köper en färdig mätprob med kabel, så brukar datakabeln vara antingen gul eller vit. VDD är röd och GND är svart.
-
Koppla därefter mätprobens VDD (inspänningen) till första pinnen (P1) på Raspberry Pi:en. P1 på Raspberry Pi:en levererar 3.3V, vilket vår mätprob kräver för att fungera.
-
Koppla nu in GND (minus/jord) från mätproben till pinne 9 på Raspberry Pi:en.
-
Koppla in databenet (DQ) från mätproben till pinne 7 på Raspberry Pi:en. Nu är du klar med inkopplingen av mätproben.
-
Koppla pinne 11 (GPIO7) från Raspberry Pi:en till anoden (det längsta benet) på lysdioden. Koppla det andra benet på lysdioden till en resistor på 220 Ohm.
-
Koppla nu andra änden av resistorn (som är kopplad till lysdioden) till pinne 25 (GND) på Raspberry Pi:en.
Det var allt, nu är allting inkopplat! Kontrollera gärna med kopplingsschemat nedan.
Mjukvaran
Jag använder själv uteslutande Python version 3, därför rekommendarar jag dig
att installera de bibliotek vi behöver för Python 3 och vår Raspberry Pi.
Gör detta med sudo apt-get install python3-rpi.gpio
. Svara ja på frågan om du
vill installera alla beroenden. Detta installerar även Python 3 om du inte redan
har gjort det.
Läsa av temperaturen
Därefter behöver vi aktivera stödet för 1-Wire i Raspberry Pi:en så att vi kan
läsa av temperaturen från proben. Detta gör vi genom att lägga till följande rad
i filen /boot/config.txt
.
dtoverlay=w1-gpio
Det går också bra att aktivera 1-Wire via antingen sudo raspi-config
eller via
det grafiska verktyget i Raspbian.
Därefter måste du starta om Pi:en för att stödet för 1-Wire ska aktiveras. Efter
att du startat om Pi:en är det dags att leta upp ID-numret för just din
temperaturprob. 1-Wire fungerar som så att man kan koppla in i princip hur många
mätprobar som helst till samma ingång. De olika mätprobarna skiljs sedan åt med
ett unikt ID-nummer. För att hitta ID-numret till din mätprob skriv cd
/sys/bus/w1/devices
. Skriv därefter ls
för att lista alla filerna i
katalogen. Den fil som ser ut enligt 28-xxxxx
är din mätprob. Du kan faktiskt
redan nu titta på temperaturen. Skriv cd 28-xxxx
där xxxx är resten av namnet
på mätproben. Skriv sedan cat w1_slave
. Nu ser du temperaturen från
mätproben. Observera att du måste dela temperaturen du ser med 1000 för att få
den i grader. Nu har vi kommit en bra bit på vägen!
Pythonprogrammet för att övervaka och larma
Nu har det blivit dags att göra Pythonprogrammet som övervakar och larmar vid för hög temperatur. Jag visar först hela programmet här och förklarar sedan rad för rad vad som händer i programmet och vad allting är för något.
#!/usr/bin/env python3
import RPi.GPIO as GPIO
import time
# ID-numret på temperaturproben
id = "28-0000066f2e4a"
# Temperaturlarm, förinställt värde
larmtemp = 25.0
# GPIO-inställningar
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BOARD)
GPIO.setup(11, GPIO.OUT)
# Variabel för om lysdioden redan har tänts
alarmset = 0
# Släck lysioden om den redan är tänd
GPIO.output(11, False)
# Vi lägger allt i en try, så om vi avslutar programmet (except) så släcks
# lysdioden igen (se längst ner)
try:
# Vi loopar allting oändligt
while True:
f = open("/sys/bus/w1/devices/" + id + "/w1_slave")
content = f.readlines()
line = content[1]
words = line.split()
tempstr = (words[9])
temp = "%.1f" %(int(tempstr[2:])/1000)
temp = float(temp)
print (temp)
# Här börjar koden för att själva "larmet".
# Om temperaturen är över, eller lika med, förinställt larmvärde,
# OCH lysioden redan tänts.
if (temp >= larmtemp and alarmset == 0):
# Tänd lysdioden
GPIO.output(11, True)
alarmset = 1 # Tala om lysdioden redan har tänts
# Om temperaturen är under förinställt värde OCH lysdioden har tänts
elif (temp < larmtemp and alarmset == 1):
GPIO.output(11, False)
alarmset = 0
# Vänta 3 sekunder mellan varje körning
time.sleep(3)
# Om vi avslutar programmet, vill vi släcka lysdioden
except:
GPIO.output(11, False)
Den första raden, import RPi.GPIO as GPIO
, importerar Python-biblioteket för
Raspberry Pi:ens GPIO portar. Detta gör att vi får en hel del fördefinierade
funktioner för GPIO-portarna, direkt i Python. Rad nummer två, import time
importerar diverse tidsfunktioer i Python. I vårt program använder vi en
funktion som heter sleep()
för att pausa exekveringen av programmet mellan
läsningarna av temperaturen. Den femte raden är en mycket viktig rad, här sätter
vi ID-numret för just din temperaturprob. Ändra detta värde till namnet på den
katalog du såg i /sys/bus/w1/devices/
som började på 28-xxxx.
Därefter följer tre rader som alla börjar med GPIO
. Den första,
setwarnings(False)
stänger av diverse varningar från GPIO-funktionerna i
Python. Den andra setmode(GPIO.BOARD)
talar om för Python att vi vill hänvisa
till GPIO-pinnarna enligt den layout som de fysiska pinnarna sitter i. Här kan
man välja mellan BCM eller BOARD. BCM hänvisar till GPIO-pinnarnas namn. Om du
tittar på kopplingsschemat ovan så ser du att vissa pinnar har ett namn i tukos
färg, t.ex. GPIO11, GPIO17, GPIO22 osv. Det andra systemet, BOARD, som vi
använder i detta projekt, hänvisar istället till de fysiska pinnarnas plats (i
mörkröd färg på kopplingsschemat). Personligen föredrar jag att använda BOARD,
då BCM/GPIO ändrar sig lite från version till version av Raspberry Pi:en. Men
med BOARD kan man inte göra fel, det är alltid samma nummer på pinnarna. Det
enda som skiljer sig mellan version till version i BOARD är att antalet pinnar
blir fler i de nyare versionerna. Dessutom kan man enkelt kontrollera om man
kopplat rätt bara genom att räkna pinnarna på Pi:en.
Den tredje GPIO-raden i koden, setup(11, GPIO.OUT)
talar om att vi vill
använda den elfte pinnen på Pi:en och att denna ska vara i output-mode,
det vill säga vi vill kontrollera något med hjälp av Pi:en, inte tvärtom.
Därefter sätter vi en variabel alarmset
till 0. Denna använder vi sen för att
vi ska veta om lysdioden redan har tänts eller inte. Vi passar också på att
släcka lysdioden ifall den redan är tänd med GPIO.output(11, False)
.
Nu när vi är klara med själva inställningarna för GPIO-pinnarna börjar vi koda
själva programmet. Vi vill i det här programmet läsa in temperaturen vart tredje
sekund, därför börjar vi med while True:
, vilket betyder att vi vill repetera
all koden som är indenterad nedan så länge som True är sant, vilket kommer vara
för evigt. Men innan vi omsluter hela programmet i en while True:
-slinga så
omsluter vi hela programmet i en try
/ except
för att fånga om programmet
avslutas i förväg på grund av något fel. Detta gör så att programmet kan släcka
lysdioden efter sig, oavsett vilken sorts fel som än avbryter programmet. Det är
alltid god att städa upp efter sig och stänga GPIO-portarna.
Därefter läser vi in filen som innehåller temperaturen. Detta gör vi med f =
open("/sys/bus/w1/devices/" + id + "/w1_slave")
. I mitten har vi id vilket är
variabeln som vi satte i början av programmet till ID-numret på
temperaturproben. På nästa rad läser vi in temperaturen, rad för rad, i
variabeln content med content = f.readlines()
. Texten vi vill åt i denna
fil, det vill säga temperaturen, står på andra raden. Därför läser vi rad nummer
två till en variabel som heter line med line = content[1]
(kom ihåg att vi i
programmerings värld börjar räkna från 0, och inte 1). Därefter vill vi komma åt
de enskilda orden på raden, och delar därför upp hela raden i enskilda ord i
variabeln words med words = line.split()
. Nästa steg blir att extrahera
endast temperaturen, vilket är det tioende ordet (9 i programmerings
värld). Detta gör vi med tempstr = (words[9])
.
Nu har vi temperaturen som en sträng i tempstr, inklusive texten “t=”. Nu ska
vi skala bort “t=” samt dela summan med 1000 så att temperaturen blir i grader
Celsius. Vi vill också bara ha temperaturen med en decimal, inte tre. Allt detta
gör vi med raden temp = "%.1f" %(int(tempstr[2:])/1000)
. Det som händer här
är att vi först talar om att vi vill ha resultatet med en decimal
("%.1f"
). Därefter talar vi om att tempstr ska tolkas som ett heltal, och
inte en sträng. I samma sats säger vi också att vi ska börja läsa från det andra
tecknet ([2:]
) fram tills raden är slut. Därefter ska det vi får fram delas
med 1000 så att vi får ett korrekt decimaltal för våra grader. Nu innehåller
variabeln temp ett gradtal i Celcius, t.ex. 23.5. Däremot är temp just nu en
sträng. Vi måste således göra om strängen till ett flyttal så att vi kan göra
aritmetiska jämförelser längre fram. Detta gör vi med temp = float(temp)
.
För att se temperaturen live när vi kör vårt program skriver vi ut temperaturen
med print(temp)
. Nu börjar vi på själva temperaturövervakningen. Detta görs
med stycket nedan.
if (temp >= larmtemp and alarmset == 0):
# Tänd lysdioden
GPIO.output(11, True)
alarmset = 1 # Tala om larmet redan har skickats
## Om temperaturen är under förinställt värde OCH larmet har lösts ut
elif (temp < larmtemp and alarmset == 1):
GPIO.output(11, False)
alarmset = 0
Det som sker här är att vi först jämför om temperaturen är högre än larmtemp
,
i vårt fall 25 grader och alarmset
är satt till noll, det vill säga att
inget larm har skickats ännu. Om så är fallet, så körs koden GPIO.output(11,
True)
vilket tänder lysdioden.
Om temperatren är under (elif
-raden) 25 grader och alarmset
är satt till 1,
det vill säga att lysdioden har tänts, så körs istället
GPIO.output(11, False)
som stänger av lysdioden.
Den allra sista raden, time.sleep(3)
gör att programmet väntar i tre sekunder
innan det körs igen. Hade vi inte haft med denna rad hade programet körts flera
hundra gånger i sekunden och överbelastat vår Raspberry Pi.
Testkör programmet
Testkör nu programmet för att se så att lysdioden tänds när temperaturen överstiger 25 grader. För att testa så brukar jag använda två glas med vatten, ett glas med kallt vatten, och ett med varmt vatten. När du väl vet att allting fungerar kan du gå vidare till nästa steg, att köra programmet i bakgrunden på Pi:en som en tjänst. Mer om detta kommer lite senare i annan artikel.
Om du vill lära dig mer om Python så köp gärna vår bok, Grunderna i programmering, från antingen Bokus, Adlibris, Faktaböcker eller direkt via CyberInfo Sverige.
Nyhetsbrev
Nyhetsuppdateringar från tidningen direkt till din inkorg, helt kostnadsfritt. Avsluta när du vill.
Relaterade artiklar
-
DOSBox för att programmera gamla personsökare
DOSBox kan användas till betydligt mer än bara gamla spel. Ett intressant användningsområde är att kunna använda gamla DOS-program för att programmera diverse enheter över serieporten. Oftast behövs inte ens en serieport, istället går det att använda en USB-serieportsadapter.
-
Ett av mina första nyttoprogram
Vilken nostalgi det var när jag gick igenom programmen på min gamla grafräknare från gymnasiet, en TI-83. Där hittade jag ett av mina första nyttoprogram jag någonsin skrivit. Det var ett program skrivit i ett språk kallat TI-BASIC, en version av Basic för Texas Instruments grafräknare. Året då jag skrev programmet är troligen år 2000 eller 2001.
-
Introduktion till elektronik
Ni har väl inte missat artikelserien Introduktion till elektronik som jag skrivit åt m.nu? Här nedan finns i så fall länkarna till samtliga delar i serien. Det är en kort introduktion till grundläggande elektronik på fem delar. Artiklarna behandlar allt från ellära, Ohms lag och Coulombs formel till lödning, breadboarding och hur mätinstrument fungerar.
-
Titta på seriell data
Denna gång blir det back to basics med en grundläggande förklaring av vad bitar och bytes är och hur dessa bitar ser ut på ett oscilloskop. Vi ska nämligen titta på seriell data med ett oscilloskop och även se hur vi kan “spela in” datan så att vi kan läsa av dataströmmen i efterhand.
Senaste nyheterna och inläggen
-
Avlyssna trafik på servern med Wireshark och TShark
Wireshark är ett ovärderligt verktyg för att felsöka nätverkskonfigurationer, applikationer, API:er, demoner och mycket annat. I kombination med
tshark
kan vi dessutom avlyssna trafiken på en server i realtid. -
Mysig stämning på sommarens första demoparty
I helgen var det Reunion 2024 i Kvidinge Folkets hus, sommarens första skånska demoparty. Partyt organiserades av Jesper “Skuggan” Klingvall. På plats fanns ett 30-tal besökare.
-
Sommarens skånska demopartyn
Årets sommar bjuder på två skånska demopartyn. Först ut är Reunion i Kvidinge den 28–30 juni. Därefter är det Pågadata i Örtofta den 9–11 augusti.
-
Riskerna med BankID som ingen pratar om
BankID är ett säkert och smidigt sätt att identifiera sig online. Men i takt med dess ökade popularitet och användning har det blivit en svag länk – en single point of failure – på mer än ett sätt.
-
Polisernas fängelsedomar står fast
Efter tre år är målet mot de två poliser som olovligen tog sig in i en berusad mans bostad i Landskrona och misshandlade honom klart. Högsta domstolen beslutade den sjätte mars att avvisa överklagan. Fängelsedomarna för poliserna står därmed fast.
Utvalda artiklar
-
Mysig stämning på sommarens första demoparty
I helgen var det Reunion 2024 i Kvidinge Folkets hus, sommarens första skånska demoparty. Partyt organiserades av Jesper “Skuggan” Klingvall. På plats fanns ett 30-tal besökare.
-
Datorparty i Landskrona
I helgen höll Syntax Society sitt årliga sommarparty. Platsen var en källarlokal i Landskrona där ett femtontal personer medverkade.
-
Det första Pågadata har ägt rum
I helgen ägde det första Pågadata rum – uppföljaren till Gubbdata. Platsen var Folkets Hus i Kvidinge. Organisatör av partyt var Johan “z-nexx” Osvaldsson med hjälp från Jesper “Skuggan” Klingvall. Partyt hade över 100 anmälda deltagare.
-
Även hovrätten fäller poliserna för att ha satt dit oskyldig
Hovrätten fastställer straffet för de två poliser som förra året dömdes till vardera ett års fängelse av Lunds tingsrätt för att ha misshandlat och satt dit en oskyldig man. De båda poliserna ska även betala skadestånd till mannen.
-
Retroloppis i Påarp
Idag var det retroloppis hos Andreas Nilsson i Påarp. På baksidan av huset fanns hundratals spel uppradade på långa bord. Trots friska vindar och sval temperatur var loppisen välbesökt.
CyberInfo Sverige är ett it- och medieföretag i nordvästra Skåne som tillhandahåller böcker, utbildningar, nyheter och konsulttjänster inom Linux, säkerhet och programmering.
CyberInfo Sverige är godkänd för F-skatt, är momsregistrerat och innehar
utgivningsbevis för webbplatsen www.cyberinfo.se.