树莓派 I2C 接口 BMP085:高精度温度与气压读取
博世 BMP085 是紧凑、低成本的 I2C 传感器,能提供精准的气压与温度测量。在 eBay 几美元即可入手,是气象站、高度记录仪或任何需可靠环境数据项目的理想组件。
虽然 Adafruit 的 BMP085 指南 与库提供开箱即用方案,但深入代码能更透彻理解将原始数据转为可读值的补偿算法。下文结合 Adafruit 参考与自行 Python 实现,演示传感器工作原理。
- Maarten Damen 的 Bus Pirate 教程(归档)– 优秀的 I2C 调试资源。
- John Burn C 代码的 Python 移植 – GitHub 仓库。
BMP085 接线简单:VCC 接 3.3V,GND 接地,SDA 接 GPIO2,SCL 接 GPIO3。默认 I2C 地址 0x77。
# BMP085 I2C 地址
BMP085_ADDR = 0x77
Python 实现
import smbus
import time
class BMP085:
# 过采样设置 (0–3)。3 精度最高。
OSS = 3
def __init__(self, i2c, address=BMP085_ADDR):
self.i2c = i2c
self.address = address
# 校准系数 – 从 EEPROM 读取一次
self.ac1 = self._read_signed(0xAA)
self.ac2 = self._read_signed(0xAC)
self.ac3 = self._read_signed(0xAE)
self.ac4 = self._read_unsigned(0xB0)
self.ac5 = self._read_unsigned(0xB2)
self.ac6 = self._read_unsigned(0xB4)
self.b1 = self._read_signed(0xB6)
self.b2 = self._read_signed(0xB8)
self.mb = self._read_signed(0xBA)
self.mc = self._read_signed(0xBC)
self.md = self._read_signed(0xBE)
def _read_unsigned(self, reg):
msb = self.i2c.read_byte_data(self.address, reg)
lsb = self.i2c.read_byte_data(self.address, reg + 1)
return (msb << 8) + lsb
def _read_signed(self, reg):
val = self._read_unsigned(reg)
return val - 65536 if val > 32767 else val
def _read_ut(self):
# 触发温度测量
self.i2c.write_byte_data(self.address, 0xF4, 0x2E)
time.sleep(0.0045)
return self._read_unsigned(0xF6)
def read_temperature(self):
ut = self._read_ut()
x1 = ((ut - self.ac6) * self.ac5) >> 15
x2 = (self.mc << 11) // (x1 + self.md)
self.b5 = x1 + x2
temp = (self.b5 + 8) >> 4 # 单位 0.1°C
return temp / 10.0
def _read_up(self):
# 触发气压测量,按选定 OSS
cmd = 0x34 + (self.OSS << 6)
self.i2c.write_byte_data(self.address, 0xF4, cmd)
delay = (2 + (3 << self.OSS)) / 1000.0
time.sleep(delay)
msb = self.i2c.read_byte_data(self.address, 0xF6)
lsb = self.i2c.read_byte_data(self.address, 0xF7)
xlsb = self.i2c.read_byte_data(self.address, 0xF8)
up = ((msb << 16) + (lsb << 8) + xlsb) >> (8 - self.OSS)
return up
def read_pressure(self):
up = self._read_up()
b6 = self.b5 - 4000
x1 = (self.b2 * (b6 * b6) >> 12) >> 11
x2 = (self.ac2 * b6) >> 11
x3 = x1 + x2
b3 = (((self.ac1 * 4 + x3) << self.OSS) + 2) >> 2
x1 = (self.ac3 * b6) >> 13
x2 = (self.b1 * (b6 * b6) >> 12) >> 16
x3 = ((x1 + x2) + 2) >> 2
b4 = (self.ac4 * (x3 + 32768)) >> 15
b7 = (up - b3) * (50000 >> self.OSS)
if b7 < 0x80000000:
p = (b7 * 2) // b4
else:
p = (b7 // b4) << 1
p = ((p + 1) * 1) >> 1
x1 = (p >> 8) * (p >> 8)
x1 = (x1 * 3038) >> 16
x2 = (-7357 * p) >> 16
p = p + ((x1 + x2 + 3791) >> 4)
return p # 单位 Pa
# 示例用法
bus = smbus.SMBus(1) # 树莓派 I2C 总线
bmp = BMP085(bus)
print(f"Temperature: {bmp.read_temperature():.2f} °C")
print(f"Pressure: {bmp.read_pressure() / 100:.2f} hPa")
脚本按博世 BMP085 数据手册 执行完整校准流程。运行后打印摄氏温度与百帕气压,可直接用于 Python 应用。
为何自行实现?
用 Adafruit 库省时,但掌握传感器背后的数学原理,能让你调整采样率、处理原始数据流、或将代码移植到其他单片机。无论业余爱好者还是资深工程师,精通 BMP085 内部机制都是宝贵技能。
制造工艺
- 树莓派+$5 I²C传感器打造温度记录仪
- 树莓派温度画像:Python+SQLite+LabVIEW实战
- 树莓派多路DS18B20 1-Wire温度监测:接线与编程全指南
- 树莓派温湿度网络监测站DIY全指南
- 树莓派2上使用DS18B20读取温度完整指南
- 树莓派专业温度监测:基于 DS18B20 传感器的完整指南
- 树莓派结合 Maxim 1-Wire 传感器与 DS2482 I2C 桥接器的多点温度测量
- 树莓派配合 TMP006 红外温度传感器:Python 库与安装指南
- 树莓派与 Python 构建远程温度传感器:分步实战指南
- 树莓派配合 EzTemp 实现无缝温湿度监测
- 树莓派精准监测机柜温度:DS18B20 多点部署实战
- IoT 入门教程:树莓派流式传输温度数据