|
Raspberry Pi
24) Čidlo atmosférického tlaku BMP180
(BMP085)
Další čidlo, které jsem k Raspíčku připojil a zprovoznil, je modul
pro měření atmosférického tlaku s čipem BMP180.
Katalogový list čipu je tady: http://www.bosch-sensortec.com/content/language1/downloads/BST-BMP180-DS000-08.pdf
Připojení je opět na sběrnici I2C, takže stačí pouze 4 dráty:
Modul BMP180 |
RasPI |
Piny na konektoru GPIO |
Vcc |
+3,3V |
1 |
GND |
GND |
6 |
SDA |
SDA |
3 |
SCL |
SCL |
5 |
Na desce není možné upravit I2C adresu. Natvrdo je
ta adresa nastavená na 0x77.
Ovládací program jsem vytvořil v Pythonu. I tady využívám
doplněk SMBUS pro snadné ovládání I2C sběrnice Pokud
ho nemáte nainstalovaný od minule, tak ho v terminálu nainstalujte takto:
sudo apt-get install python-smbus |
Spouštění měření i čtení hodnot příslušných registrů je velice jednoduché.
Větší
problém byl s výpočtem tlaku.
K hodnotám z měřících registrů se totiž musely připočítat ještě různé
kalibrační konstanty.
Postupoval jsem podle algoritmu v katalogovém listu.
Občas jsem měl problémy
s různými datovými typy (unsigned short, long, float...), ale nakonec jsem to
snad dal dohromady správně. Tady je ten program:
#!/usr/bin/python
# -*- encoding: utf-8 -*-
import smbus
import time
import datetime
bus = smbus.SMBus(0)) # starsi varianta RasPi (256MB)
#bus = smbus.SMBus(1) # novejsi varianta RasPi (512MB)
addr = 0x77 # i2c adresa cidla tlaku
# precteni kalibracnich konstant z cipu
ac1 = (bus.read_byte_data(addr,0xaa) * 256) + bus.read_byte_data(addr,0xab)
ac2 = (bus.read_byte_data(addr,0xac) * 256) + bus.read_byte_data(addr,0xad)
ac3 = (bus.read_byte_data(addr,0xae) * 256) + bus.read_byte_data(addr,0xaf)
ac4 = (bus.read_byte_data(addr,0xb0) * 256) + bus.read_byte_data(addr,0xb1)
ac5 = (bus.read_byte_data(addr,0xb2) * 256) + bus.read_byte_data(addr,0xb3)
ac6 = (bus.read_byte_data(addr,0xb4) * 256) + bus.read_byte_data(addr,0xb5)
b1 = (bus.read_byte_data(addr,0xb6) * 256) + bus.read_byte_data(addr,0xb7)
b2 = (bus.read_byte_data(addr,0xb8) * 256) + bus.read_byte_data(addr,0xb9)
mb = (bus.read_byte_data(addr,0xba) * 256) + bus.read_byte_data(addr,0xbb)
mc = (bus.read_byte_data(addr,0xbc) * 256) + bus.read_byte_data(addr,0xbd)
md = (bus.read_byte_data(addr,0xbe) * 256) + bus.read_byte_data(addr,0xbe)
# nektere kalibracni konstanty mohou vyjadrovat i zaporna cisla,
# proto je bylo treba prevest na typ "signed short"
if(ac1 & 0x8000):
ac1 = -0x10000 + ac1
if(ac2 & 0x8000):
ac2 = -0x10000 + ac2
if(ac3 & 0x8000):
ac3 = -0x10000 + ac3
if(b1 & 0x8000):
b1 = -0x10000 + b1
if(b2 & 0x8000):
b2 = -0x10000 + b2
if(mb & 0x8000):
mb = -0x10000 + mb
if(mc & 0x8000):
mc = -0x10000 + mc
if(md & 0x8000):
md = -0x10000 + md
# jen pro kontrolu - tisk kalibracnich konstant
print ac1 , ac2 , ac3 , ac4 , ac5 , ac6 , b1 , b2 , mb , mc , md
# soubor, do ktereho se budou ukladat namerene udaje
soubor=file("/home/pi/tlakdata.txt",'a')
while True:
# prikaz pro spusteni mereni teploty
bus.write_byte_data(addr,0xf4,0x2e)
time.sleep(0.5)
# precteni mericich registu teploty
tepmsb = bus.read_byte_data(addr,0xF6)
teplsb = bus.read_byte_data(addr,0xF7)
# prepocet namerene hodnoty na stupne Celsia
ut= (tepmsb<<8) + teplsb
x1 = (ut-ac6) * ac5 / 2**15
x2 = (mc * 2**11) / (x1 + md)
b5 = x1 + x2
t = (b5 + 8) / 2**4
# prikaz pro spusteni mereni tlaku
# pomoci tohoto prikazu je mozne nastavit presnost, rychlost a spotrebu cipu
# takto vypada prikaz pro nejpresnejsi, ale nepomalejsi mereni:
bus.write_byte_data(addr,0xf4,0xf4)
oss = 3
# a toto by byl prikaz pro nejmene presne, ale nejrychlejsi mereni
#bus.write_byte_data(addr,0xf4,0x34)
#oss = 0
# mezi temito extremy jsou jeste mozne hodnoty 0x74 pro oss=1, nebo 0xb4 pro oss=2
time.sleep(0.5)
# precteni namerenych hodnot z registru tlaku
tlakmsb = bus.read_byte_data(addr,0xF6)
tlaklsb = bus.read_byte_data(addr,0xF7)
tlakxlsb = bus.read_byte_data(addr,0xF8)
# prepocet na atmosfericky tlak (algoritmus z katalogoveho listu)
up = ((tlakmsb<<16)+(tlaklsb<<8)+tlakxlsb)>>(8-oss)
b6 = b5-4000
x1 = (b2*(b6 * b6 / 2**12))/2**11
x2 = ac2 * b6 / 2**11
x3 = x1 + x2
b3 = (((ac1 * 4 + x3)<<oss) + 2) / 4
x1 = ac3 * b6 / 2**13
x2 = (b1 * (b6 * b6 / 2**12)) / 2**16
x3 = ((x1 + x2) + 2) / 2**2
b4 = ac4 * (x3 + 32768) / 2**15
b7 = (up - b3) * (50000>>oss)
if (b7 < 0x80000000):
p = (b7 * 2 ) / b4
else:
p = (b7 / b4) * 2
x1 = (float(p) / 256) * (float(p) / 256)
x1 = (x1 * 3038) / 2**16
x2 = (-7357 * p) / 2**16
# absolutni tlak (tlak v miste mereni) a jeho prepocet na hektopascaly
p_abs = p + (x1 + x2 + 3791) / 2**4
p_abs_hpa = round(p_abs/100,1)
# prepocet tlaku na hladinu more
# k tomuto prepoctu je treba znat presnou nadmorskou vysku cidla a VENKOVNI teplotu
vyska = 497 # nadmorska vyska v metrech
# pokud mate cidlo umistene venku, je mozne pro vypocet pouzit teplotu namerenou primo cidlem
teplota = float(t)/10
# jestlize je cidlo tlaku uvnitr budovy, musi se teplota zjistovat jinym zpusobem
p_rel = (p_abs * 9.80665 * vyska) / (287 * (273 + teplota + (vyska / 400))) + p_abs
p_rel_hpa = round(p_rel/100,1)
# tisk a ulozeni teploty , absolutniho tlaku a tlaku prepocitaneho na hladinu more
print str(teplota) + "°C" + "\t" + str(p_abs_hpa) + "hPa" + " (rel. tlak=" + str(p_rel_hpa) + "hPa)"
aktualnicas = datetime.datetime.now()
soubor.write(aktualnicas.strftime("%Y-%m-%d_%H:%M:%S") + ";" + str(float(t)/10) + ";" + str(p_abs) + "\n")
soubor.close()
|
Program funguje i s méně přesným čidlem BMP085.
Pak jsem s tím čidlem provedl ještě následující pokus:
Doplnil jsem do programu čtení stavu 2 tlačítek a záznam tohoto stavu
společně s naměřenými údaji do souboru.
Pak jsem připojil Raspíčko se senzorem tlaku k akumulátoru a prošel jsem se po
schodech v našem osmipatrovém paneláku.
Při tom jsem prováděl záznam naměřeného tlaku. V každém patře jsem si
to patro označil tlačítkem.
Na závěr jsem zaznamenané hodnoty vynesl do grafu.
Tady je výsledek (většinou se v grafu dají rozpoznat i
mezipatra):
A tady jsou naměřené hodnoty v excelovské tabulce: tlakdata.xls
Doplnění:
Program byl doplněn o část přepočtu z absolutního
tlaku (naměřená hodnota) na tlak přepočtený na hladinu moře
(hodnota, která se uvádí ve zprávách o počasí).
K tomuto výpočtu potřebujete znát přesnou nadmořskou výšku čidla a aktuální
venkovní teplotu.
Pokud máte čidlo tlaku někde venku ve stínu, je možné použít údaj
o teplotě naměřený přímo čidlem tlaku.
Pokud máte čidlo tlaku umístěné uvnitř budovy, nebo pokud je venku,
ale svítí na něj slunce, musíte si zjistit přesnou teplotu jiným způsobem.
Hodnota teploty má při výpočtu docela velký vliv na výsledek.
Pro výpočet jsem použil jednoduchý vzorec z diskusního
fóra : http://forum.amaterskameteorologie.cz/...
Složitější výpočty jsou pak třeba tady: http://de.wikipedia.org/wiki/...
Protože je absolutní přesnost čidla podle katalogového
listu v řádu jednotek hektopascalů, myslím, že je jednoduchý přepočet
na hladinu moře dostačující.
Doplnění 15.11.2012:
Děkuji Honzovi za zapůjčení čidla BMP085. Provedl
jsem jednoduché porovnání obou čidel. Zhruba ve dvacetisekundových
intervalech jsem je střídavě připojoval na I2C sběrnici a
zaznamenával údaje o naměřené teplotě a tlaku.
Zjistil jsem následující:
1) Oba typy čidel mají stejnou adresu (0x77), takže není
možné je připojit na I2C sběrnici najednou.
2) Výše uvedený program pracuje bez jakýchkoliv změn
s oběma čidly.
3) Rozdíly v naměřených teplotách se pohybují do 1°C
(viz graf níže). Nemám jak určit, který z teploměrů je přesnější.
Lihový teploměr, který ale není kalibrovaný, mi poblíž čidel
ukazoval něco málo přes 21°C. Takže možná že je ten čip BMP085
trochu přesnější.
V grafu průběhu teploty čipu BMP180 je vidět mírný nárůst teploty
(z 22,2 na 22,4°C) - možná to způsobuje svítící LEDka, která je na
desce těsně vedle měřícího čipu.
4) Rozdíly v měření absolutního tlaku jsou asi
2,5hPa. Obě čidla vykazují při pokojové teplotě podobný šum.
Naměřená data jsou k dispozici tady: bmp180-085.xls
Na začátku každého měřícího bloku jsem nechal do souboru
vypsat i kalibrační konstanty právě měřícího čidla.
Pořadí vypsaných konstant je stejné, jako je uvedeno v programu.
|
|
|