BMM150

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 硬件准备

7.2 软件准备

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)

  • 烧录程序
#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. 更多资料

SEN0529 STP 3D模型.rar

SEN0529 2D CAD 尺寸图.rar

SEN0529_2D_CAD 尺寸图.pdf

SEN0529 原理图.pdf

BMM150 芯片手册.pdf

10. 常见问题

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

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

DFshopping_car1.png DFRobot商城购买链接

WIKI文档修改历史

文档版本号 修改时间 修改人 修改内容
V1.0 2022.6.27 康啸 第一版发布

产品修改历史

产品版本号 修改时间 修改人 产品修改内容
V1.0 2022.6.27 刘礼华 第一版发布