2026 Make Blocks #3阶段2 - 基于BME280的环境采集模块
该项目使用了BME280,实现了环境采集模块的设计,它的主要功能为:采集温度湿度大气压力。
标签
BME280
Make Blocks
环境采集模块
金玉其中
更新2026-07-17
45

任务介绍

本次选择的任务是设计一款集成数字温度(或环境)传感器的采集模块,通过数字接口直接读取传感器值,为后续测量或控制系统提供数据源。基本要求:

  1. 至少集成一种数字温度传感器(DS18B20、BME280、SHT30 等)
  2. 数字通信接口(I2C/SPI/1-Wire 至少一种)
  3. 板载3.3V或5V供电,含去耦电容
  4. 提供MCU接口(含必要的上拉电阻)
  5. 板载工作指示LED

模块介绍

本次推荐了集中温度采集芯片,实际上还有很多类似的传感器,通过对性能参数的对比,我们选择了BME280作为本次设计的主要传感器,其测量的参数最多。

我们这次通过对本次任务的分析和本次活动的走势,觉得需要选择一种比较通用的接口,目前正在看的一个开发板上的PMOD接口进入了视线,后续准备都选用这个接口了。
0

硬件介绍

BME280是一款非常流行的小型环境传感器,它能够同时测量温度、湿度和气压,广泛应用于智能家居、气象监测、无人机和可穿戴设备等领域。它体积小巧,功耗低,非常适合电池供电的移动设备。温度测量范围大约在-40到85摄氏度之间,精度可以达到±1°C,湿度测量范围在0%到100%相对湿度,精度约为±3%,气压测量范围约300到1100 hPa,精度可达±1 hPa。BME280内部采用了高精度的传感元件和先进的信号处理算法,能够将原始电信号转换为稳定、可用的数字数据,支持I2C和SPI两种通信方式,方便与各种微控制器或开发板连接。使用时,它能够实时采集环境信息,并且由于传感器体积小、抗干扰能力强,即使在复杂环境下也能提供可靠的数据。此外,BME280具有校准数据存储功能,可以在出厂时进行标定,确保长期使用的精度和稳定性。总体来说,BME280是一款高性价比、操作简单、功能全面的环境传感器,非常适合需要实时监测温度、湿度和气压的各类电子项目。

原理图和PCB模块介绍
0

基于BME280环境传感器设计的PMOD标准接口电路,核心依托博世BME280集成温湿度、气压三合一传感芯片实现高精度环境数据采集,电路左侧VCC供电支路串联10K限流电阻搭配LED1电源指示灯,可直观反馈模块供电状态,电源引脚旁并联100nF与1uF电容组成滤波网络,有效滤除电源纹波保障传感器供电稳定性,SCL、SDA两条I2C通信总线分别通过10K上拉电阻R2、R3连接电源,确保I2C通信电平稳定可靠,电路右侧搭载两路完全一致的PMOD标准接口,完整引出SCK、SDA等通信与控制引脚(本次通信使用I2C接口),支持多传感器并联扩展,,适配各类支持PMOD接口的嵌入式开发平台,无需复杂接线即可快速完成环境感知功能的原型搭建,整体电路简洁规范,完全符合PMOD外设模块的设计规范,兼顾了使用便捷性与功能扩展性。

原理图
0

PMOD-BME280的环境传感器模块PCB,整体采用紧凑的矩形布局,将核心BME280传感芯片放置在板面中心区域,四周预留充足的通风空间,避免周边器件的热传导与热辐射干扰温湿度、气压的测量精度,板上搭载J1、J2两路标准12针PMOD接口,完整引出电源、I2C通信所需的全部引脚,完全符合PMOD外设接口规范,可直接适配各类支持PMOD标准的嵌入式开发平台,电源路径上布置的C1、C2滤波电容就近贴近芯片电源引脚,搭配R1、R2、R3、R4完成通信上拉与电源限流配置,左侧板边设置的LED1电源指示灯可直观反馈模块供电状态,PCB走线按信号特性规划路径,减少信号反射与电磁干扰风险,整体铺铜连通GND网络,进一步提升板级抗干扰能力,兼顾了测量精度、通信稳定性与使用便捷性,非常适合物联网环境监测、嵌入式原型快速验证等场景使用。

PCB
0

3D效果图
0

实物图

软件调试

我们本次设计模块采用的PMOD接口,所以我们本次使用了一个板子这个接口的板子,就是NXP的一块W72板子,直接使用上面的PMOD接口进行连接,完美适配:
0

软件方面我们直接用的是基于zephyr的例程进行的工程创建:
image.png

关键代码详解

boards/frdm_mcxw72.overlay —— 板级设备声明


/*
* BME280 连接到 FRDM-MCXW72 的 lpi2c1 (PB4/PB5) 总线
* I2C 地址: 0x76 (SDO 接地)
* 与板上加速度计 fxls8974 (0x19) 共用同一条 I2C 总线
*/
&lpi2c1 {
bme280: bme280@76 {
compatible = "bosch,bme280";
reg = <0x76>;
label = "BME280";
status = "okay";
};
};

prj.conf —— 内核配置


CONFIG_SENSOR=y
CONFIG_SENSOR_ASYNC_API=y

src/main.c —— 应用核心


#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/devicetree.h>
#include <zephyr/drivers/sensor.h>
#include <zephyr/drivers/sensor_data_types.h>
#include <zephyr/rtio/rtio.h>
#include <zephyr/dsp/print_format.h>

/* 1. 获取 BME280 设备指针 */
const struct device *const dev = DEVICE_DT_GET_ANY(bosch_bme280);

/* 2. 定义 RTIO 读通道:温度、湿度、气压 */
SENSOR_DT_READ_IODEV(iodev, DT_COMPAT_GET_ANY_STATUS_OKAY(bosch_bme280),
{SENSOR_CHAN_AMBIENT_TEMP, 0},
{SENSOR_CHAN_HUMIDITY, 0},
{SENSOR_CHAN_PRESS, 0});

/* 3. 定义 RTIO 上下文:1 个 in-flight,1 个 SQ */
RTIO_DEFINE(ctx, 1, 1);

static const struct device *check_bme280_device(void)
{
if (dev == NULL) {
printk("\nError: no device found.\n");
return NULL;
}
if (!device_is_ready(dev)) {
printk("\nError: Device \"%s\" is not ready; "
"check the driver initialization logs for errors.\n",
dev->name);
return NULL;
}
printk("Found device \"%s\", getting sensor data\n", dev->name);
return dev;
}

int main(void)
{
const struct device *dev = check_bme280_device();
if (dev == NULL) {
return 0;
}

while (1) {
uint8_t buf[128];

/* 4. 异步提交读请求,buf 接收驱动返回的 raw bytes */
int rc = sensor_read(&iodev, &ctx, buf, 128);
if (rc != 0) {
printk("%s: sensor_read() failed: %d\n", dev->name, rc);
return rc;
}

/* 5. 获取解码器 */
const struct sensor_decoder_api *decoder;
rc = sensor_get_decoder(dev, &decoder);
if (rc != 0) {
printk("%s: sensor_get_decode() failed: %d\n", dev->name, rc);
return rc;
}

/* 6. 解码三个通道的数据 */
uint32_t temp_fit = 0;
struct sensor_q31_data temp_data = {0};
decoder->decode(buf,
(struct sensor_chan_spec) {SENSOR_CHAN_AMBIENT_TEMP, 0},
&temp_fit, 1, &temp_data);

uint32_t press_fit = 0;
struct sensor_q31_data press_data = {0};
decoder->decode(buf,
(struct sensor_chan_spec) {SENSOR_CHAN_PRESS, 0},
&press_fit, 1, &press_data);

uint32_t hum_fit = 0;
struct sensor_q31_data hum_data = {0};
decoder->decode(buf,
(struct sensor_chan_spec) {SENSOR_CHAN_HUMIDITY, 0},
&hum_fit, 1, &hum_data);

/* 7. 格式化为可读字符串 */
printk("temp: %s%d.%d; press: %s%d.%d; humidity: %s%d.%d\n",
PRIq_arg(temp_data.readings[0].temperature, 6, temp_data.shift),
PRIq_arg(press_data.readings[0].pressure, 6, press_data.shift),
PRIq_arg(hum_data.readings[0].humidity, 6, hum_data.shift));

k_sleep(K_MSEC(1000));
}
return 0;
}

sensor_decoder_api::decode()

驱动不直接返回浮点数,而是返回编码后的 Q31 定点数 + shift:


struct sensor_q31_data {
int64_t temperature; /* Q31.32 定点数 */
int64_t pressure; /* 单位 Pa,乘以 256 */
int64_t humidity; /* 单位 %RH,乘以 1024 */
int8_t shift; /* 缩放因子 */
};

效果展示

串口接收如下:

image.png

心得体会

本次参与项目的开发实际上有很多优秀的参考设计可以参考,也希望可以学习这个优秀设计的内容,进而锻炼自己的硬件设计能力和PCB的绘制能力,通过不断的模块化的设计可以尽可能多的接触更多的新器件,在了解其基本特性的前提下,学习使用他们,这是一次非常不错的机会,同时再软件驱动的时候要考虑器件的特性进行,当一切准备就绪,他们就可以正常工作了。本次我们在调试的时候就出现了传感器无法发现的问题,结果查了老半天确实硬件虚焊的问题。

附件下载
PMOD-BME280.zip
src.zip
团队介绍
评论
0 / 100
查看更多
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2024 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号