回到首页 返回首页
回到顶部 回到顶部
返回上一页 返回上一页

Beetle 树莓派RP2350 - 随身气压计 简单

头像 无垠的广袤 2025.05.24 43 1

Beetle 树莓派RP2350 - 随身气压计

 

本文介绍了 DFRobot Beetle RP2350 开发板结合 BMP280 模块和锂电池模块实现环境大气压强、温度、海拔实时OLED显示的便携随身气压计的项目设计。

 

项目介绍

 

本项目包括 BMP280 传感器模块介绍、工作原理、参数特点等信息,在此基础上实现工程代码编写、硬件测试等流程,最终实现气压计的制作。

 

BMP280 模块

 

BMP280 是一款由 博世(Bosch) 开发的高精度数字气压传感器,广泛应用于移动设备、气象监测、无人机、室内导航等领域。

 

BMP280.jpg

 

它集成了 气压温度 测量功能,具有低功耗、小尺寸和高精度的特点,适用于电池供电设备。

 

原理图

 

SCH_BMP280.jpg

 

特点

 

高精度测量

 

气压测量范围:300~1100 hPa(海拔 -500m 至 +9000m)

相对精度:±0.12 hPa(高度误差 ±1 米)

温度测量范围:-40°C ~ +85°C,精度 ±0.01°C

 

低功耗设计

 

工作电流仅 2.7μA @1Hz,适合电池供电设备;

 

支持多种通信接口

 

I²C(默认地址 0x76 或 0x77)和 SPI,方便与微控制器连接;

 

紧凑封装

 

采用 8 引脚 LGA 封装(2.0×2.5mm,高度 0.95mm),适合空间受限的应用。

 

内置温度补偿

 

温度数据可用于校准气压测量,提高精度。

 

应用

 

气象站:用于气压趋势监测和天气预报;

无人机 & 飞行控制器:测量高度和垂直速度;

室内导航:检测楼层变化(如电梯、商场导航);

智能穿戴设备(如运动手表):计算海拔变化和运动数据;

健康监测:如肺活量检测(气压变化反映呼吸情况).

 

IIC 时序图

 

bmp280_iic_timing_diagram.jpg

 

详见:BMP280 Datasheet - BST .

 

硬件连接

 

  •  GP4 ---- SDA (BMP280)
  •  GP5 ---- SCL (BMP280)
  •  GP4 ---- SDA (OLED_SSD1306)
  •  GP5 ---- SCL (OLED_SSD1306)
  •  BAT -> Battery Positive
  •  GND -> Battery Negative

 

示意图

 

connect_bmp280_battery_oled.jpg

 

实物连接

 

bmp280_sensor_battery_charge_full.jpg

 

代码

 

通过复用 IIC 引脚 GPIO4 和 GPIO5 ,实现 BMP280 模块的数据采集、终端打印以及 OLED 显示。

打开 Thonny IDE 软件,连接开发板,新建 main.py 文件,并添加如下代码

 

from machine import Pin, I2C
import utime
import math
from ssd1306 import SSD1306_I2C

# BMP280 I2C地址
BMP280_I2C_ADDR = 0x76  # 如果使用0x77地址,请修改此值

# BMP280寄存器地址
BMP280_REGISTER_DIG_T1 = 0x88
BMP280_REGISTER_DIG_T2 = 0x8A
BMP280_REGISTER_DIG_T3 = 0x8C
BMP280_REGISTER_DIG_P1 = 0x8E
BMP280_REGISTER_DIG_P2 = 0x90
BMP280_REGISTER_DIG_P3 = 0x92
BMP280_REGISTER_DIG_P4 = 0x94
BMP280_REGISTER_DIG_P5 = 0x96
BMP280_REGISTER_DIG_P6 = 0x98
BMP280_REGISTER_DIG_P7 = 0x9A
BMP280_REGISTER_DIG_P8 = 0x9C
BMP280_REGISTER_DIG_P9 = 0x9E
BMP280_REGISTER_CHIPID = 0xD0
BMP280_REGISTER_CONTROL = 0xF4
BMP280_REGISTER_CONFIG = 0xF5
BMP280_REGISTER_PRESSUREDATA = 0xF7
BMP280_REGISTER_TEMPDATA = 0xFA

# 初始化I2C
i2c = I2C(0, scl=Pin(5), sda=Pin(4), freq=400000)

devices = i2c.scan()
# scan iic devices and print address name
if len(devices) == 0:
    print("No i2c device found.")
else:
    print("i2c devices found:", len(devices))
    
    for device in devices:
        print("i2c scan:", hex(device))
        
oled_width = 128
oled_height = 64
oled = SSD1306_I2C(oled_width, oled_height, i2c, addr=devices[0])

# 读取校准数据
def read_calibration_data():
    calib = {}
    
    # 读取温度校准数据
    calib["dig_T1"] = read_unsigned_short(BMP280_REGISTER_DIG_T1)
    calib["dig_T2"] = read_signed_short(BMP280_REGISTER_DIG_T2)
    calib["dig_T3"] = read_signed_short(BMP280_REGISTER_DIG_T3)
    
    # 读取压力校准数据
    calib["dig_P1"] = read_unsigned_short(BMP280_REGISTER_DIG_P1)
    calib["dig_P2"] = read_signed_short(BMP280_REGISTER_DIG_P2)
    calib["dig_P3"] = read_signed_short(BMP280_REGISTER_DIG_P3)
    calib["dig_P4"] = read_signed_short(BMP280_REGISTER_DIG_P4)
    calib["dig_P5"] = read_signed_short(BMP280_REGISTER_DIG_P5)
    calib["dig_P6"] = read_signed_short(BMP280_REGISTER_DIG_P6)
    calib["dig_P7"] = read_signed_short(BMP280_REGISTER_DIG_P7)
    calib["dig_P8"] = read_signed_short(BMP280_REGISTER_DIG_P8)
    calib["dig_P9"] = read_signed_short(BMP280_REGISTER_DIG_P9)
    
    return calib

# 读取无符号16位数据
def read_unsigned_short(reg):
    data = i2c.readfrom_mem(BMP280_I2C_ADDR, reg, 2)
    return (data[1] << 8) | data[0]

# 读取有符号16位数据
def read_signed_short(reg):
    data = i2c.readfrom_mem(BMP280_I2C_ADDR, reg, 2)
    value = (data[1] << 8) | data[0]
    if value > 32767:
        value -= 65536
    return value

# 初始化BMP280
def init_bmp280():
    # 检查设备ID
    chip_id = i2c.readfrom_mem(BMP280_I2C_ADDR, BMP280_REGISTER_CHIPID, 1)[0]
    if chip_id != 0x58:  # BMP280芯片ID应为0x58
        print("错误的芯片ID: 0x%02X" % chip_id)
        return False
    
    # 设置工作模式
    # osrs_t x2, osrs_p x16, normal mode
    i2c.writeto_mem(BMP280_I2C_ADDR, BMP280_REGISTER_CONTROL, bytes([0b01011011]))
    
    return True

# 读取原始温度和压力数据
def read_raw_data():
    # 读取压力数据(20位)
    data = i2c.readfrom_mem(BMP280_I2C_ADDR, BMP280_REGISTER_PRESSUREDATA, 3)
    adc_p = (data[0] << 12) | (data[1] << 4) | (data[2] >> 4)
    
    # 读取温度数据(20位)
    data = i2c.readfrom_mem(BMP280_I2C_ADDR, BMP280_REGISTER_TEMPDATA, 3)
    adc_t = (data[0] << 12) | (data[1] << 4) | (data[2] >> 4)
    
    return (adc_t, adc_p)

# 计算补偿后的温度
def compensate_temperature(adc_t, calib):
    var1 = ((adc_t) / 16384.0 - (calib["dig_T1"]) / 1024.0) * (calib["dig_T2"])
    var2 = (((adc_t) / 131072.0 - (calib["dig_T1"]) / 8192.0) * ((adc_t)/131072.0 - (calib["dig_T1"])/8192.0)) * (calib["dig_T3"])
    t_fine = var1 + var2
    temperature = (var1 + var2) / 5120.0
    return (temperature, t_fine)

# 计算补偿后的压力
def compensate_pressure(adc_p, t_fine, calib):
    var1 = (t_fine / 2.0) - 64000.0
    var2 = var1 * var1 * (calib["dig_P6"]) / 32768.0
    var2 = var2 + var1 * (calib["dig_P5"]) * 2.0
    var2 = (var2 / 4.0) + ((calib["dig_P4"]) * 65536.0)
    var1 = ((calib["dig_P3"]) * var1 * var1 / 524288.0 + (calib["dig_P2"]) * var1) / 524288.0
    var1 = (1.0 + var1 / 32768.0) * (calib["dig_P1"])
    if var1 == 0:
        return 0  # 避免除以零
    
    p = 1048576.0 - adc_p
    p = (p - (var2 / 4096.0)) * 6250.0 / var1
    var1 = (calib["dig_P9"]) * p * p / 2147483648.0
    var2 = p * (calib["dig_P8"]) / 32768.0
    p = p + (var1 + var2 + (calib["dig_P7"])) / 16.0
    
    return p / 100.0  # 转换为hPa

# 计算海拔高度(简化版)
def calculate_altitude(pressure_hpa, sea_level_hpa=1013.25):
    # 使用国际标准大气压公式简化计算
    altitude = 44330.0 * (1.0 - pow(pressure_hpa / sea_level_hpa, 0.1903))
    return altitude

# 主程序
def main():
    # 初始化BMP280
    if not init_bmp280():
        print("BMP280初始化失败")
        return
    
    # 读取校准数据
    calib = read_calibration_data()
    
    while True:
        # 读取原始数据
        adc_t, adc_p = read_raw_data()
        
        # 计算补偿后的温度和压力
        temperature, t_fine = compensate_temperature(adc_t, calib)
        pressure_hpa = compensate_pressure(adc_p, t_fine, calib)
        
        # 计算海拔高度
        altitude = calculate_altitude(pressure_hpa)
        
        # 打印结果
        print("Temperature: {:.2f} °C".format(temperature))
        print("Pressure: {:.2f} hPa".format(pressure_hpa))
        print("Altitude: {:.2f} m".format(altitude))
        print("----------------------")
        oled.fill(0)
        oled.text('Temp: ' + '{:.2f} C'.format(temperature), 0, 0)
        oled.text('Press: ' + '{:.1f} hPa'.format(pressure_hpa), 0, 16)
        oled.text('Alt: ' + '{:.1f} m'.format(altitude), 0, 32)
        oled.rotate(0) # rotate the screen display for a more comfortable position
        oled.show()
        # 延时2秒
        utime.sleep(2)

if __name__ == "__main__":
    main()

 

将该文件上传至 Beetle RP2350 开发板根目录,上电自动运行程序。

 

效果

 

终端打印温度、压强和海拔信息,同时 OLED 显示三组数据。

 

bmp280_altitude_sensor.jpg

 

bmp280_altitude_sensor_battery.jpg

 

bmp280_altitude_sensor_handy.jpg

 

 

充电状态

 

绿色指示灯常亮

充电指示灯为绿色 LED ,充电状态:

充满电或未接入电源时熄灭;

充电时常亮;

 

USB供电,未连接锂电池时高频闪烁

 

bmp280_sensor_battery_charging.jpg

 

充满状态:绿色指示灯熄灭

 

bmp280_sensor_battery_charge_full.jpg

 

总结

 

本文介绍了 DFRobot Beetle RP2350 开发板结合 BMP280 模块和锂电池模块实现环境大气压强、温度、海拔实时OLED显示的便携随身气压计的项目设计,为 Beetle RP2350 开发板的开发设计和产品应用提供了参考。

评论

user-avatar
  • 无垠的广袤

    无垠的广袤2025.05.24

    项目使用的扩展板详见: https://oshwhub.com/lijinlei0907/beetle-rp2350-expansion-board 锂电池可装载于壳体内,可实现随身携带。

    0