2025 Make Blocks第二期阶段2-IIC数字外设设计
该项目使用了BMP390,SHT30,BMI323,实现了IIC数字外设的设计,它的主要功能为:温度、湿度、气压、陀螺仪等数据的采集与分析。
标签
嵌入式系统
温湿度传感器
姿态传感器
Make Blocks
zxfeng02
更新2025-09-17
24

一、任务介绍

本次2025 Make Blocks(第二期)活动中,我选择的为任务11:数字外设、时钟-自命题。计划在第一期的基础上,添加基于IIC的数字外设,实现温度、湿度、气压、陀螺仪等传感器数据的采集与分析。

二、模块介绍

设计框图

本次硬件设计在第一期ESP32-PICO-V3-02最小系统的基础上进行了功能性优化与结构精简。一方面,针对系统资源占用情况,合理裁剪未使用的I/O引脚,提升了电路布局的紧凑性;另一方面,新增一路IIC数字传感器接口,分别接入环境温湿度(SHT30)、气压高度(BMP390)与六轴惯性(BMI323)等环境传感器模块,极大丰富了系统的数据感知维度与功能拓展能力,使系统不仅具备了对周边环境变化(温度、湿度、气压)的实时监测能力,还可基于陀螺仪与加速度信息实现更灵敏的人机交互识别。

选型介绍

高精度气压与高度传感器

BMP390是Bosch推出的一款超高精度的数字气压传感器,采用I²C或SPI通信接口,支持16位至24位输出分辨率,具备±0.03 hPa的气压精度,对应高度精度可达±2.5 cm,远优于常见的BMP180/BMP280系列。该传感器集成温度补偿和低噪声设计,适用于精准海拔变化检测等应用场景。其封装小巧、功耗极低,适合嵌入式低功耗系统部署。

环境温湿度传感器

SHT30是Sensirion公司推出的高性价比温湿度传感器,具备±2% RH湿度精度和±0.3°C温度精度,支持I²C接口输出,响应时间快,稳定性高。该传感器内置校准电路、温湿度补偿算法与CRC校验机制,保障数据准确性与可靠性,长期漂移控制在极低范围。在本项目中,SHT30可实现对办公、寝室等环境温湿状态的实时监测,为App端健康提醒、天气联动提供数据支撑。模块体积紧凑,价格适中,非常适合成本敏感型消费类电子产品。

惯性测量单元(IMU)

BMI323是Bosch Sensortec推出的一款低功耗六轴惯性传感器,集成三轴加速度计与三轴陀螺仪,支持I²C/SPI双接口输出,具备高达1600Hz的数据输出率与灵活的量程配置(±2g~±16g、±125°/s~±2000°/s)。该器件内置FIFO缓存与运动检测引擎,可实现敲击识别、拿起检测、翻转触发等智能功能,适用于智能穿戴、运动感知和静音交互等场景。

在智能水杯垫中,BMI323可用于精准检测水杯拿放、震动过滤以及用户午休后自然唤醒的微动作识别。六轴数据融合不仅提升状态识别鲁棒性,也为后续扩展手势交互等功能提供基础。其低功耗运行模式(<1mA)和小型封装使其非常适合本项目对续航与空间的双重要求。

三、模块设计

原理图

在原理图部分,主要是在第一期的基础上新增了IIC数字外设设计,包括BMP390,SHT30,BMI323,从而实现温度、湿度、气压、陀螺仪等数据的采集与分析。其中ist8310为冗余设计,在本期中并未使用到。

PCB

PCB设计中,我们将形状从之前核心板的长方形修改为了圆形,从而便于适配后期外壳的设计。

实物图

四、软件调试介绍

BMP390测试

基于 Adafruit 官方 BMP3XX 库,实现对 BMP390 气压与温度传感器的初始化、配置与数据读取,并通过串口输出温度(°C)、压力(hPa)与估算高度(m)数据,从而验证BMP390设备能否正常工作。关键代码如下:

1. I²C初始化与传感器连接

Wire.begin(SDA_PIN, SCL_PIN);

if (!bmp.begin_I2C(0x76, &Wire)) {
Serial.println("Could not find a valid BMP3 sensor, check wiring!");
while (1);
}

首先初始化 IIC 总线,指定 SDA/SCL 引脚,随后通过 begin_I2C() 尝试与 BMP390 传感器建立通信。默认地址为 0x76,符合PCB设计中 SDO口 接地时的地址设定。

2. 传感器配置:过采样与滤波设置

bmp.setTemperatureOversampling(BMP3_OVERSAMPLING_8X);
bmp.setPressureOversampling(BMP3_OVERSAMPLING_4X);
bmp.setIIRFilterCoeff(BMP3_IIR_FILTER_COEFF_3);
bmp.setOutputDataRate(BMP3_ODR_50_HZ);

接着配置传感器的工作参数,包括温度与气压的过采样倍率、IIR 滤波器系数以及数据输出频率。8倍温度过采样和4倍压力过采样有助于提高精度,适合静态或低动态场景。IIR 滤波系数设置为3,可有效滤除短时间噪声波动。数据输出频率设为 50Hz。

3. 数据读取执行

if (! bmp.performReading()) {
Serial.println("Failed to perform reading :(");
return;
}

在主循环中,每轮数据读取前调用 performReading() 函数执行一次完整采样并更新内部缓存。该函数会自动触发传感器采样并等待数据完成,是使用 Adafruit 封装库的标准调用流程。若读取失败,程序将输出提示并跳过本次打印。

4. 温度与气压打印

Serial.print("Temperature = ");
Serial.print(bmp.temperature);
Serial.println(" *C");

Serial.print("Pressure = ");
Serial.print(bmp.pressure / 100.0);
Serial.println(" hPa");

读取完成后,依次输出当前环境的温度与气压值,其中温度以摄氏度(°C)为单位,气压单位转换为百帕(hPa)。由于 Adafruit 库已在内部封装原始数据读取与浮点转换,因此无需开发者自行计算 LSB 转换,极大提升了开发效率与稳定性。该输出可直接用于调试对比气候变化趋势,或用于高度估算。

5. 高度估算与海平面压力补偿

Serial.print("Approx. Altitude = ");
Serial.print(bmp.readAltitude(SEALEVELPRESSURE_HPA));
Serial.println(" m");

最后,基于当前读取到的气压值,调用 readAltitude() 估算海拔高度。该方法内部基于国际标准大气公式,将当前压力与设定的海平面压力(默认 1013.25 hPa)对比换算为相对高度。

SHT30测试

基于 Sensirion 官方 SHT3x 驱动库,实现对 SHT30 温湿度传感器的初始化、采样与数据读取,并通过串口输出当前环境的温度(°C)与相对湿度(%RH)数据,从而验证 SHT30 设备的通信与传感功能是否正常。关键代码如下:

1. IIC初始化

Wire.begin(SDA_PIN, SCL_PIN);
ClosedCube_SHT31D sht3xd;

首先初始化 IIC 总线并创建传感器对象 sht3xd,用于后续封装函数调用。

2. 传感器地址初始化与序列号读取

sht3xd.begin(0x44);
Serial.println(sht3xd.readSerialNumber());

之后将传感器初始化到地址 0x44(SHT30 默认地址),并尝试读取其唯一序列号以确认连接是否成功。若读取失败,将输出 0 或错误码,通常意味着通信异常。

3. 启动周期性测量模式(Periodic Mode)

sht3xd.periodicStart(SHT3XD_REPEATABILITY_HIGH, SHT3XD_FREQUENCY_10HZ);

之后调用函数启动周期采样模式,设置为高重复性(即高精度)和10Hz采样频率。周期模式是 SHT3x 特有特性,能在后台自动完成采样并缓存结果,降低主控资源消耗并提升读取效率。

4. 数据读取与错误处理

SHT31D result = sht3xd.periodicFetchData();

程序循环中调用 periodicFetchData() 读取最新的温湿度数据封装结构体 SHT31D,其中包含温度 t、湿度 rh 以及错误码字段 error。该机制避免手动处理原始寄存器和数据位,提升代码简洁性和安全性。若读取失败,返回的错误码会被打印到串口,方便调试定位。

5. 串口格式化输出

Serial.print(result.t);
Serial.print("C, RH=");
Serial.print(result.rh);
Serial.println("%");

一旦数据采集成功,系统会将当前温度与湿度以标准文本格式输出到串口,单位分别为摄氏度(°C)与相对湿度(%RH)。该输出适配人类可读格式,适合调试观察、实验记录或接入串口数据采集平台,验证传感器精度与环境响应特性。

BMI323测试

为验证六轴惯性传感器 BMI323 的正常通信与数据采集功能,我们编写了基于 Arduino 平台Wire 库的调试程序,实现了传感器的 IIC 通讯初始化、功能配置、数据采样与串口输出。关键代码如下:

1. IIC初始化配置

#define SDA_PIN 15
#define SCL_PIN 13

Wire.begin(SDA_PIN, SCL_PIN);
Wire.setClock(400000); // 400kHz I2C clock

首先初始化 IIC 总线,指定使用的 SDA 和 SCL 引脚,并将通信速率设置为 400kHz 的快速模式。在默认模式(100kHz)下,读取六轴数据可能存在响应滞后,因此此处通过设定较高的速率提升数据吞吐能力。SDA 和 SCL 分别对应 BMI323 的数据与时钟引脚,需确保外部已加上合适的上拉电阻(如4.7kΩ)以维持总线高电平稳定。

2. 芯片 ID 读取与地址确认

uint16_t chipID = readRegister16(CHIP_ID_REG, BMI323_I2C_ADDR_1);
if ((chipID & 0xFF) == 0x43 || (chipID & 0xFF) == 0x41) {
bmi323_i2c_addr = BMI323_I2C_ADDR_1;
}

该段用于读取 BMI323 的芯片 ID(地址 0x00)以确认器件是否连接正常。芯片的低8位 ID 预计为 0x43 或 0x41,根据官方文档判定是否为有效识别。程序使用此判断结果设置通信地址并继续后续初始化,否则中止执行。这一步用于调试判断 IIC 是否连通。

3. 软件复位指令

writeRegister16(CMD_REG, SOFT_RESET_CMD);
delay(5);

之后向 BMI323 的命令寄存器(0x7E)写入特定的软复位指令(0xDEAF),以清除传感器上电后可能存在的异常状态或历史配置。复位执行后传感器内部寄存器恢复出厂默认值,确保接下来的初始化配置具备一致的基础状态。延时5ms用于等待设备内部重启完成,这是确保可靠初始化的重要步骤。

4. Feature Engine 启动流程

writeRegister16(FEATURE_IO0_REG, 0x0000);
writeRegister16(FEATURE_IO2_REG, 0x012C);
writeRegister16(FEATURE_IO_STATUS_REG, 0x0001);
writeRegister16(FEATURE_CTRL_REG, 0x0001);

BMI323 的高级功能(如运动检测与传感融合)需要启用 Feature Engine,该段代码完成相关寄存器的设置与启动流程。首先清除状态,然后配置启动参数,最后通过控制寄存器触发功能模块。此处还包含轮询机制判断启动是否成功,是确保传感器能返回有效加速度/陀螺仪数据的前提。

5. 原始数据读取与物理单位转换

uint16_t accX = readRegister16(ACC_DATA_X_REG);
float ax = convertAccelData(accX); // 转换为 g 单位

接着就是读取 BMI323 的加速度 X 轴原始数据寄存器,并将其转换为标准重力单位(g)。传感器输出为有符号16位整数,代表 ±8g 范围内的加速度。转换函数 convertAccelData() 使用当前量程下的 LSB 值 进行归一化处理。该机制同样适用于陀螺仪数据,确保串口输出为可直接理解的物理量,便于分析与调试。

6. 串口定时输出与数据有效性检查

void loop() {
  // Limit output to 20Hz
  unsigned long currentTime = millis();
  if (currentTime - lastPrintTime < printInterval) return;
  lastPrintTime = currentTime;


  // Read sensor data
  uint16_t accX = readRegister16(ACC_DATA_X_REG);
  uint16_t accY = readRegister16(ACC_DATA_Y_REG);
  uint16_t accZ = readRegister16(ACC_DATA_Z_REG);
  uint16_t gyrX = readRegister16(GYR_DATA_X_REG);
  uint16_t gyrY = readRegister16(GYR_DATA_Y_REG);
  uint16_t gyrZ = readRegister16(GYR_DATA_Z_REG);
  uint16_t tempRaw = readRegister16(TEMP_DATA_REG);


  // Convert to physical units
  float ax = convertAccelData(accX);
  float ay = convertAccelData(accY);
  float az = convertAccelData(accZ);
  float gx = convertGyroData(gyrX);
  float gy = convertGyroData(gyrY);
  float gz = convertGyroData(gyrZ);
  float temp = convertTempData(tempRaw);


  // Print valid data in CSV format
  if (!isnan(ax) && !isnan(ay) && !isnan(az) &&
      !isnan(gx) && !isnan(gy) && !isnan(gz)) {
    Serial.print(ax, 3); Serial.print(",");
    Serial.print(ay, 3); Serial.print(",");
    Serial.print(az, 3); Serial.print(",");
    Serial.print(gx, 2); Serial.print(",");
    Serial.print(gy, 2); Serial.print(",");
    Serial.print(gz, 2); Serial.print(",");
    Serial.println(isnan(temp) ? "NAN" : String(temp, 1));
  }
}

该段代码控制数据输出频率,并将六轴传感器数据和温度值输出至串口。通过时间差限制,从而控制数据的采集频率。

五、功能展示

BMP390测试

SHT30测试

BMI323测试

六、心得体会

感谢得捷电子与硬禾提供的这次学习的机会。本次硬件设计过程中,在第一期核心板的基础上顺利集成了三种IIC传感器,完成了温湿度、气压和六轴姿态数据的采集与调试,进一步完善了系统的环境感知能力。通过实际调试,我加深了对I²C通信与传感器配置的理解,取得了不小的收获。

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