简介
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中直接下载步骤如下图所示:
关于如何安装库文件,点击链接
关于如何使用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);
}
结果
树莓派使用教程
准备
-
硬件
- 树莓派4代B型(或类似)主控板 x 1
- BMP390L数字气压传感器 x 1
- 若干杜邦线 x 1
-
软件
接线图
- 将模块与树莓派按照连线图相连。
安装驱动
- 启动树莓派的I2C接口。如已开启,可跳过该步骤。
打开终端(Terminal),键入如下指令,并回车:
sudo raspi-config
然后用上下键选择“ 5 Interfacing Options ”, 按回车进入,选择 “ P5 I2C ”, 按回车确认“ YES ”即可。重启树莓派主控板。
- 安装Python依赖库与git,树莓派需要联网。如已安装,可跳过该步骤。
在终端中,依次键入如下指令,并回车:
sudo apt-get update
sudo apt-get install build-essential python-dev python-smbus git
- 下载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)
- 样例代码2-数据中断功能(interrupt_data_drdy.py)
- 样例代码3-FIFO水位或存满中断功能(interrupt_using_FIFO.py)
- 样例代码4-数据处理高级设置功能(set_ODR_OSR_IIR.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或者论坛联系我们!
更多问题及有趣的应用,可以 访问论坛 进行查阅或发帖。