4、读取原始数据:编写第一个 Python 脚本,读取 BMP280 的温度与压力原始值
好,到了这一步,咱们的 BMP280 传感器已经焊好、接好线了。I2C 地址也确认过了。接下来要干嘛?当然是让它开口说话——读取原始数据。
说实话,我第一次调 BMP280 的时候,心里还挺没底的。毕竟 datasheet 里那些寄存器地址看着就头大。但后来我发现,其实没那么复杂。你只要按部就班,把几个关键寄存器读出来,数据就到手了。
4.1 准备工作:安装必要的库
在写脚本之前,得先确认你的树莓派(或者 Jetson Nano、香橙派都行)上装了 smbus2 这个库。它是用来跟 I2C 设备打交道的。
安装命令:
sudo pip3 install smbus2
我个人习惯用 smbus2 而不是老的 smbus。为什么?因为 smbus2 更稳定,而且支持 Python 3。我在一个项目里遇到过 smbus 莫名其妙报错,换成 smbus2 就再也没出过问题。
4.2 BMP280 的原始数据长什么样?
BMP280 内部有温度传感器和压力传感器。它们输出的原始值,说白了就是两个 20 位的二进制数。但注意,它不是直接给你 20 位,而是分成了三个 8 位寄存器来存。
具体来说:
- 温度原始值:存放在寄存器 0xFA(高8位)、0xFB(中8位)、0xFC(低8位)
- 压力原始值:存放在寄存器 0xF7(高8位)、0xF8(中8位)、0xF9(低8位)
你想想看,这三个 8 位拼起来,就是一个 24 位的数。但 BMP280 只用了高 20 位,低 4 位是 0。所以读出来之后,要右移 4 位才是真正的原始值。
小技巧: 我建议你一次性读 6 个字节(从 0xF7 开始),而不是分两次读。这样能保证温度和压力数据是同一时刻采样的,不会出现时间差。
4.3 第一个脚本:读取原始值
好,咱们直接上代码。这个脚本很简单,就是读寄存器、拼数据、打印出来。
import smbus2
import time
# BMP280 的 I2C 地址(默认是 0x76,也可能是 0x77)
BMP280_ADDR = 0x76
# 寄存器地址
BMP280_REG_PRESS_MSB = 0xF7 # 压力高8位
BMP280_REG_TEMP_MSB = 0xFA # 温度高8位
# 初始化 I2C 总线(树莓派一般是 1)
bus = smbus2.SMBus(1)
def read_raw_data():
"""
读取 BMP280 的温度和压力原始值
返回: (temp_raw, press_raw)
"""
# 一次性读取 6 个字节,从压力寄存器开始
# 顺序:press_msb, press_lsb, press_xlsb, temp_msb, temp_lsb, temp_xlsb
data = bus.read_i2c_block_data(BMP280_ADDR, BMP280_REG_PRESS_MSB, 6)
# 拼出压力原始值(24位,取高20位)
press_raw = (data[0] << 16) | (data[1] << 8) | data[2]
press_raw = press_raw >> 4 # 右移4位,得到20位原始值
# 拼出温度原始值(24位,取高20位)
temp_raw = (data[3] << 16) | (data[4] << 8) | data[5]
temp_raw = temp_raw >> 4 # 右移4位,得到20位原始值
return temp_raw, press_raw
# 主循环:每秒读一次
try:
while True:
temp_raw, press_raw = read_raw_data()
print(f"温度原始值: {temp_raw:6d} 压力原始值: {press_raw:8d}")
time.sleep(1)
except KeyboardInterrupt:
print("\n程序已停止")
bus.close()
注意: 如果你用的是 0x77 地址,记得把 BMP280_ADDR = 0x76 改成 0x77。我曾经在一个项目里忘了改,折腾了半小时才发现是地址不对。
4.4 运行脚本,看看结果
把上面的代码保存成 read_bmp280_raw.py,然后在终端里运行:
python3 read_bmp280_raw.py
你应该会看到类似这样的输出:
温度原始值: 52340 压力原始值: 412345
温度原始值: 52341 压力原始值: 412346
温度原始值: 52340 压力原始值: 412344
...
嗯,这里要注意:这些数字看着很大,对吧?别急,它们还不是真正的温度和压力值。原始值需要经过校准公式换算,才能变成摄氏度和帕斯卡。下一章咱们就讲这个。
4.5 常见问题与避坑指南
我遇到过不少新手在这步卡住,总结几个常见问题:
| 问题 | 可能原因 | 解决办法 |
|---|---|---|
| 读出来全是 0 | I2C 地址不对,或者传感器没上电 | 用 i2cdetect -y 1 确认地址 |
| 读出来数值不变 | 传感器处于休眠模式,没启动测量 | 检查是否写了控制寄存器(下一章会讲) |
| 数值跳变很大 | 电源不稳定,或者接线太长 | 加一个 100nF 电容在 VCC 和 GND 之间 |
我的经验: 如果你发现数值一直不变,先别急着怀疑代码。用手捏一下传感器,温度原始值应该会变化。如果没变化,那八成是传感器没启动测量。我曾经被这个坑过,后来发现是忘了设置 ctrl_meas 寄存器。
4.6 小结
这一章咱们干了三件事:
- 理解了 BMP280 原始数据的存储方式(三个寄存器拼一个 20 位数)
- 写了一个完整的 Python 脚本,用 smbus2 读取原始值
- 学会了怎么排查常见问题
下一章,咱们就要把这些原始值转换成真正的温度和压力了。到时候你会看到,BMP280 的校准公式其实挺巧妙的——它用了一组出厂时烧录的校准系数,来修正传感器的非线性误差。
嗯,今天就到这儿。代码跑通了的话,记得在终端里按 Ctrl+C 停止程序。咱们下章见。