1.产品简介
这款BMM150三轴地磁传感器,是博世专为指南针应用设计的,可以在三个垂直轴上测量磁场和罗盘角度,具有低功耗、低噪音(0.3-1.4uT) 、高精度(30uT水平磁场分量 ±2.5°)、磁力测试范围达±1300uT(x,y轴),±2047uT(z轴)等特点。板子轻便小巧,板载2位拨码开关,用于切换地址,最多可设置4个I2C地址。基于博世特有的FlipCore技术,BMM150三轴地磁传感器无需校准,便能提供精确的空间方位,可应用于机器人导航和定位、电子罗盘、电子地图、导航或增强现实
2.产品特性
-
1个可编程中断引脚
-
可配置4个I2C地址
-
低噪音(0.3-1.4uT)
-
高精度(30uT水平磁场分量 ±2.5°)
3.应用场景
- 无人机
- 指南针/电子罗盘
- 室内/室外导航
- 头部运动追踪
- 增强现实
- 倾斜补偿的电子地图
4.引脚排列图
引脚 | 功能描述 |
---|---|
VCC | DC3.3V-5V |
GND | 接地 |
SCL | I2C时钟线 |
SDA | I2C数据线 |
INT | 中断引脚 |
I2C地址设置表
地址名称 | A0 | A1 | 地址 |
---|---|---|---|
ADDRESS_1 | 0 | 0 | 0X10 |
ADDRESS_2 | 0 | 1 | 0X11 |
ADDRESS_3 | 1 | 0 | 0X12 |
ADDRESS_4 | 1 | 1 | 0X13 |
5.规格参数
- 供电电压:3.3V-5V
- 正常工作温度范围:-40~85°C
- 接口协议:I2C
- 分辨率:0.3uT
- 零度漂移:±40uT/±2uT(软件优化后)
- 非线性:< 1%FS
- 磁力测量范围:±1300μT (x,y轴) ±2047μT (z轴)
- 工作电流:1.7mA(采集频率为10HZ时)
- 低噪声:0.3-1.4uT
- 精度:30uT水平磁场分量 ±2.5°
- 启动时间:3ms
6.尺寸图
7.使用教程
7.1 硬件准备
-
FireBeetle ESP32-E主控板 (SKU:DFR0654) ×1
-
BMM150三轴磁力计传感器(SKU:SEN0529)×1
-
杜邦线 若干
7.2 软件准备
- 下载Arduino IDE: 点击下载Arduino IDE
- 安装SDK:点击进入FireBeetle ESP32-E主控板 WIKI页面 查找SDK安装教程
- 下载Arduino库:DFRobot_BMM150库文件下载,
- 关于如何安装库文件: 如何加载库文件
7.3 硬件连接
Gravity I2C BMM150模块:VCC---(连接)---ESP32-E主控:3V3;
Gravity I2C BMM150模块:GND---(连接)---ESP32-E主控:GND;
Gravity I2C BMM150模块:SCL---(连接)---ESP32-E主控:SCL;
Gravity I2C BMM150模块:SDA---(连接)---ESP32-E主控:SDA;
7.4 演示代码
样例代码
- 样例代码1-获取配置状态(getAllState.ino)
- 样例代码2-获取三轴地磁数据、罗盘角度(getGeomagneticData.ino)
- 样例代码3-阈值中断功能(thresholdInterrupt.ino)
样例代码1-获取配置状态(getAllState.ino)
- 烧录程序
#include "DFRobot_BMM150.h"
DFRobot_BMM150_I2C bmm150(&Wire, I2C_ADDRESS_4);
/*i2c Address select, that CS and SDO pin select 1 or 0 indicates the high or low respectively. There are 4 combinations:
*I2C_ADDRESS_1 0x10 (CS:0 SDO:0)
*I2C_ADDRESS_2 0x11 (CS:0 SDO:1)
*I2C_ADDRESS_3 0x12 (CS:1 SDO:0)
*I2C_ADDRESS_4 0x13 (CS:1 SDO:1) default i2c address */
#define BMM150_CS D3
void setup()
{
Serial.begin(115200);
while(!Serial);
while(bmm150.begin()){
Serial.println("bmm150 init failed, Please try again!");
delay(1000);
} Serial.println("bmm150 init success!");
Serial.println(bmm150.selfTest(BMM150_SELF_TEST_NORMAL));//返回的字符串表明自检结果
bmm150.setOperationMode(BMM150_POWERMODE_NORMAL);//正常模式
bmm150.setPresetMode(BMM150_PRESETMODE_HIGHACCURACY);// 高精度模式
bmm150.setRate(BMM150_DATA_RATE_30HZ);//30HZ
bmm150.setMeasurementXYZ();//默认xyz轴配置
uint8_t rate = bmm150.getRate();//获取配置的数据速率
Serial.print("rate is "); Serial.print(rate); Serial.println(" HZ");
Serial.println(bmm150.getMeasurementStateXYZ());
/**!
* 获取传感器的执行模式,返回字符串为传感器的执行模式
*/
Serial.println(bmm150.getOperationMode());
bmm150.softReset(); //软件复位
}
void loop()
{
Serial.println(bmm150.getOperationMode());
delay(1000);
}
结果
烧录示例程序,串口打印出传感器目前的配置状态
样例代码2-获取三轴地磁数据、罗盘角度(getGeomagneticData.ino)
- 烧录程序
#include "DFRobot_BMM150.h"
DFRobot_BMM150_I2C bmm150(&Wire, I2C_ADDRESS_4);
/*i2c Address select, that CS and SDO pin select 1 or 0 indicates the high or low respectively. There are 4 combinations:
*I2C_ADDRESS_1 0x10 (CS:0 SDO:0)
*I2C_ADDRESS_2 0x11 (CS:0 SDO:1)
*I2C_ADDRESS_3 0x12 (CS:1 SDO:0)
*I2C_ADDRESS_4 0x13 (CS:1 SDO:1) default i2c address */
//When using SPI communication, use the following program to construct an object by DFRobot_BMM150_SPI
#define BMM150_CS D3
//DFRobot_BMM150_SPI bmm150(/*cs = */BMM150_CS);
void setup()
{
Serial.begin(115200);
while(!Serial);
while(bmm150.begin()){
Serial.println("bmm150 init failed, Please try again!");
delay(1000);
} Serial.println("bmm150 init success!");
bmm150.setOperationMode(BMM150_POWERMODE_NORMAL);//正常模式
bmm150.setPresetMode(BMM150_PRESETMODE_HIGHACCURACY);//高精度模式
bmm150.setRate(BMM150_DATA_RATE_10HZ);//10HZ
bmm150.setMeasurementXYZ();//默认xyz轴配置
}
void loop()
{
sBmm150MagData_t magData = bmm150.getGeomagneticData();
Serial.print("mag x = "); Serial.print(magData.x); Serial.println(" uT");
Serial.print("mag y = "); Serial.print(magData.y); Serial.println(" uT");
Serial.print("mag z = "); Serial.print(magData.z); Serial.println(" uT");
/*float type data 打开以下代码,可显示浮点型数据*/
//Serial.print("mag x = "); Serial.print(magData.xx); Serial.println(" uT");
//Serial.print("mag y = "); Serial.print(magData.yy); Serial.println(" uT");
//Serial.print("mag z = "); Serial.print(magData.zz); Serial.println(" uT");
float compassDegree = bmm150.getCompassDegree();
Serial.print("the angle between the pointing direction and north (counterclockwise) is:");
Serial.println(compassDegree);
Serial.println("--------------------------------");
delay(100);
}
结果
烧录示例程序,串口打印出传感器获取的地磁数据和罗盘角度数据
样例代码3-阈值中断功能(thresholdInterrupt.ino)
- 烧录程序
#include "DFRobot_BMM150.h"
DFRobot_BMM150_I2C bmm150(&Wire, I2C_ADDRESS_4);
#if defined(ESP32) || defined(ESP8266)
#define BMM150_CS D3
#elif defined(__AVR__) || defined(ARDUINO_SAM_ZERO)
#define BMM150_CS 3
#elif (defined NRF5)
#define BMM150_CS 2
#endif
volatile uint8_t interruptFlag = 0;
void myInterrupt(void)
{
interruptFlag = 1; // 中断标志
#if defined(ESP32) || defined(ESP8266) || defined(ARDUINO_SAM_ZERO)
detachInterrupt(13); // 分离中断
#else
detachInterrupt(0); // 分离中断
#endif
}
void setup()
{
Serial.begin(115200);
while(!Serial);
while(bmm150.begin()){
Serial.println("bmm150 init failed, Please try again!");
delay(1000);
} Serial.println("bmm150 init success!");
bmm150.setOperationMode(BMM150_POWERMODE_NORMAL);//正常模式
bmm150.setPresetMode(BMM150_PRESETMODE_HIGHACCURACY);//高精度模式
bmm150.setRate(BMM150_DATA_RATE_10HZ);//10HZ
bmm150.setMeasurementXYZ();//默认xyz轴配置
bmm150.setThresholdInterrupt(LOW_THRESHOLD_INTERRUPT, 0, POLARITY_LOW);//极性低电平
#if defined(ESP32) || defined(ESP8266)
pinMode(/*Pin */13 ,INPUT_PULLUP);
attachInterrupt(/*interput io*/13, myInterrupt, ONLOW);
#elif defined(ARDUINO_SAM_ZERO)
pinMode(/*Pin */13 ,INPUT_PULLUP);
attachInterrupt(/*interput io*/13, myInterrupt, LOW);
#else
pinMode(/*Pin */2 ,INPUT_PULLUP);
attachInterrupt(/*Interrupt No*/0, /*function*/myInterrupt ,/*state*/LOW );
#endif
}
void loop()
{
if(interruptFlag == 1){
sBmm150ThresholdData_t threshold = bmm150.getThresholdData();
if(threshold.x != NO_DATA){
Serial.print("mag x = "); Serial.print(threshold.x); Serial.println(" uT");
}
if(threshold.y != NO_DATA){
Serial.print("mag y = "); Serial.print(threshold.y); Serial.println(" uT");
}
if(threshold.z != NO_DATA){
Serial.print("mag z = "); Serial.print(threshold.z); Serial.println(" uT");
}
Serial.println();
interruptFlag = 0;
#if defined(ESP32) || defined(ESP8266)
attachInterrupt(13, myInterrupt, ONLOW);
#elif defined(ARDUINO_SAM_ZERO)
attachInterrupt(13, myInterrupt, LOW);
#else
attachInterrupt(0, myInterrupt, LOW);
#endif
}
delay(100);
}
结果
烧录示例程序,晃动传感器触发阈值中断,串口打印变化数据
8. API函数
/*!
* @brief 软件复位,软件复位后先恢复为挂起模式,而后恢复为睡眠模式,suspend mode下不能软件复位
*/
void softReset(void);
/*!
* @brief 设置传感器的执行模式
* @param op mode
* BMM150_POWERMODE_NORMAL // normal mode 正常的获得地磁数据的模式
* BMM150_POWERMODE_FORCED // forced mode 单次测量,测量完成后,传感器恢复sleep mode
* BMM150_POWERMODE_SLEEP // sleep mode 用户可以访问所有寄存器,不能测量地磁数据
* BMM150_POWERMODE_SUSPEND // suspend mode 此时传感器cpu不工作,无法执行任何操作,用户只能访问控制寄存器 BMM150_REG_POWER_CONTROL的内容
*/
void setOperationMode(uint8_t opMode);
/*!
* @brief 获取传感器的执行模式
* @return result 返回字符串为传感器的执行模式
*/
String getOperationMode(void);
/*!
* @brief 设置预置模式,使用户更简单的配置传感器来获取地磁数据
* @param presetMode
* BMM150_PRESETMODE_LOWPOWER // 低功率模式,获取少量的数据 取均值
* BMM150_PRESETMODE_REGULAR // 普通模式,获取中量数据 取均值
* BMM150_PRESETMODE_ENHANCED // 增强模式,获取大量数据 取均值
* BMM150_PRESETMODE_HIGHACCURACY // 高精度模式,获取超大量数据 取均值
*/
void setPresetMode(uint8_t presetMode);
/*!
* @brief 设置获取地磁数据的速率,速率越大获取越快(不加延时函数)
* @param rate
* BMM150_DATA_RATE_02HZ
* BMM150_DATA_RATE_06HZ
* BMM150_DATA_RATE_08HZ
* BMM150_DATA_RATE_10HZ (default rate)
* BMM150_DATA_RATE_15HZ
* BMM150_DATA_RATE_20HZ
* BMM150_DATA_RATE_25HZ
* BMM150_DATA_RATE_30HZ
*/
void setRate(uint8_t rate);
/*!
* @brief 获取配置的数据速率 单位:HZ
* @return rate
*/
uint8_t getRate(void);
/*!
* @brief 获取x y z 三轴的地磁数据
*
* @return 地磁的数据的结构体,单位:微特斯拉(uT)
*/
sMagData getGeomagneticData(void);
/*!
* @brief 获取罗盘方向
*
* @return 罗盘方向 (0° - 360°)
* 0° = North, 90° = East, 180° = South, 270° = West.
*/
float getCompassDegree(void);
/*!
* @brief 使能或者禁止数据准备中断引脚
* 使能后有数据来临DRDY引脚跳变
* 禁止后有数据来临DRDY不进行跳变
* 高极性:高电平为活动电平,默认为低电平,触发中断时电平变为高
* 低极性:低电平为活动电平,默认为高电平,触发中断时电平变为低
* @param modes
* DRDY_ENABLE // 使能DRDY
* DRDY_DISABLE // 禁止DRDY
* @param polarity
* POLARITY_HIGH // 高极性
* POLARITY_LOW // 低极性
*/
void setDataReadyPin(uint8_t modes, uint8_t polarity=POLARITY_HIGH);
/*!
* @brief 获取数据准备的状态,用来判断数据是否准备好
*
* @return status
* true 数据准备好了
* false 数据没有准备好
*/
bool getDataReadyState(void);
/*!
* @brief 使能x y z 轴的测量,默认设置为使能,禁止后xyz轴的地磁数据不准确
*
* @param channelX
* MEASUREMENT_X_ENABLE // 使能 x 轴的测量
* MEASUREMENT_X_DISABLE // 禁止 x 轴的测量
* @param channelY
* MEASUREMENT_Y_ENABLE // 使能 y 轴的测量
* MEASUREMENT_Y_DISABLE // 禁止 y 轴的测量
* @param channelZ
* MEASUREMENT_Z_ENABLE // 使能 z 轴的测量
* MEASUREMENT_Z_DISABLE // 禁止 z 轴的测量
*/
void setMeasurementXYZ(uint8_t channelX = MEASUREMENT_X_ENABLE, uint8_t channelY = MEASUREMENT_Y_ENABLE, uint8_t channelZ = MEASUREMENT_Z_ENABLE);
/*!
* @brief 获取 x y z 轴的使能状态
* @return result 返回字符串为使能的状态
*/
String getMeasurementStateXYZ(void);
/*!
* @brief 设置阈值中断,当某个通道的地磁值高/低于阈值时触发中断
* 高极性:高电平为活动电平,默认为低电平,触发中断时电平变为高
* 低极性:低电平为活动电平,默认为高电平,触发中断时电平变为低
* @param modes
* LOW_THRESHOLD_INTERRUPT // 低阈值中断模式
* HIGH_THRESHOLD_INTERRUPT // 高阈值中断模式
* @param threshold
* 阈值,默认扩大16倍,例如:低阈值模式下传入阈值1,实际低于16的地磁数据都会触发中断
* @param polarity
* POLARITY_HIGH // 高极性
* POLARITY_LOW // 低极性
*/
void setThresholdInterrupt(uint8_t modes, int8_t threshold, uint8_t polarity);
/*!
* @brief 设置阈值中断,当某个通道的地磁值高于/低于阈值时触发中断
* 当产生中断时,INT引脚电平产生跳变
* 高极性:高电平为活动电平,默认为低电平,触发中断时电平变为高
* 低极性:低电平为活动电平,默认为高电平,触发中断时电平变为低
* @param modes
* LOW_THRESHOLD_INTERRUPT // 低阈值中断模式
* HIGH_THRESHOLD_INTERRUPT // 高阈值中断模式
* @param channelX
* INTERRUPT_X_ENABLE // 使能 x 轴高阈值中断
* INTERRUPT_X_DISABLE // 禁止 x 轴高阈值中断
* @param channelY
* INTERRUPT_Y_ENABLE // 使能 y 轴高阈值中断
* INTERRUPT_Y_DISABLE // 禁止 y 轴高阈值中断
* @param channelZ
* INTERRUPT_Z_ENABLE // 使能 z 轴高阈值中断
* INTERRUPT_Z_DISABLE // 禁止 z 轴高阈值中断
* @param threshold
* 阈值,默认扩大16倍,例如:传入 1 的阈值,实际高于/低于16的地磁数据都会触发中断
* @param polarity
* POLARITY_HIGH // 高极性
* POLARITY_LOW // 低极性
*/
void setThresholdInterrupt(uint8_t modes, uint8_t channelX, uint8_t channelY, uint8_t channelZ, int8_t threshold, uint8_t polarity);
/*!
* @brief 获取发生阈值中断的数据
* @return 返回存放地磁数据的结构体,结构体存放三轴当数据和中断状态,
* xyz轴的数据为 NO_DATA 时,未触发中断
* String state 存放状态二进制数据的字符串
* uint8_t value 存放状态二进制的原始值,数据格式如下
* bit0 is 1 代表x轴发生了中断
* bit1 is 1 代表y轴发生了中断
* bit2 is 1 代表z轴发生了中断
* ------------------------------------
* | bit7 ~ bit3 | bit2 | bit1 | bit0 |
* ------------------------------------
* | reserved | 0 | 0 | 0 |
* ------------------------------------
*/
sThresholdData getThresholdData(void);
/*!
* @brief 传感器自测,返回值表明自检结果
*
* @param mode:
* BMM150_SELF_TEST_NORMAL // 普通自测,测试X,Y,Z轴是否连接,是否短路
* BMM150_SELF_TEST_ADVANCED // 高级自测,测试z轴数据的准确性
*
* @return result 返回的字符串为自测的结果
*/
String selfTest(uint8_t testMode);
9. 更多资料
10. 常见问题
还没有客户对此产品有任何问题,欢迎通过qq或者论坛联系我们!
更多问题及有趣的应用,可以 访问论坛 进行查阅或发帖。
WIKI文档修改历史
文档版本号 | 修改时间 | 修改人 | 修改内容 |
---|---|---|---|
V1.0 | 2022.6.27 | 康啸 | 第一版发布 |
产品修改历史
产品版本号 | 修改时间 | 修改人 | 产品修改内容 |
---|---|---|---|
V1.0 | 2022.6.27 | 刘礼华 | 第一版发布 |