BML390L数字大气压传感器

简介

BMP390L是一款博世新研发的工业级专用数字气压传感器,具有极高的温度稳定性、低漂移、低功耗(睡眠电流仅54uA,最高功耗测量模式为650uA)和低噪声影响(0.02Pa)的特性。该产品绝对精度最大误差低于50Pa,相对精度可达±3Pa(相当于25cm),相比前代提升了166.7%,保证了测量的精准度。此外,新款在长期稳定性表现上也远超前代的表现,12个月的长期稳定性误差仅为16Pa。精准稳定低功耗的高度检测使得该产品十分适合用于GPS信号无法覆盖的室内定位等应用中,且该产品供货期长达十年,因此可以放心集成到您的设备中。

特性

  • 高精度(绝对误差<50 Pa,相对误差<3 Pa)
  • 长期稳定性高(±16 Pa/年)
  • 极高的温度稳定性和低漂移性
  • 超低的工作功耗(<650uA)

应用场景

  • 垂直速度指示(如上升/下沉速度)
  • 物联网 (IoT)
  • GPS 导航增强(例如改进初次定位时间、航位推算、斜率检测)
  • 室内导航和定位(室内检测、电梯检测)
  • 户外导航,休闲和运动应用
  • 天气预报
  • 健康保健应用(如肺活量测定)
  • 健身应用(如增强热量检测)
  • 增强现实和虚拟现实应用
  • 情境感知

技术规格

  • 工作电压:3.3V
  • 工作电流:睡眠模式(54uA)/正常模式(357~650uA)
  • 接口方式:I2C/SPI
  • I2C地址:0x77(默认地址)/0x76(可选:SDO引脚连接GND)
  • 压力感应范围:300~1250 hPa
  • 相对精度:±0.03hPa(相当于25cm)(@700-1100hPa,25-40°C)
  • 绝对精度:±0.50hPa
  • 温度偏移系数:±0.6Pa/K(@900hPa,25-40°C)
  • 长期稳定性:±0.16hPa/年
  • ODR精度:±2%~±12%
  • 启动时间:2ms
  • 工作温度范围:-40℃ ~ +85℃(在0℃~+65℃下可使用全精度测量)
  • 模块尺寸:15*20(mm)

引脚说明


序号 丝印 功能描述
1 VCC 3.3V~5.5V电源输入
2 3V3 3.3V电源输出/输入
3 GND 电源负极
4 SCL I2C时钟线
5 SDA I2C数据线
6 SCK SPI时钟控制线
7 SDI SPI数据线(输入)
8 SDO SPI数据线(输出)
9 CS SPI 片选线
10 INT 中断引脚

注意:

  • 仅支持3.3V主板
  • 所有数据输出电压均为3.3V
  • 将SDO引脚拉低可切换I2C地址为:0x77

不同通信方式连线提示:

- I2C:0x77(默认)

- I2C:0x76

- SPI

注意:cs引脚可自行选择不冲突的引脚

- 中断引脚连接

主板 默认连接引脚
UNO/MEGA2560 D2
Leonardo D3
Micro:bit P0
ESP32/ESP8266/ARDUINO_SAM_ZERO(M0) D6
Raspberry Pi GPIO25

M0 使用教程

请按接线图所示将传感器与M0(或其它主板)相连接即可。

准备

  • 硬件

    • 1 x Firebeetle Board-M0
    • 1 x BMP390L数字气压传感器
    • 若干 杜邦线
  • 软件

    • Arduino IDE, 点击下载Arduino IDE
    • 库文件和示例程序,可在ARDUINO中直接下载步骤如下图所示:

    下载库步骤1


    下载库步骤2

关于如何安装库文件,点击链接

关于如何使用Firebeetle Board-M0,点击链接

注意:教程示例使用的是成都市温江区(中国)海拔540米,请使用者实际使用时换成本地海拔校准

  • 主要API接口函数列表

  
  /**
  * @brief 初始化函数
  * @return 返回0表示初始化成功,返回其他值表示初始化失败,返回错误码
  */
  virtual int begin(void);

  /**
  * @brief 让用户方便配置常用的采样模式
  * @param mode:
  *        eUltraLowPrecision,超低精度,适合天气监控(最低功耗),电源模式为强制模式
  *        eLowPrecision,低精度,适合随意的检测,电源模式为正常模式
  *        eNormalPrecision1,标准精度1,适合在手持式设备上动态检测(例如在手机上),电源模式为正常模式
  *        eNormalPrecision2,标准精度2,适合无人机,电源模式为正常模式
  *        eHighPrecision,高精度,适合在低功耗手持式设备上(例如在手机上),电源模式为正常模式
  *        eUltraPrecision,超高精度,适合室内的导航,采集速率会极低,采集周期1000ms,电源模式为正常模式
  * @return 返回True表示配置成功,返回False表示配置失败,保持原来的状态
  */
  bool setSamplingMode(ePrecisionMode_t mode);

  /**
  * @brief 获取传感器当前采样模式下的采样周期
  * @return 返回采样周期,单位us
  */
  uint32_t getSamplingPeriodUS(void);

  /**
  * @brief 从寄存器获取温度测量值,工作范围(-40 ‒ +85 °C)
  * @return 返回温度测量值,单位是℃
  */
  float readTempC(void);

  /**
  * @brief 从寄存器获取压力测量值,工作范围(300‒1250 hPa)
  * @brief 若之前提供了基准值,则根据校准的海平面大气压,计算当前位置气压的绝对值
  * @return 返回压力测量值,单位是Pa
  */
  float readPressPa(void);

  /**
  * @brief 以给定的当前位置海拔做为基准值,为后续压力和海拔数据消除绝对差
  * @param altitude 当前位置海拔高度
  * @return 传入基准值成功,返回ture,失败返回false
  */
  bool calibratedAbsoluteDifference(float altitude);

  /**
  * @brief 根据传感器所测量大气压,计算海拔高度
  * @brief 若之前提供了基准值,则根据校准的海平面大气压,计算当前位置海拔绝对高度
  * @return 返回海拔高度,单位m
  */
  float readAltitudeM(void);

  /**
  * @brief 获取FIFO中缓存的数据
  * @brief 温度单位摄氏度,压力单位帕
  */
  void getFIFOData(float &FIFOTemperatureC, float &FIFOPressurePa);

  /**
  * @brief 传感器FIFO清空命令和软复位命令
  * @param mode 传感器基本命令,三种命令:
  *        BMP3XX_CMD_NOP,空命令
  *        BMP3XX_CMD_FIFO_FLUSH,清除FIFO中的所有数据,不改变FIFO配置
  *        BMP3XX_CMD_SOFTRESET,触发重置,所有用户配置设置将被其默认状态覆盖
  */
  void setCommand(uint8_t mode);

  /**
  * @brief FIFO水位设置配置
  * @param WTMSetting 需要设置的FIFO水位(0-511),FIFO填充达到水位值触发中断
  */
  void setFIFOWTM(uint16_t WTMSetting);

  /**
  * @brief FIFO配置一(FIFO1)
  * @param mode 需要设置的FIFO模式,下列模式相加为mode:
  *        eFIFODIS: 禁用FIFO ,eFIFOEN: 启用FIFO
  *        eFIFOStopOnFullDIS: 写满时继续写入 ,eFIFOStopOnFullEN: 写满时停止写入
  *        eFIFOTimeDIS: 禁用 ,eFIFOTimeEN: 启用在最后一个有效数据帧之后返回传感器时间帧
  *        eFIFOPressDIS: 禁用压力数据缓存 ,eFIFOPressEN: 启用压力数据缓存
  *        eFIFOTempDIS: 禁用温度数据缓存 ,eFIFOTempEN: 启用温度数据缓存
  */
  void setFIFOMode1(uint8_t mode);

  /**
  * @brief FIFO配置二(FIFO2)
  * @param mode 需要设置的FIFO模式,下列模式相加为mode:
  *        8种压力和温度数据的FIFO下采样选择(1-128), 系数为2^fifo_subsampling(0-7):
  *          eFIFOSubsampling0, eFIFOSubsampling1, eFIFOSubsampling2, eFIFOSubsampling3,
  *          eFIFOSubsampling4, eFIFOSubsampling5, eFIFOSubsampling6, eFIFOSubsampling7,
  *        eFIFODataSelectDIS: 未过滤数据(补偿或未补偿) ,eFIFODataSelectEN: 过滤数据(补偿或未补偿),外加两种保留状态:与“unfilt”相同
  */
  void setFIFOMode2(uint8_t mode);

  /**
  * @brief 中断配置(INT)
  * @param mode 需要设置的中断模式,下列模式相加为mode:
  *        中断引脚输出模式: eINTPinPP: 推挽 ,eINTPinOD: 开漏
  *        中断引脚有效电平: eINTPinActiveLevelLow: 低电平有效 ,eINTPinActiveLevelHigh: 高电平有效
  *        中断寄存器锁定: eINTLatchDIS: 禁用 ,eINTLatchEN: 启用
  *        FIFO水位到达中断: eINTFWTMDIS: 禁用 ,eINTFWTMEN: 启用
  *        FIFO存满中断: eINTFFullDIS: 禁用 ,eINTFFullEN: 启用
  *        中断引脚初始(无效、无中断)电平: eINTInitialLevelLOW: 低电平 ,eINTInitialLevelHIGH: 高电平
  *        温度/压力数据准备中断: eINTDataDrdyDIS: 禁用 ,eINTDataDrdyEN: 启用
  */
  void setINTMode(uint8_t mode);

  /**
  * @brief 测量模式和电源模式的配置
  * @param mode 需要设置的测量模式和电源模式,下列模式相加为mode:
  *        ePressDIS: 禁用压力测量 ,ePressEN: 启用压力测量
  *        eTempDIS: 禁用温度测量 ,eTempEN: 启用温度测量
  *        eSleepMode, eForcedMode, eNormalMode 三种模式:
  *          睡眠模式:上电复位后默认设置为睡眠模式。在睡眠模式下,不执行任何测量,并且功耗最少。所有寄存器均可访问;可以读取芯片ID和补偿系数。
  *          强制模式:在强制模式下,根据选择的测量和滤波选项进行单个测量。测量完成后,传感器返回睡眠模式,测量结果可从数据寄存器中获得。
  *          正常模式:在测量周期和待机周期之间连续循环,输出数据率(output data rates)与ODR模式设置有关。
  */
  void setPWRMode(uint8_t mode);

  /**
  * @brief 压力和温度测量的过采样配置(OSR:over-sampling register)
  * @param mode 需要设置的压力和温度测量的过采样模式,下列模式相加为mode:
          6种压力过采样模式:
            ePressOSRMode1,  压力采样×1,16 bit / 2.64 Pa(推荐温度过采样×1)
            ePressOSRMode2,  压力采样×2,16 bit / 2.64 Pa(推荐温度过采样×1)
            ePressOSRMode4,  压力采样×4,18 bit / 0.66 Pa(推荐温度过采样×1)
            ePressOSRMode8,  压力采样×8,19 bit / 0.33 Pa(推荐温度过采样×2)
            ePressOSRMode16,  压力采样×16,20 bit / 0.17 Pa(推荐温度过采样×2)
            ePressOSRMode32,  压力采样×32,21 bit / 0.085 Pa(推荐温度过采样×2)
          6种温度过采样模式
            eTempOSRMode1,  温度采样×1,16 bit / 0.0050 °C
            eTempOSRMode2,  温度采样×2,16 bit / 0.0025 °C
            eTempOSRMode4,  温度采样×4,18 bit / 0.0012 °C
            eTempOSRMode8,  温度采样×8,19 bit / 0.0006 °C
            eTempOSRMode16,  温度采样×16,20 bit / 0.0003 °C
            eTempOSRMode32,  温度采样×32,21 bit / 0.00015 °C
  */
  void setOSRMode(uint8_t mode);

  /**
  * @brief 细分/二次采样的方式设置输出数据率配置(ODR:output data rates)
  * @param mode 需要设置的输出数据率,可配置模式:
  *        BMP3XX_ODR_200_HZ,BMP3XX_ODR_100_HZ,BMP3XX_ODR_50_HZ,BMP3XX_ODR_25_HZ,BMP3XX_ODR_12P5_HZ,
  *        BMP3XX_ODR_6P25_HZ,BMP3XX_ODR_3P1_HZ,BMP3XX_ODR_1P5_HZ,BMP3XX_ODR_0P78_HZ,BMP3XX_ODR_0P39_HZ,
  *        BMP3XX_ODR_0P2_HZ,BMP3XX_ODR_0P1_HZ,BMP3XX_ODR_0P05_HZ,BMP3XX_ODR_0P02_HZ,BMP3XX_ODR_0P01_HZ,
  *        BMP3XX_ODR_0P006_HZ,BMP3XX_ODR_0P003_HZ,BMP3XX_ODR_0P0015_HZ
  * @return 返回True表示配置成功,返回False表示配置失败,保持原来的状态
  */
  bool setODRMode(uint8_t mode);

  /**
  * @brief IIR滤波系数配置(IIR filtering)
  * @param mode IIR滤波系数设置,可配置模式:
  *        BMP3XX_IIR_CONFIG_COEF_0,BMP3XX_IIR_CONFIG_COEF_1,BMP3XX_IIR_CONFIG_COEF_3,
  *        BMP3XX_IIR_CONFIG_COEF_7,BMP3XX_IIR_CONFIG_COEF_15,BMP3XX_IIR_CONFIG_COEF_31,
  *        BMP3XX_IIR_CONFIG_COEF_63,BMP3XX_IIR_CONFIG_COEF_127
  */
  void setIIRMode(uint8_t mode);

  /**
  * @brief 获取FIFO已缓存数据大小
  * @return 返回值范围为:0-511
  */
  uint16_t getFIFOLength(void);

  /**
  * @brief 获取FIFO设定的水位值
  * @return 返回值范围为:0-511
  */
  uint16_t getFIFOWTMValue(void);


样例代码1-读取温度,气压和海拔(getTempPress.ino)

  • 选择getTempPress.ino

  • 烧录程序
/*!
 * @file getTempPress.ino
 * @brief 获取传感器测量频率和测量数据(温度,气压,海拔)
 * @n 可以选择传入当前海拔高度,校准传感器,为气压海拔测量值消除误差
 * @n 获取当前测量频率,获取当前测量的温度和气压值
 * @n 海拔高度是由气压测量值和校准值计算而得
 * @copyright   Copyright (c) 2010 DFRobot Co.Ltd (http://www.dfrobot.com)
 * @licence     The MIT License (MIT)
 * @author [qsj](qsj.huang@dfrobot.com)
 * @version  V0.1
 * @date  2021-4-30
 * @get from https://www.dfrobot.com
 * @url https://github.com/DFRobot/DFRobot_BMP3XX
 */
#include <DFRobot_BMP3XX.h>

/** 若使用Gravity系列的产品,则直接选用这两个接口,注释后续接口即可*/
// DFRobot_BMP388_IIC sensor();
// DFRobot_BMP390L_IIC sensor();

/**
* 选择芯片版本BMP388/BMP390L
* 选择通信接口IIC,请注释掉SPI接口
* IIC通信地址设置: eSDOGND: SDO引脚连接到GND,此时I2C地址为0x76
*                   eSDOVDD: SDO引脚连接到VDDIO(3v3),此时I2C地址为0x77
*/
// DFRobot_BMP388_IIC sensor(&Wire, sensor.eSDOVDD);
 DFRobot_BMP390L_IIC sensor(&Wire, sensor.eSDOVDD);
/**
* 选择芯片版本BMP388/BMP390L
* 选择通信接口SPI,请注释掉IIC接口
* 根据SPI片选管脚连接的板上引脚,自行设置digital引脚
* 注意:这里用的csPin是ESP32板子的D3数字引脚,也可以选择其它不冲突的引脚作为外部中断引脚
*/
// uint8_t csPin = D3;
// DFRobot_BMP388_SPI sensor(&SPI, csPin);
// DFRobot_BMP390L_SPI sensor(&SPI, csPin);


/* 如果不需要消除测量绝对差,请注释下面这一行 */
#define CALIBRATE_ABSOLUTE_DIFFERENCE

void setup(void)
{
  Serial.begin(115200);

  int rslt;
  while( ERR_OK != (rslt = sensor.begin()) ){
    if(ERR_DATA_BUS == rslt){
      Serial.println("Data bus error!!!");
    }else if(ERR_IC_VERSION == rslt){
      Serial.println("Chip versions do not match!!!");
    }
    delay(3000);
  }
  Serial.println("Begin ok!");

  /**
  * 让用户方便配置常用的6种采样模式,mode:
  *      eUltraLowPrecision,超低精度,适合天气监控(最低功耗),电源模式为强制模式
  *      eLowPrecision,低精度,适合随意的检测,电源模式为正常模式
  *      eNormalPrecision1,标准精度1,适合在手持式设备上动态检测(例如在手机上),电源模式为正常模式
  *      eNormalPrecision2,标准精度2,适合无人机,电源模式为正常模式
  *      eHighPrecision,高精度,适合在低功耗手持式设备上(例如在手机上),电源模式为正常模式
  *      eUltraPrecision,超高精度,适合室内的导航,采集速率会极低,采集周期1000ms,电源模式为正常模式
  */
  while( !sensor.setSamplingMode(sensor.eUltraPrecision) ){
    Serial.println("Set samping mode fail, retrying....");
    delay(3000);
  }

  delay(100);
  #ifdef CALIBRATE_ABSOLUTE_DIFFERENCE
  /**
  * 根据所给当前位置海拔,校准传感器
  * 此示例使用的是成都市温江区(中国)海拔540米,请使用者实际使用时换成本地海拔校准
  * 如果没有调用此接口,测量数据将不消除绝对误差
  * 注意:此接口只有第一次调用有效
  */
  if( sensor.calibratedAbsoluteDifference(540.0) ){
    Serial.println("Absolute difference base value set successfully!");
  }
  #endif

  /* 获取当前测量模式的采样周期,单位us */
  float sampingPeriodus = sensor.getSamplingPeriodUS();
  Serial.print("samping period : ");
  Serial.print(sampingPeriodus);
  Serial.println(" us");

  /* 获取当前测量模式的采样频率,单位Hz */
  float sampingFrequencyHz = 1000000 / sampingPeriodus;
  Serial.print("samping frequency : ");
  Serial.print(sampingFrequencyHz);
  Serial.println(" Hz");

  Serial.println();
  delay(1000);
}

void loop()
{
  /* 直接读取当前测量的温度数据,单位℃ */
  float temperature = sensor.readTempC();
  Serial.print("temperature : ");
  Serial.print(temperature);
  Serial.println(" C");

  /* 直接读取当前测量的压力数据,单位pa */
  float Pressure = sensor.readPressPa();
  Serial.print("Pressure : ");
  Serial.print(Pressure);
  Serial.println(" Pa");

  /* 读取海拔高度,单位m */
  float altitude = sensor.readAltitudeM();
  Serial.print("Altitude : ");
  Serial.print(altitude);
  Serial.println(" m");

  Serial.println();
  delay(1000);
}

结果

样例代码2-数据中断功能(interruptDataDrdy.ino)

  • 选择interruptDataDrdy.ino

  • 烧录程序
/*!
 * @file interruptDataDrdy.ino
 * @brief 演示数据(温度/压力)准备就绪的中断:
 * @n 当传感器数据测量完毕后,在非中断寄存器锁定状态下,会通过中断引脚(INT)产生一个2.5ms的脉冲信号
 * @copyright   Copyright (c) 2010 DFRobot Co.Ltd (http://www.dfrobot.com)
 * @licence     The MIT License (MIT)
 * @author [qsj](qsj.huang@dfrobot.com)
 * @version  V0.1
 * @date  2021-4-30
 * @get from https://www.dfrobot.com
 * @url https://github.com/DFRobot/DFRobot_BMP3XX
 */
#include <DFRobot_BMP3XX.h>

/**
* 选择芯片版本BMP388/BMP390L
* 选择通信接口IIC,请注释掉SPI接口
* IIC通信地址设置: eSDOGND: SDO引脚连接到GND,此时I2C地址为0x76
*                   eSDOVDD: SDO引脚连接到VDDIO(3v3),此时I2C地址为0x77
* 注意:若使用Gravity系列的产品,IIC通信地址设置默认为:0x77(eSDOVDD)
*/
//DFRobot_BMP388_IIC sensor(&Wire, sensor.eSDOVDD);
 DFRobot_BMP390L_IIC sensor(&Wire, sensor.eSDOVDD);

/**
* 选择芯片版本BMP388/BMP390L
* 选择通信接口SPI,请注释掉IIC接口
* 根据SPI片选管脚连接的板上引脚,自行设置digital引脚
* 注意:这里用的csPin是ESP32板子的D3数字引脚,也可以选择其它不冲突的引脚作为外部中断引脚
*/
// uint8_t csPin = D3;
// DFRobot_BMP388_SPI sensor(&SPI, csPin);
// DFRobot_BMP390L_SPI sensor(&SPI, csPin);


/* 如果不需要消除测量绝对差,请注释下面这一行 */
#define CALIBRATE_ABSOLUTE_DIFFERENCE

/* 中断标志 */
volatile uint8_t flag = 0;
/* 外部中断函数 */
void interrupt()
{
  if(flag ==0){
    flag = 1;
  }
}

void setup(void)
{
  Serial.begin(115200);

  int rslt;
  while( ERR_OK != (rslt = sensor.begin()) ){
    if(ERR_DATA_BUS == rslt){
      Serial.println("Data bus error!!!");
    }else if(ERR_IC_VERSION == rslt){
      Serial.println("Chip versions do not match!!!");
    }
    delay(3000);
  }
  Serial.println("Begin ok!");

  /**
  * 中断配置
  * mode 需要设置的中断模式,下列模式相加为mode:
  *      中断引脚输出模式: eINTPinPP: 推挽 ,eINTPinOD: 开漏
  *      中断引脚有效电平: eINTPinActiveLevelLow: 低电平有效 ,eINTPinActiveLevelHigh: 高电平有效
  *      寄存器锁定中断: eINTLatchDIS: 禁用 ,eINTLatchEN: 启用
  *      FIFO水位到达中断: eINTFWTMDIS: 禁用 ,eINTFWTMEN: 启用
  *      FIFO存满中断: eINTFFullDIS: 禁用 ,eINTFFullEN: 启用
  *      中断引脚初始(无效、无中断)电平: eINTInitialLevelLOW: 低电平 ,eINTInitialLevelHIGH: 高电平
  *      温度/压力数据准备中断: eINTDataDrdyDIS: 禁用 ,eINTDataDrdyEN: 启用
  * 注意:在非锁存模式(eINTLatchDIS)中,中断信号为2.5ms的脉冲信号
  * 提示:当使用eINTPinActiveLevelLow(中断引脚低电平有效)时,需使用eINTInitialLevelHIGH(中断引脚初始高电平),后边中断触发请使用 "FALLING" 
  *       当使用eINTPinActiveLevelHigh(中断引脚低电平有效)时,需使用eINTInitialLevelLOW(中断引脚初始高电平),后边中断触发请使用 "RISING" 
  */
  sensor.setINTMode(sensor.eINTPinPP + 
                    sensor.eINTPinActiveLevelHigh + 
                    sensor.eINTLatchDIS + 
                    sensor.eINTFWTMDIS + 
                    sensor.eINTFFullDIS + 
                    sensor.eINTInitialLevelLOW + 
                    sensor.eINTDataDrdyEN);

  delay(100);
  #ifdef CALIBRATE_ABSOLUTE_DIFFERENCE
  /**
  * 根据所给当前位置海拔,校准传感器
  * 此示例使用的是成都市温江区(中国)海拔540米,请使用者实际使用时换成本地海拔校准
  * 如果没有调用此接口,测量数据将不消除绝对误差
  * 注意:此接口只有第一次调用有效
  */
  if( sensor.calibratedAbsoluteDifference(540.0) ){
    Serial.println("Absolute difference base value set successfully!");
  }
  #endif

  #if defined(ESP32) || defined(ESP8266)
  //默认使用D6引脚作为中断引脚,也可以选择其它不冲突的引脚作为外部中断引脚
  attachInterrupt(digitalPinToInterrupt(D6)/*Query the interrupt number of the D6 pin*/,interrupt,CHANGE);
  #elif defined(ARDUINO_SAM_ZERO)
  //默认使用5引脚作为中断引脚,也可以选择其它不冲突的引脚作为外部中断引脚
  attachInterrupt(digitalPinToInterrupt(5)/*Query the interrupt number of the 5 pin*/,interrupt,CHANGE);
  #else
  /*    The Correspondence Table of AVR Series Arduino Interrupt Pins And Terminal Numbers
   * ---------------------------------------------------------------------------------------
   * |                                        |  DigitalPin  | 2  | 3  |                   |
   * |    Uno, Nano, Mini, other 328-based    |--------------------------------------------|
   * |                                        | Interrupt No | 0  | 1  |                   |
   * |-------------------------------------------------------------------------------------|
   * |                                        |    Pin       | 2  | 3  | 21 | 20 | 19 | 18 |
   * |               Mega2560                 |--------------------------------------------|
   * |                                        | Interrupt No | 0  | 1  | 2  | 3  | 4  | 5  |
   * |-------------------------------------------------------------------------------------|
   * |                                        |    Pin       | 3  | 2  | 0  | 1  | 7  |    |
   * |    Leonardo, other 32u4-based          |--------------------------------------------|
   * |                                        | Interrupt No | 0  | 1  | 2  | 3  | 4  |    |
   * |--------------------------------------------------------------------------------------
   */
  /*                      The Correspondence Table of micro:bit Interrupt Pins And Terminal Numbers
   * ---------------------------------------------------------------------------------------------------------------------------------------------
   * |             micro:bit                       | DigitalPin |P0-P20 can be used as an external interrupt                                     |
   * |  (When using as an external interrupt,      |---------------------------------------------------------------------------------------------|
   * |no need to set it to input mode with pinMode)|Interrupt No|Interrupt number is a pin digital value, such as P0 interrupt number 0, P1 is 1 |
   * |-------------------------------------------------------------------------------------------------------------------------------------------|
   */
  attachInterrupt(/*Interrupt No*/0,interrupt,CHANGE);//Open the external interrupt 0, connect INT1/2 to the digital pin of the main control: 
     //UNO(2), Mega2560(2), Leonardo(3), microbit(P0).
  #endif

  /* 获取当前测量模式的采样周期,单位us */
  float sampingPeriodus = sensor.getSamplingPeriodUS();
  Serial.print("samping period : ");
  Serial.print(sampingPeriodus);
  Serial.println(" us");

  /* 获取当前测量模式的采样频率,单位Hz */
  float sampingFrequencyHz = 1000000 / sampingPeriodus;
  Serial.print("samping frequency : ");
  Serial.print(sampingFrequencyHz);
  Serial.println(" Hz");

  Serial.println();
  delay(1000);
}

void loop()
{
  if(flag == 1){
    flag = 0;
    /* 当数据准备就绪中断触发时,读取海拔高度,单位m */
    float altitude = sensor.readAltitudeM();
    Serial.print("Altitude : ");
    Serial.print(altitude);
    Serial.println(" m");
  }
}

结果

样例代码3-FIFO水位或存满中断功能(interruptUsingFIFO.ino)

  • 选择interruptUsingFIFO.ino

  • 烧录程序
/*!
 * @file interruptUsingFIFO.ino
 * @brief 演示FIFO水位中断或FIFO存满中断:
 * @n 先将FIFO清空一次,然后开始获取FIFO中缓存的测量数据
 * @n 当收到中断引脚发出的FIFO水位中断信号后,将FIFO中的所有数据读出并求其平均值,在打印出来
 * @copyright   Copyright (c) 2010 DFRobot Co.Ltd (http://www.dfrobot.com)
 * @licence     The MIT License (MIT)
 * @author [qsj](qsj.huang@dfrobot.com)
 * @version  V0.1
 * @date  2021-4-30
 * @get from https://www.dfrobot.com
 * @url https://github.com/DFRobot/DFRobot_BMP3XX
 */
#include <DFRobot_BMP3XX.h>

/**
* 选择芯片版本BMP388/BMP390L
* 选择通信接口IIC,请注释掉SPI接口
* IIC通信地址设置: eSDOGND: SDO引脚连接到GND,此时I2C地址为0x76
*                   eSDOVDD: SDO引脚连接到VDDIO(3v3),此时I2C地址为0x77
* 注意:若使用Gravity系列的产品,IIC通信地址设置默认为:0x77(eSDOVDD)
*/
// DFRobot_BMP388_IIC sensor(&Wire, sensor.eSDOGND);
 DFRobot_BMP390L_IIC sensor(&Wire, sensor.eSDOVDD);

/**
* 选择芯片版本BMP388/BMP390L
* 选择通信接口SPI,请注释掉IIC接口
* 根据SPI片选管脚连接的板上引脚,自行设置digital引脚
* 注意:这里用的csPin是ESP32板子的D3数字引脚,也可以选择其它不冲突的引脚作为外部中断引脚
*/
// uint8_t csPin = D3;
// DFRobot_BMP388_SPI sensor(&SPI, csPin);
// DFRobot_BMP390L_SPI sensor(&SPI, csPin);


/* 如果不需要消除测量绝对差,请注释下面这一行 */
#define CALIBRATE_ABSOLUTE_DIFFERENCE

/* 中断标志 */
volatile uint8_t flag = 0;
/* 外部中断函数 */
void interrupt()
{
  if(flag ==0){
    flag = 1;
  }
}

void setup(void)
{
  Serial.begin(115200);

  int rslt;
  while( ERR_OK != (rslt = sensor.begin()) ){
    if(ERR_DATA_BUS == rslt){
      Serial.println("Data bus error!!!");
    }else if(ERR_IC_VERSION == rslt){
      Serial.println("Chip versions do not match!!!");
    }
    delay(3000);
  }
  Serial.println("Begin ok!");

  /**
  * FIFO配置一
  * mode 需要设置的FIFO模式,下列模式相加为mode:
  *      eFIFODIS: 禁用FIFO ,eFIFOEN: 启用FIFO
  *      eFIFOStopOnFullDIS: 写满时继续写入 ,eFIFOStopOnFullEN: 写满时停止写入
  *      eFIFOTimeDIS: 禁用 ,eFIFOTimeEN: 启用在最后一个有效数据帧之后返回传感器时间帧
  *      eFIFOPressDIS: 禁用压力数据存储 ,eFIFOPressEN: 启用压力数据存储
  *      eFIFOTempDIS: 禁用温度数据存储 ,eFIFOTempEN: 启用温度数据存储
  */
  sensor.setFIFOMode1(sensor.eFIFOEN + 
                      sensor.eFIFOStopOnFullDIS + 
                      sensor.eFIFOTimeEN + 
                      sensor.eFIFOPressEN + 
                      sensor.eFIFOTempEN);

  /**
  * FIFO配置二
  * mode 需要设置的FIFO模式,下列模式相加为mode:
  *      8种压力和温度数据的FIFO下采样选择(1-128), 系数为2^fifo_subsampling(0-7):
  *        eFIFOSubsampling0, eFIFOSubsampling1, eFIFOSubsampling2, eFIFOSubsampling3,
  *        eFIFOSubsampling4, eFIFOSubsampling5, eFIFOSubsampling6, eFIFOSubsampling7,
  *      eFIFODataSelectDIS: 未过滤数据(补偿或未补偿) ,eFIFODataSelectEN: 过滤数据(补偿或未补偿),外加两种保留状态:与“unfilt”相同
  */
  sensor.setFIFOMode2(sensor.eFIFOSubsampling2 + 
                      sensor.eFIFODataSelectEN);

  /**
  * 传感器FIFO清空命令和软复位命令
  * mode 传感器基本命令,三种命令:
  *      BMP3XX_CMD_NOP,空命令
  *      BMP3XX_CMD_FIFO_FLUSH,清除FIFO中的所有数据,不改变FIFO配置
  *      BMP3XX_CMD_SOFTRESET,触发重置,所有用户配置设置将被其默认状态覆盖
  */
  sensor.setCommand(BMP3XX_CMD_FIFO_FLUSH);

  /**
  * FIFO水位设置配置
  * WTMSetting 需要设置的FIFO水位(0-511),FIFO填充达到水位值触发中断
  */
  uint16_t FIFOWTM = 500;
  sensor.setFIFOWTM(FIFOWTM);

  /**
  * 中断配置
  * mode 需要设置的中断模式,下列模式相加为mode:
  *      中断引脚输出模式: eINTPinPP: 推挽 ,eINTPinOD: 开漏
  *      中断引脚有效电平: eINTPinActiveLevelLow: 低电平有效 ,eINTPinActiveLevelHigh: 高电平有效
  *      寄存器锁定中断: eINTLatchDIS: 禁用 ,eINTLatchEN: 启用
  *      FIFO水位到达中断: eINTFWTMDIS: 禁用 ,eINTFWTMEN: 启用
  *      FIFO存满中断: eINTFFullDIS: 禁用 ,eINTFFullEN: 启用
  *      中断引脚初始(无效、无中断)电平: eINTInitialLevelLOW: 低电平 ,eINTInitialLevelHIGH: 高电平
  *      温度/压力数据准备中断: eINTDataDrdyDIS: 禁用 ,eINTDataDrdyEN: 启用
  * 注意:在非锁存模式(eINTLatchDIS)中,中断信号为2.5ms的脉冲信号
  * 提示:当使用eINTPinActiveLevelLow(中断引脚低电平有效)时,需使用eINTInitialLevelHIGH(中断引脚初始高电平),后边中断触发请使用 "FALLING" 
  *       当使用eINTPinActiveLevelHigh(中断引脚低电平有效)时,需使用eINTInitialLevelLOW(中断引脚初始高电平),后边中断触发请使用 "RISING" 
  */
  sensor.setINTMode(sensor.eINTPinPP + 
                    sensor.eINTPinActiveLevelHigh + 
                    sensor.eINTLatchDIS + 
                    sensor.eINTFWTMEN + 
                    sensor.eINTFFullDIS + 
                    sensor.eINTInitialLevelLOW + 
                    sensor.eINTDataDrdyDIS);

  delay(100);
  #ifdef CALIBRATE_ABSOLUTE_DIFFERENCE
  /**
  * 根据所给当前位置海拔,校准传感器
  * 此示例使用的是成都市温江区(中国)海拔540米,请使用者实际使用时换成本地海拔校准
  * 如果没有调用此接口,测量数据将不消除绝对误差
  * 注意:此接口只有第一次调用有效
  */
  if( sensor.calibratedAbsoluteDifference(540.0) ){
    Serial.println("Absolute difference base value set successfully!");
  }
  #endif

  #if defined(ESP32) || defined(ESP8266)
  //默认使用D6引脚作为中断引脚,也可以选择其它不冲突的引脚作为外部中断引脚
  attachInterrupt(digitalPinToInterrupt(D6)/*Query the interrupt number of the D6 pin*/,interrupt,CHANGE);
  #elif defined(ARDUINO_SAM_ZERO)
  //默认使用5引脚作为中断引脚,也可以选择其它不冲突的引脚作为外部中断引脚
  attachInterrupt(digitalPinToInterrupt(5)/*Query the interrupt number of the 5 pin*/,interrupt,CHANGE);
  #else
  /*    The Correspondence Table of AVR Series Arduino Interrupt Pins And Terminal Numbers
   * ---------------------------------------------------------------------------------------
   * |                                        |  DigitalPin  | 2  | 3  |                   |
   * |    Uno, Nano, Mini, other 328-based    |--------------------------------------------|
   * |                                        | Interrupt No | 0  | 1  |                   |
   * |-------------------------------------------------------------------------------------|
   * |                                        |    Pin       | 2  | 3  | 21 | 20 | 19 | 18 |
   * |               Mega2560                 |--------------------------------------------|
   * |                                        | Interrupt No | 0  | 1  | 2  | 3  | 4  | 5  |
   * |-------------------------------------------------------------------------------------|
   * |                                        |    Pin       | 3  | 2  | 0  | 1  | 7  |    |
   * |    Leonardo, other 32u4-based          |--------------------------------------------|
   * |                                        | Interrupt No | 0  | 1  | 2  | 3  | 4  |    |
   * |--------------------------------------------------------------------------------------
   */
  /*                      The Correspondence Table of micro:bit Interrupt Pins And Terminal Numbers
   * ---------------------------------------------------------------------------------------------------------------------------------------------
   * |             micro:bit                       | DigitalPin |P0-P20 can be used as an external interrupt                                     |
   * |  (When using as an external interrupt,      |---------------------------------------------------------------------------------------------|
   * |no need to set it to input mode with pinMode)|Interrupt No|Interrupt number is a pin digital value, such as P0 interrupt number 0, P1 is 1 |
   * |-------------------------------------------------------------------------------------------------------------------------------------------|
   */
  attachInterrupt(/*Interrupt No*/0,interrupt,CHANGE);//Open the external interrupt 0, connect INT1/2 to the digital pin of the main control: 
     //UNO(2), Mega2560(2), Leonardo(3), microbit(P0).
  #endif

  /* 清空FIFOFIFO中的数据,FIFO配置保持不变 */
  sensor.setCommand(BMP3XX_CMD_FIFO_FLUSH);
}

void loop()
{
  float fifoTemperatureC, fifoPressurePa;
  float fifoTemperatureSUM = 0, fifoPressureSUM = 0;
  uint8_t count = 0;

  if(flag == 1){
    /* 当水位中断触发时,读取海拔高度,单位m */
    float altitude = sensor.readAltitudeM();
    Serial.print("Altitude : ");
    Serial.print(altitude);
    Serial.println(" m");
    /* 读取FIFO中已存储的所有测量数据,并将所有数据求和 */
    while(sensor.getFIFOLength()){
      sensor.getFIFOData(fifoTemperatureC, fifoPressurePa);
      fifoTemperatureSUM += fifoTemperatureC;
      fifoPressureSUM += fifoPressurePa;
      count++;
    }
    Serial.print("The number of data read this time is:");
    Serial.println(count);
    Serial.println("Below is the average of the results:");
    Serial.print("temperature : ");
    /* 同时在FIFO中读count个温度数据得到的平均温度值,单位℃ */
    Serial.print(fifoTemperatureSUM/count);
    Serial.println(" C");
    Serial.print("Pressure : ");
    /* 同时在FIFO中读count个压力数据得到的平均压力值,单位pa */
    Serial.print(fifoPressureSUM/count);
    Serial.println(" Pa");
    count = 0;
    flag = 0;
  }
  sensor.getFIFOData(fifoTemperatureC, fifoPressurePa);
  Serial.print("temperature : ");
  /* 温度数据,单位℃(当FIFO中没有此数据时,其值为零) */
  Serial.print(fifoTemperatureC);
  Serial.println(" C");
  Serial.print("Pressure : ");
  /* 压力数据,单位pa(当FIFO中没有此数据时,其值为零) */
  Serial.print(fifoPressurePa);
  Serial.println(" Pa");
  /* FIFO已存储数据的字节数 */
  Serial.println(sensor.getFIFOLength());

  Serial.println();
  delay(300);
}

结果

样例代码4-数据处理高级设置功能(set_ODR_OSR_IIR.ino)

  • 选择set_ODR_OSR_IIR.ino

  • 烧录程序
/*!
 * @file set_ODR_OSR_IIR.ino
 * @brief 数据处理高级设置,配置更高级更符合您需求的数据采样、处理模式
 * @n 配置测量模式:睡眠模式,强制模式,正常模式
 * @n 配置压力、温度的过采样模式(增加采样次数)
 * @n 细分/二次采样的方式设置输出数据率的设置(设置数据输出率,需小于采样频率)
 * @n IIR滤波系数设置(过滤噪音)
 * @copyright   Copyright (c) 2010 DFRobot Co.Ltd (http://www.dfrobot.com)
 * @licence     The MIT License (MIT)
 * @author [qsj](qsj.huang@dfrobot.com)
 * @version  V0.1
 * @date  2021-4-30
 * @get from https://www.dfrobot.com
 * @url https://github.com/DFRobot/DFRobot_BMP3XX
 */
#include <DFRobot_BMP3XX.h>

/**
* 选择芯片版本BMP388/BMP390L
* 选择通信接口IIC,请注释掉SPI接口
* IIC通信地址设置: eSDOGND: SDO引脚连接到GND,此时I2C地址为0x76
*                   eSDOVDD: SDO引脚连接到VDDIO(3v3),此时I2C地址为0x77
* 注意:若使用Gravity系列的产品,IIC通信地址设置默认为:0x77(eSDOVDD)
*/
//DFRobot_BMP388_IIC sensor(&Wire, sensor.eSDOGND);
 DFRobot_BMP390L_IIC sensor(&Wire, sensor.eSDOVDD);

/**
* 选择芯片版本BMP388/BMP390L
* 选择通信接口SPI,请注释掉IIC接口
* 根据SPI片选管脚连接的板上引脚,自行设置digital引脚
* 注意:这里用的csPin是ESP32板子的D3数字引脚,也可以选择其它不冲突的引脚作为外部中断引脚
*/
// uint8_t csPin = D3;
// DFRobot_BMP388_SPI sensor(&SPI, csPin);
// DFRobot_BMP390L_SPI sensor(&SPI, csPin);


/* 如果不需要消除测量绝对差,请注释下面这一行 */
#define CALIBRATE_ABSOLUTE_DIFFERENCE

void setup(void)
{
  Serial.begin(115200);

  int rslt;
  while( ERR_OK != (rslt = sensor.begin()) ){
    if(ERR_DATA_BUS == rslt){
      Serial.println("Data bus error!!!");
    }else if(ERR_IC_VERSION == rslt){
      Serial.println("Chip versions do not match!!!");
    }
    delay(3000);
  }
  Serial.println("Begin ok!");

  /**
  * 测量模式和电源模式的配置
  * mode 需要设置的测量模式和电源模式,下列模式相加为mode:
  *      ePressDIS: 禁用压力测量 ,ePressEN: 启用压力测量
  *      eTempDIS: 禁用温度测量 ,eTempEN: 启用温度测量
  *      eSleepMode, eForcedMode/, eNormalMode 三种模式:
  *        睡眠模式:上电复位后默认设置为睡眠模式。在睡眠模式下,不执行任何测量,并且功耗最少。所有寄存器均可访问;可以读取芯片ID和补偿系数。
  *        强制模式:在强制模式下,根据选择的测量和滤波选项进行单个测量。测量完成后,传感器返回睡眠模式,测量结果可从数据寄存器中获得。
  *        正常模式:在测量周期和待机周期之间连续循环。测量速率在odrSel寄存器中设置,可以选择不同的采样频率Fsampling=200Hz的预分频器。
  */
  sensor.setPWRMode(sensor.ePressEN + 
                    sensor.eTempEN + 
                    sensor.eNormalMode);

  /**
  *  压力和温度测量的过采样配置
  *  mode 需要设置的压力和温度测量的过采样模式,下列模式相加为mode:
  *       6种压力过采样模式:
  *         ePressOSRMode1,  压力采样×1,16 bit / 2.64 Pa(推荐温度过采样×1)
  *         ePressOSRMode2,  压力采样×2,16 bit / 2.64 Pa(推荐温度过采样×1)
  *         ePressOSRMode4,  压力采样×4,18 bit / 0.66 Pa(推荐温度过采样×1)
  *         ePressOSRMode8,  压力采样×8,19 bit / 0.33 Pa(推荐温度过采样×2)
  *         ePressOSRMode16,  压力采样×16,20 bit / 0.17 Pa(推荐温度过采样×2)
  *         ePressOSRMode32,  压力采样×32,21 bit / 0.085 Pa(推荐温度过采样×2)
  *       6种温度过采样模式
  *         eTempOSRMode1,  温度采样×1,16 bit / 0.0050 °C
  *         eTempOSRMode2,  温度采样×2,16 bit / 0.0025 °C
  *         eTempOSRMode4,  温度采样×4,18 bit / 0.0012 °C
  *         eTempOSRMode8,  温度采样×8,19 bit / 0.0006 °C
  *         eTempOSRMode16,  温度采样×16,20 bit / 0.0003 °C
  *         eTempOSRMode32,  温度采样×32,21 bit / 0.00015 °C
  */
  sensor.setOSRMode(sensor.ePressOSRMode4 + 
                    sensor.eTempOSRMode1);

  /**
  * 细分/二次采样的方式设置输出数据率配置
  * mode 需要设置的输出数据率,可配置模式:
  *      BMP3XX_ODR_200_HZ,BMP3XX_ODR_100_HZ,BMP3XX_ODR_50_HZ,BMP3XX_ODR_25_HZ,BMP3XX_ODR_12P5_HZ,
  *      BMP3XX_ODR_6P25_HZ,BMP3XX_ODR_3P1_HZ,BMP3XX_ODR_1P5_HZ,BMP3XX_ODR_0P78_HZ,BMP3XX_ODR_0P39_HZ,
  *      BMP3XX_ODR_0P2_HZ,BMP3XX_ODR_0P1_HZ,BMP3XX_ODR_0P05_HZ,BMP3XX_ODR_0P02_HZ,BMP3XX_ODR_0P01_HZ,
  *      BMP3XX_ODR_0P006_HZ,BMP3XX_ODR_0P003_HZ,BMP3XX_ODR_0P0015_HZ
  */
  while( !sensor.setODRMode(BMP3XX_ODR_50_HZ) ){
    Serial.println("Set ODR mode fail! Please select lower frequency!");
    delay(3000);
  }

  /**
  * IIR滤波系数配置
  * mode IIR滤波系数设置,可配置模式:
  *      BMP3XX_IIR_CONFIG_COEF_0,BMP3XX_IIR_CONFIG_COEF_1,BMP3XX_IIR_CONFIG_COEF_3,
  *      BMP3XX_IIR_CONFIG_COEF_7,BMP3XX_IIR_CONFIG_COEF_15,BMP3XX_IIR_CONFIG_COEF_31,
  *      BMP3XX_IIR_CONFIG_COEF_63,BMP3XX_IIR_CONFIG_COEF_127
  */
  sensor.setIIRMode(BMP3XX_IIR_CONFIG_COEF_3);

  delay(100);
  #ifdef CALIBRATE_ABSOLUTE_DIFFERENCE
  /**
  * 根据所给当前位置海拔,校准传感器
  * 此示例使用的是成都市温江区(中国)海拔540米,请使用者实际使用时换成本地海拔校准
  * 如果没有调用此接口,测量数据将不消除绝对误差
  * 注意:此接口只有第一次调用有效
  */
  if( sensor.calibratedAbsoluteDifference(540.0) ){
    Serial.println("Absolute difference base value set successfully!");
  }
  #endif
}

void loop()
{
  /* 直接读取当前测量的温度数据,单位℃ */
  float temperature = sensor.readTempC();
  Serial.print("temperature : ");
  Serial.print(temperature);
  Serial.println(" C");

  /* 直接读取当前测量的压力数据,单位pa */
  float Pressure = sensor.readPressPa();
  Serial.print("Pressure : ");
  Serial.print(Pressure);
  Serial.println(" Pa");

  Serial.println();
  delay(1000);
}

结果

树莓派使用教程

准备

接线图

  • 将模块与树莓派按照连线图相连。

安装驱动

  1. 启动树莓派的I2C接口。如已开启,可跳过该步骤。
    打开终端(Terminal),键入如下指令,并回车:
sudo raspi-config 

然后用上下键选择“ 5 Interfacing Options ”, 按回车进入,选择 “ P5 I2C ”, 按回车确认“ YES ”即可。重启树莓派主控板。

  1. 安装Python依赖库与git,树莓派需要联网。如已安装,可跳过该步骤。
    在终端中,依次键入如下指令,并回车:
sudo apt-get update
sudo apt-get install build-essential python-dev python-smbus git
  1. 下载BMP3XX系列驱动库。在终端中,依次键入如下指令,并回车:
cd Desktop
git clone https://github.com/cdjq/DFRobot_BMP3XX

注意:
若您选择使用I2C或SPI的通信方式,需要修改demo至相应的通信,您可能会遇到没有权限修改示例程序的情况,以下是解决办法:

1.在要修改的文件目录下查询权限,命令为:

 ls -al

2.修改该文件权限,命令为:

sudo chmod a+w XXX.py

此时,所有人都对该文件具备写权限了。

样例代码

样例代码1-读取温度,气压,海拔(get_temp_press.py)

  • 在终端中,键入如下指令并回车,运行样例代码:
cd DFRobot_BMP3XX/python/raspberrypi/example
python3 get_temp_press.py
  • 结果

样例代码2-数据中断功能(interrupt_data_drdy.py)

  • 在终端中,键入如下指令并回车,运行样例代码:
cd DFRobot_BMP3XX/python/raspberrypi/example
python3 interrupt_data_drdy.py
  • 结果

样例代码3-FIFO水位或存满中断功能(interrupt_using_FIFO.py)

  • 在终端中,键入如下指令并回车,运行样例代码:
cd DFRobot_BMP3XX/python/raspberrypi/example
python3 interrupt_using_FIFO.py
  • 结果

样例代码4-数据处理高级设置功能(set_ODR_OSR_IIR.py)

  • 在终端中,键入如下指令并回车,运行样例代码:
cd DFRobot_BMP3XX/python/raspberrypi/example
 python3 set_ODR_OSR_IIR.py
  • 结果

常见问题

还没有客户对此产品有任何问题,欢迎通过qq或者论坛联系我们!

更多问题及有趣的应用,可以 访问论坛 进行查阅或发帖。

更多

DFshopping_car1.png DFRobot商城购买链接