风筝
发表于: 2023-2-23 20:58:54 | 显示全部楼层

现今越来越多的人喜欢玩无人机,了解无人机能到达的高度是一件很好的事情。像博世的BMP388这样速度极快、温度稳定、精确定位的气压传感器可能是您下一次制作无人机时进行高度跟踪的完美选择。


硬件概述

该模块的核心是博世的最新一代数字气压和温度传感器 – BMP388


BMP388是一款非常小、超快、精确、低功耗、低噪声的绝对气压传感器。 它可以实现精确的高度跟踪,非常适合无人机应用或任何想要跟踪海拔高度的项目。

BMP388-Module-Hardware-Overview-Chip.jpg


BMP388可以测量300hPa到1250hPa的气压,相对精度为8帕斯卡(Pascals),相当于大约±0.5米的高度。


BMP388有一个片上温度传感器,可用于补偿环境变化和校准测量值。 这是一个相当精确的温度传感器,可测量-40˚C至+85˚C范围内的芯片温度,精度为±1˚C。


电源

该模块带有一颗MIC5219 3.3V精密稳压器和电压电平转换器,因此您可以放心地与您最喜欢的3.3V或5V微控制器一起使用。

BMP388-Module-Voltage-Regulator-Translator.jpg


BMP388 在测量期间消耗的电流小于0.7mA,在睡眠模式下仅为2µA。 这种低功耗允许在手机、可穿戴设备或智能手表等电池驱动设备中实施。


I2C接口

传感器使用I2C接口与Arduino进行通信。 它支持两个独立的I2C地址:0x77H 和0x76H。 这允许两个BMP388模块在同一总线上使用或避免与总线上的另一个设备发生地址冲突。

BMP388-Module-I2C-Address-Selection-Pin.jpg


SDO引脚决定模块的I2C地址。 该引脚内置上拉电阻。 因此,当您不连接SDO引脚时,默认I2C地址为0x77H,当您将其连接到GND时,该线被拉低,I2C地址变为0x76H。


SPI接口

传感器还可以通过SPI接口进行通信。


运行模式

BMP388有3种运行模式:

●   SLEEP_MODE:将设备置于非活动待机状态(不执行测量)。

●   NORMAL_MODE:执行连续转换,以待机时间分隔。

●   FORCED_MODE:执行单次转换,完成后返回SLEEP_MODE。


FIFO先进先出缓冲器

BMP388嵌入了一个512字节的FIFO(先进先出)缓冲区,用于存储多达72个压力和/或温度测量结果。FIFO缓冲区可以减轻微控制器从传感器读取每个新数据样本的负担,从而节省系统功耗。


中断

BMP388有一个中断 (INT) 输出引脚,可以通过中断驱动测量而不是使用轮询,从而允许主机微控制器在传感器收集数据的同时执行其他任务。 可以为3个不同的来源启用中断:

●   数据就绪:在压力和温度测量结束且转换结果存储到数据寄存器和FIFO后触发。

●   FIFO阈值:当FIFO的填充水平达到预设限制时触发。

●   FIFO充满:当FIFO已满且未来数据即将丢失时触发。


INT 引脚输出驱动可以是:PUSH_PULL或OPEN_COLLECTOR,INT引脚的电平可以是:ACTIVE_LOW或ACTIVE_HIGH,中断本身可以是:UNLATCHED或LATCHED。 在UNLATCHED模式下,中断信号在 2.5ms后自动清除,而在LATCHED模式下,中断信号保持有效,直到数据被读取。


BMP388模块的引脚分布

现在让我们看一下引脚分布。

BMP388-Module-Pinout.png


电源引脚:

VCC 是电源引脚。 您可以将它连接到Arduino的5V输出。

3Vo 是稳压器输出的3.3V。 如果需要,您可以从中获取高达100mA的电流。

GND 是电源和逻辑的公共地。


SPI逻辑引脚:

SCK 是SPI时钟引脚,它是芯片的输入。

SDO 是串行数据输出 (MISO) 引脚,用于将数据从BMP388发送到您的微控制器。

SDI 是串行数据输入 (MOSI) 引脚,用于从微控制器发送到BMP388的数据。

CS 是芯片选择引脚,将其拉低以启用SPI通信。


I2C逻辑引脚:

SCK 也是I2C时钟引脚,连接到单片机I2C时钟线。

SDI 也是I2C数据引脚,连接到单片机I2C数据线。

SDO 引脚决定了模块的I2C地址。


中断引脚:

INT 是中断引脚。BMP388可以编程为在某些事件上产生中断。


BMP388模块与Arduino开发板的硬件连接

现在我们已经了解了关于模块的一切,可以开始将它连接到Arduino上了!


I2C接线

如果您想通过I2C接口连接,请使用此种接线方法。


首先将VCC引脚连接到电源,3V-5V就可以了。 使用与您的微控制器逻辑相同的电压。对于大多数Arduino,使用5V。 对3.3V逻辑设备,使用3.3V。将GND连接到公共地。


将SCK引脚连接到I2C时钟引脚,将SDI引脚连接到Arduino的I2C数据引脚。在Arduino UNO R3开发板上,SDA和 SCL位于靠近AREF引脚的排针上。 它们也被称为 A5 (SCL) 和 A4 (SDA)。

Wiring-BMP388-Module-with-Arduino-through-I2C-Interface.png


SPI接线

由于它是一个支持SPI的传感器,您可以使用硬件或软件SPI。 但是,建议您使用硬件SPI引脚,因为它们比使用另一组引脚位转换接口代码要快得多。


同样,每个Arduino开发都有不同的SPI引脚,应相应地进行连接。 对于UNO/Nano V3.0等Arduino,这些引脚是数字13 (SCK)、12 (MISO)、11 (MOSI) 和 10 (SS)。

Wiring-BMP388-Module-with-Arduino-through-SPI-Interface.png


一旦您的模块连接到Arduino开发板,就可以编写一些代码了!


库安装

要开始读取传感器数据,您需要安装Adafruit BMP3XX库。 它可以从Arduino库管理器获得。


要安装库,请导航至 Sketch > Include Library > Manage Libraries…等待库管理器下载库索引并更新已安装库的列表。

Manage-Libraries.png


输入adafruit bmp3xx过滤搜索结果并安装库。

Adafruit-BMP3XX-Library-Installation.png


BMP3XX传感器库使用了Adafruit传感器支持后端。 因此,在库管理器中搜索 Adafruit Unified Sensor 并安装。

Adafruit-Unified-Sensor-Library-Installation.png


Arduino代码 - 读取气压、海拔高度和温度

下面是一个基本的Arduino草图。 将其上传到您的Arduino。

  1. #include <Wire.h>
  2. #include <SPI.h>
  3. #include <Adafruit_Sensor.h>
  4. #include "Adafruit_BMP3XX.h"

  5. //Uncomment if you want to use SPI
  6. //#define BMP_SCK 13
  7. //#define BMP_MISO 12
  8. //#define BMP_MOSI 11
  9. //#define BMP_CS 10

  10. #define SEALEVELPRESSURE_HPA (1013.25)

  11. Adafruit_BMP3XX bmp;

  12. void setup() {
  13.   Serial.begin(115200);
  14.   while (!Serial);

  15.   if (!bmp.begin_I2C()) {   // hardware I2C mode, can pass in address & alt Wire
  16.   //if (! bmp.begin_SPI(BMP_CS)) {  // hardware SPI mode  
  17.   //if (! bmp.begin_SPI(BMP_CS, BMP_SCK, BMP_MISO, BMP_MOSI)) {  // software SPI mode
  18.     Serial.println("Could not find a valid BMP3 sensor, check wiring!");
  19.     while (1);
  20.   }

  21.   // Set up oversampling and filter initialization
  22.   bmp.setTemperatureOversampling(BMP3_OVERSAMPLING_8X);
  23.   bmp.setPressureOversampling(BMP3_OVERSAMPLING_4X);
  24.   bmp.setIIRFilterCoeff(BMP3_IIR_FILTER_COEFF_3);
  25.   bmp.setOutputDataRate(BMP3_ODR_50_HZ);
  26. }

  27. void loop() {
  28.   if (! bmp.performReading()) {
  29.     Serial.println("Failed to perform reading :(");
  30.     return;
  31.   }
  32.   Serial.print("Temperature = ");
  33.   Serial.print(bmp.temperature);
  34.   Serial.println(" *C");

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

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

  41.   Serial.println();
  42.   delay(2000);
  43. }
复制代码

您应该可以在串口监视器看到很多显示气压、温度和高度值。尝试四处移动传感器并注意数据如何变化。

BMP388-Sensor-Arduino-Output.png


代码说明

首先草图包括四个必要的库 - Wire.h(用于I2C)、SPI.h(用于SPI)、Adafruit_Sensor.h和Adafruit_BMP3XX.h。

  1. #include <Wire.h>
  2. #include <SPI.h>
  3. #include <Adafruit_Sensor.h>
  4. #include "Adafruit_BMP3XX.h"
复制代码

草图使用I2C通信协议与传感器通信。 但是,如果您想使用 SPI,草图已准备就绪。 您只需取消注释以下定义SPI引脚的代码行。

  1. //#define BMP_SCK 13
  2. //#define BMP_MISO 12
  3. //#define BMP_MOSI 11
  4. //#define BMP_CS 10
复制代码

接下来,定义一个名为SEALEVELPRESSURE_HPA的变量。 此变量以milibar为单位保存海平面气压,并用于通过将给定气压与海平面气压进行比较来估算高度。 此草图使用默认值,但为了获得准确的结果,请将该值替换为您所在位置的当前海平面气压。

  1. #define SEALEVELPRESSURE_HPA (1013.25)
复制代码

以下代码行创建Adafruit_BMP3XX对象bmp

  1. Adafruit_BMP3XX bmp;
复制代码

setup()函数中,我们初始化串口通信并调用begin()函数。


bmp.begin_I2C()函数初始化I2C接口并检查芯片ID是否正确。 然后它使用软复位重置芯片并等待传感器在唤醒后进行校准。 同样,bmp.begin_SPI() 函数初始化SPI接口。 如果要使用SPI,需要取消对应if的注释。

  1. Serial.begin(115200);
  2. while (!Serial);
  3. Serial.println("Adafruit BMP388 / BMP390 test");

  4. if (!bmp.begin_I2C()) {   // hardware I2C mode, can pass in address & alt Wire
  5.         //if (! bmp.begin_SPI(BMP_CS)) {  // hardware SPI mode  
  6.         //if (! bmp.begin_SPI(BMP_CS, BMP_SCK, BMP_MISO, BMP_MOSI)) {  // software SPI mode
  7.         Serial.println("Could not find a valid BMP3 sensor, check wiring!");
  8.         while (1);
  9. }
复制代码

接下来,我们为传感器设置一些参数。

  1. bmp.setTemperatureOversampling(BMP3_OVERSAMPLING_8X);
  2. bmp.setPressureOversampling(BMP3_OVERSAMPLING_4X);
  3. bmp.setIIRFilterCoeff(BMP3_IIR_FILTER_COEFF_3);
  4. bmp.setOutputDataRate(BMP3_ODR_50_HZ);
复制代码

在loop()中,我们调用bmp.performReading()函数来执行读取。 完成后,我们可以使用点运算符访问对象的 (bmp) 实例变量。

bmp.temperature 返回温度读数。

bmp.pressure 返回大气压力读数。

bmp.readAltitude(SEALEVELPRESSURE_HPA) 函数根据指定的大气压力(以 hPa 为单位)和海平面气压(以 hPa 为单位)计算高度(以米为单位)。

  1. void loop() {
  2.   if (! bmp.performReading()) {
  3.     Serial.println("Failed to perform reading :(");
  4.     return;
  5.   }
  6.   Serial.print("Temperature = ");
  7.   Serial.print(bmp.temperature);
  8.   Serial.println(" *C");

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

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

  15.   Serial.println();
  16.   delay(2000);
  17. }
复制代码


跳转到指定楼层
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题 714 | 回复: 1501



手机版|

GMT+8, 2024-12-22 17:07 , Processed in 0.067836 second(s), 9 queries , Gzip On, MemCache On. Powered by Discuz! X3.5

YiBoard一板网 © 2015-2022 地址:河北省石家庄市长安区高营大街 ( 冀ICP备18020117号 )

快速回复 返回顶部 返回列表