樹莓派連接BMP180氣壓傳感器

作為最常見的傳感器,本篇(來自于知乎某大神的文章)實現(xiàn)氣壓傳感的交互:

1.先說明BMP180的特點

? 壓力范圍:300~1100hPa(海拔 9000 米~-500 米)

? 電源電壓:1.8V~3.6V(VDDA), 1.62V~3.6V(VDDD)

? 尺寸:3.6mmx3.8x0.93mm

? 低功耗:5μA,在標準模式

? 高精度:低功耗模式下蕉鸳,分辨率為 0.06hPa(0.5 米)

? 高線性模式下蜕煌,分辨率為 0.03hPa(0.25 米)

? 含溫度輸出

? I2C 接口

? 溫度補償

? MSL 1 反應(yīng)時間:7.5ms

? 待機電流:0.1μA

注意了該傳感器是I2C接口的,因此在后續(xù)步驟要稍加注意株扛。

2. 接線

I2C 有兩個總線:SCL 為時鐘信號养距,和 SDA 為雙向數(shù)據(jù)傳輸诉探。 每個 I2C 器件采用獨特的 7 位地址,這意味著你可以有超過 120 個獨特的 I2C 器件共享總線棍厌, 并且可以同時控制這些器件一起工作肾胯。

圖一 樹莓派與BMP180接線圖

將 BMP180 的 VCC 引腳用紅色跳線連接樹莓派的 3V3 ( 3.3 伏電源)。將 BMP180 的 SDA 引腳 接入樹莓派的 SDA 引腳并將 BMP180 SCL 引腳接入樹莓派的 SCL 引腳耘纱,該引腳提供一個規(guī)律的 時鐘信號敬肚。SDA 傳遞數(shù)據(jù)信號。BMP180 的 GND 引腳通過黑色跳線連接樹莓派的接地( GND) 引腳束析。 在上電前艳馒,一定多檢查兩次接線的準確性。

3. 環(huán)境和程序部分

配置文件/boot/config.txt:

dtparam=i2c_arm=on

重啟樹莓派,用如下命令查看傳感器是否接上:

i2cdetect -y 1

如果接上了的話會顯示下圖:


圖二 I2C接口檢測結(jié)果

編寫 BMP180.py:

#!/usr/bin/env python

import time

import smbus

# BMP085 default address.

BMP180_I2CADDR? ? ? ? ? = 0x77

# Operating Modes

BMP180_ULTRALOWPOWER? ? = 0

BMP180_STANDARD? ? ? ? ? = 1

BMP180_HIGHRES? ? ? ? ? = 2

BMP180_ULTRAHIGHRES? ? ? = 3

# BMP085 Registers

BMP180_CAL_AC1? ? ? ? ? = 0xAA? # R? Calibration data (16 bits)

BMP180_CAL_AC2? ? ? ? ? = 0xAC? # R? Calibration data (16 bits)

BMP180_CAL_AC3? ? ? ? ? = 0xAE? # R? Calibration data (16 bits)

BMP180_CAL_AC4? ? ? ? ? = 0xB0? # R? Calibration data (16 bits)

BMP180_CAL_AC5? ? ? ? ? = 0xB2? # R? Calibration data (16 bits)

BMP180_CAL_AC6? ? ? ? ? = 0xB4? # R? Calibration data (16 bits)

BMP180_CAL_B1? ? ? ? ? ? = 0xB6? # R? Calibration data (16 bits)

BMP180_CAL_B2? ? ? ? ? ? = 0xB8? # R? Calibration data (16 bits)

BMP180_CAL_MB? ? ? ? ? ? = 0xBA? # R? Calibration data (16 bits)

BMP180_CAL_MC? ? ? ? ? ? = 0xBC? # R? Calibration data (16 bits)

BMP180_CAL_MD? ? ? ? ? ? = 0xBE? # R? Calibration data (16 bits)

BMP180_CONTROL? ? ? ? ? = 0xF4

BMP180_TEMPDATA? ? ? ? ? = 0xF6

BMP180_PRESSUREDATA? ? ? = 0xF6

# Commands

BMP180_READTEMPCMD? ? ? = 0x2E

BMP180_READPRESSURECMD? = 0x34

class BMP180(object):

? ? def __init__(self, address=BMP180_I2CADDR, mode=BMP180_STANDARD):

? ? ? ? self._mode = mode

? ? ? ? self._address = address

? ? ? ? self._bus = smbus.SMBus(1)

? ? ? ? # Load calibration values.

? ? ? ? self._load_calibration()

? ? def _read_byte(self,cmd):

? ? ? ? return self._bus.read_byte_data(self._address,cmd)

? ? def _read_u16(self,cmd):

? ? ? ? MSB = self._bus.read_byte_data(self._address,cmd)

? ? ? ? LSB = self._bus.read_byte_data(self._address,cmd+1)

? ? ? ? return (MSB << 8) + LSB

? ? def _read_s16(self,cmd):

? ? ? ? result = self._read_u16(cmd)

? ? ? ? if result > 32767:result -= 65536

? ? ? ? return result

? ? def _write_byte(self,cmd,val):

? ? ? ? self._bus.write_byte_data(self._address,cmd,val)

? ? def _load_calibration(self):

? ? ? ? "load calibration"

? ? ? ? self.cal_AC1 = self._read_s16(BMP180_CAL_AC1)? # INT16

? ? ? ? self.cal_AC2 = self._read_s16(BMP180_CAL_AC2)? # INT16

? ? ? ? self.cal_AC3 = self._read_s16(BMP180_CAL_AC3)? # INT16

? ? ? ? self.cal_AC4 = self._read_u16(BMP180_CAL_AC4)? # UINT16

? ? ? ? self.cal_AC5 = self._read_u16(BMP180_CAL_AC5)? # UINT16

? ? ? ? self.cal_AC6 = self._read_u16(BMP180_CAL_AC6)? # UINT16

? ? ? ? self.cal_B1? = self._read_s16(BMP180_CAL_B1)? ? # INT16

? ? ? ? self.cal_B2? = self._read_s16(BMP180_CAL_B2)? ? # INT16

? ? ? ? self.cal_MB? = self._read_s16(BMP180_CAL_MB)? ? # INT16

? ? ? ? self.cal_MC? = self._read_s16(BMP180_CAL_MC)? ? # INT16

? ? ? ? self.cal_MD? = self._read_s16(BMP180_CAL_MD)? ? # INT16

? ? def read_raw_temp(self):

? ? ? ? """Reads the raw (uncompensated) temperature from the sensor."""

? ? ? ? self._write_byte(BMP180_CONTROL, BMP180_READTEMPCMD)

? ? ? ? time.sleep(0.005)? # Wait 5ms

? ? ? ? MSB = self._read_byte(BMP180_TEMPDATA)

? ? ? ? LSB = self._read_byte(BMP180_TEMPDATA+1)

? ? ? ? raw = (MSB << 8) + LSB

? ? ? ? return raw

? ? def read_raw_pressure(self):

? ? ? ? """Reads the raw (uncompensated) pressure level from the sensor."""

? ? ? ? self._write_byte(BMP180_CONTROL, BMP180_READPRESSURECMD + (self._mode << 6))

? ? ? ? if self._mode == BMP180_ULTRALOWPOWER:

? ? ? ? ? ? time.sleep(0.005)

? ? ? ? elif self._mode == BMP180_HIGHRES:

? ? ? ? ? ? time.sleep(0.014)

? ? ? ? elif self._mode == BMP180_ULTRAHIGHRES:

? ? ? ? ? ? time.sleep(0.026)

? ? ? ? else:

? ? ? ? ? ? time.sleep(0.008)

? ? ? ? MSB = self._read_byte(BMP180_PRESSUREDATA)

? ? ? ? LSB = self._read_byte(BMP180_PRESSUREDATA+1)

? ? ? ? XLSB = self._read_byte(BMP180_PRESSUREDATA+2)

? ? ? ? raw = ((MSB << 16) + (LSB << 8) + XLSB) >> (8 - self._mode)

? ? ? ? return raw

? ? def read_temperature(self):

? ? ? ? """Gets the compensated temperature in degrees celsius."""

? ? ? ? UT = self.read_raw_temp()

? ? ? ? X1 = ((UT - self.cal_AC6) * self.cal_AC5) >> 15

? ? ? ? X2 = (self.cal_MC << 11) / (X1 + self.cal_MD)

? ? ? ? B5 = X1 + X2

? ? ? ? temp = ((B5 + 8) >> 4) / 10.0

? ? ? ? return temp

? ? def read_pressure(self):

? ? ? ? """Gets the compensated pressure in Pascals."""

? ? ? ? UT = self.read_raw_temp()

? ? ? ? UP = self.read_raw_pressure()

? ? ? ? X1 = ((UT - self.cal_AC6) * self.cal_AC5) >> 15

? ? ? ? X2 = (self.cal_MC << 11) / (X1 + self.cal_MD)

? ? ? ? B5 = X1 + X2

? ? ? ? # Pressure Calculations

? ? ? ? B6 = B5 - 4000

? ? ? ? X1 = (self.cal_B2 * (B6 * B6) >> 12) >> 11

? ? ? ? X2 = (self.cal_AC2 * B6) >> 11

? ? ? ? X3 = X1 + X2

? ? ? ? B3 = (((self.cal_AC1 * 4 + X3) << self._mode) + 2) / 4

? ? ? ? X1 = (self.cal_AC3 * B6) >> 13

? ? ? ? X2 = (self.cal_B1 * ((B6 * B6) >> 12)) >> 16

? ? ? ? X3 = ((X1 + X2) + 2) >> 2

? ? ? ? B4 = (self.cal_AC4 * (X3 + 32768)) >> 15

? ? ? ? B7 = (UP - B3) * (50000 >> self._mode)

? ? ? ? if B7 < 0x80000000:

? ? ? ? ? ? p = (B7 * 2) / B4

? ? ? ? else:

? ? ? ? ? ? p = (B7 / B4) * 2

? ? ? ? X1 = (p >> 8) * (p >> 8)

? ? ? ? X1 = (X1 * 3038) >> 16

? ? ? ? X2 = (-7357 * p) >> 16

? ? ? ? p = p + ((X1 + X2 + 3791) >> 4)

? ? ? ? return p

? ? def read_altitude(self, sealevel_pa=101325.0):

? ? ? ? """Calculates the altitude in meters."""

? ? ? ? # Calculation taken straight from section 3.6 of the datasheet.

? ? ? ? pressure = float(self.read_pressure())

? ? ? ? altitude = 44330.0 * (1.0 - pow(pressure / sealevel_pa, (1.0/5.255)))

? ? ? ? return altitude

? ? def read_sealevel_pressure(self, altitude_m=0.0):

? ? ? ? """Calculates the pressure at sealevel when given a known altitude in

? ? ? ? meters. Returns a value in Pascals."""

? ? ? ? pressure = float(self.read_pressure())

? ? ? ? p0 = pressure / pow(1.0 - altitude_m/44330.0, 5.255)

? ? ? ? return p0

然后編寫調(diào)用函數(shù)bmp180_example.py:

#!/usr/bin/python

import time

from BMP180 import BMP180

# Initialise the BMP085 and use STANDARD mode (default value)

# bmp = BMP085(0x77, debug=True)

bmp = BMP180()

# To specify a different operating mode, uncomment one of the following:

# bmp = BMP085(0x77, 0)? # ULTRALOWPOWER Mode

# bmp = BMP085(0x77, 1)? # STANDARD Mode

# bmp = BMP085(0x77, 2)? # HIRES Mode

# bmp = BMP085(0x77, 3)? # ULTRAHIRES Mode

while True:

? ? temp = bmp.read_temperature()

# Read the current barometric pressure level

? ? pressure = bmp.read_pressure()

# To calculate altitude based on an estimated mean sea level pressure

# (1013.25 hPa) call the function as follows, but this won't be very accurate

? ? altitude = bmp.read_altitude()

# To specify a more accurate altitude, enter the correct mean sea level

# pressure level.? For example, if the current pressure level is 1023.50 hPa

# enter 102350 since we include two decimal places in the integer value

# altitude = bmp.readAltitude(102350)

? ? print "Temperature: %.2f C" % temp

? ? print "Pressure:? ? %.2f hPa" % (pressure / 100.0)

? ? #print "Altitude:? ? %.2f\n" % altitude

? ? time.sleep(1)

執(zhí)行./bmp180_example.py就可以在終端看到實時的溫度/氣壓輸出弄慰。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末第美,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子陆爽,更是在濱河造成了極大的恐慌什往,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,496評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件慌闭,死亡現(xiàn)場離奇詭異别威,居然都是意外死亡,警方通過查閱死者的電腦和手機驴剔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,187評論 3 385
  • 文/潘曉璐 我一進店門省古,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人仔拟,你說我怎么就攤上這事衫樊。” “怎么了利花?”我有些...
    開封第一講書人閱讀 157,091評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長载佳。 經(jīng)常有香客問我炒事,道長,這世上最難降的妖魔是什么蔫慧? 我笑而不...
    開封第一講書人閱讀 56,458評論 1 283
  • 正文 為了忘掉前任挠乳,我火速辦了婚禮,結(jié)果婚禮上姑躲,老公的妹妹穿的比我還像新娘睡扬。我一直安慰自己,他們只是感情好黍析,可當我...
    茶點故事閱讀 65,542評論 6 385
  • 文/花漫 我一把揭開白布卖怜。 她就那樣靜靜地躺著,像睡著了一般阐枣。 火紅的嫁衣襯著肌膚如雪马靠。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,802評論 1 290
  • 那天蔼两,我揣著相機與錄音甩鳄,去河邊找鬼。 笑死额划,一個胖子當著我的面吹牛妙啃,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播俊戳,決...
    沈念sama閱讀 38,945評論 3 407
  • 文/蒼蘭香墨 我猛地睜開眼揖赴,長吁一口氣:“原來是場噩夢啊……” “哼馆匿!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起储笑,我...
    開封第一講書人閱讀 37,709評論 0 266
  • 序言:老撾萬榮一對情侶失蹤甜熔,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后突倍,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體腔稀,經(jīng)...
    沈念sama閱讀 44,158評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,502評論 2 327
  • 正文 我和宋清朗相戀三年羽历,在試婚紗的時候發(fā)現(xiàn)自己被綠了焊虏。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,637評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡秕磷,死狀恐怖诵闭,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情澎嚣,我是刑警寧澤疏尿,帶...
    沈念sama閱讀 34,300評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站易桃,受9級特大地震影響褥琐,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜晤郑,卻給世界環(huán)境...
    茶點故事閱讀 39,911評論 3 313
  • 文/蒙蒙 一敌呈、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧造寝,春花似錦磕洪、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,744評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至赐稽,卻和暖如春叫榕,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背姊舵。 一陣腳步聲響...
    開封第一講書人閱讀 31,982評論 1 266
  • 我被黑心中介騙來泰國打工晰绎, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人括丁。 一個月前我還...
    沈念sama閱讀 46,344評論 2 360
  • 正文 我出身青樓荞下,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子尖昏,可洞房花燭夜當晚...
    茶點故事閱讀 43,500評論 2 348

推薦閱讀更多精彩內(nèi)容

  • 在標記的圖像訓(xùn)練集上進行面向梯度的直方圖(HOG)特征提取并訓(xùn)練分類器線性SVM分類器 應(yīng)用顏色轉(zhuǎn)換仰税,并將分箱的顏...
    劉老實Peter閱讀 2,923評論 1 3
  • 第二天清晨。 "噔噔"抽诉。聽到聲音,梁境立馬跑了過去陨簇。推開窗戶后,卻像往常一樣又不見了人影。 她打開飯盒邊吃邊搜尋著...
    三木水乙閱讀 281評論 2 1
  • 老規(guī)矩迹淌,先上圖 演示中用的是CardView嵌套的ListView,背景是攝像頭河绽,接下來說實現(xiàn)。理論上所有的Vie...
    BertSir閱讀 3,165評論 0 5
  • 最近在爬某網(wǎng)站唉窃,老是蹦出來驗證碼耙饰,就想著找個OCR破了這個驗證碼,然后就開始了OCR探索之旅纹份。 首先簡單說一下什么...
    吳鈞澤閱讀 4,915評論 9 22
  • 有句話說苟跪,養(yǎng)兒方知父母恩,果真是不錯的蔓涧。平時工作忙碌件已,只在周末抽空陪兒子玩玩,并沒有體會到帶孩子的不容易元暴。在真正意...
    Sinead閱讀 544評論 1 1