简介
该传感器也可与六轴MEMS(3轴加速度+3轴陀螺仪)配对使用以获得一个9自由度惯性测量单元。
该传感器是专为指南针应用设计的三轴数字地磁传感器,具有低功耗(170uA)低噪(0.3-1.4uT)低温漂(±0.01%/K)、高分辨率(0.3uT)和高指针准确度(误差最大±2.5°@30uT水平磁场分量@25°C)的特点。BMM150能提供绝对空间方向上的运动矢量,该产品可与六轴IMU(三轴加速度+三轴磁力计)搭配使用以获得一个9自由度姿态传感器的效果。
BMM150还非常适合用于无人机这样的飞行项目中,轻便小巧的板子不会附加任何重量和占用体积,精准的空间方向可为无人机提供正确航向。
特性
- 低功耗
- 低噪声
- 精度高
- 精致小巧
应用场景
- 无人机
- 指南针/电子罗盘
- 室内/室外导航
- 头部运动追踪
- 增强现实
- 倾斜补偿的电子地图
技术规格
- 供电电压:3.3V
- 温度范围:-40~85°C
- 数字接口:I2C/SPI
- 可编程中断:2个中断引脚
- 分辨率:0.3uT
- 零B漂移:±40uT/±2uT(软件优化后)
- 非线性:< 1%FS
- 磁力测量范围:±1300μT (x,y轴) ±2047μT (z轴)
- 平均功耗:170 μA (低功耗模式) / 500 μA (正常模式)
- 低噪声:0.3-1.4uT
- 精度:30uT水平磁场分量 ±2.5°
- 启动时间:3ms
引脚说明
序号 | 丝印 | 功能描述 |
---|---|---|
1 | VCC | 3.3V电源输 |
2 | SCK | 时钟线 |
4 | SDI | SPI、I2C数据线(输入) |
5 | SDO | SPI、I2C数据线(输出) |
6 | CS | SPI 片选线、I2C接地 |
7 | PS | 选择通讯协议 |
8 | DRDY | 数据收发准备状态 |
9 | INT | 中断引脚 |
注意:
- 所有数据输出电压均为3.3V
- 只能接入3.3V电压
不同通信方式连线提示:
- I2Cl连接:0x13是默认地址
- 在使用magDrdyInterrupt时DRDY接中断,INT不接
- SPI连接
注意:使用SPI连线时PS引脚要接地
- 中断引脚连接
主板 | 默认连接引脚 |
---|---|
Leonardo | D3 |
Micro:bit | P0 |
ESP32/ESP8266/ARDUINO_SAM_ZERO(M0) | D7 |
Raspberry Pi | GPIO25 |
- 在使用中断时才接中断引脚 其他状态下不接
M0使用教程
请按接线图所示将传感器与M0(或其它主板)相连接即可。
这里使用的是默认地址0x13
准备
- 硬件
- 1 x Firebeetle Board-M0
- 1 x BMM150三轴磁力计传感器
- 若干 杜邦线
- 软件
- Arduino IDE, 点击下载Arduino IDE
- DFRobot_BMM150库文件下载
关于如何安装库文件,点击链接
关于如何使用Firebeetle Board-M0,点击链接
-
样例代码
-
主要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);
样例代码1-获取配置状态(getAllState.ino)
- 选择getAllState.ino
- 烧录程序
/*!
* @file getAllState.ino
* @brief 获取所有的配置状态,自测状态,软件复位后传感器可以从正常模式变为为睡眠模式
* @n 实验现象 传感器的配置信息打印在串口上,自测信息打印在串口上
* @copyright Copyright (c) 2010 DFRobot Co.Ltd (http://www.dfrobot.com)
* @licence The MIT License (MIT)
* @author ZhixinLiu(zhixin.liu@dfrobot.com)
* @version V0.4
* @date 2021-04-21
* @get from https://www.dfrobot.com
* @url https://github.com/dfrobot/DFRobot_BMM150
*/
#include "DFRobot_BMM150.h"
//When using I2C communication, use the following program to construct an object by DFRobot_BMM150_I2C
/*!
* @brief Constructor
* @param pWire I2C controller
* @param I2C address
* i2c 地址选择,CS,SDO引脚连接1代表高电平,0代表低电平,4 种组合为
* 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
*/
DFRobot_BMM150_I2C bmm150(&Wire, I2C_ADDRESS_4);
//When using SPI communication, use the following program to construct an object by DFRobot_BMM150_SPI
#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 //The corresponding silkscreen on the development board is the pin of P2
#endif
/*!
* @brief Constructor
* @param cs Chip selection pinChip selection pin
* spi连接方法
* (SDO<-->MISO) (SDI<-->MOSI)
* (SCK<-->SCK) (PS<--> GND)
* (CS<-->CS 可自定义引脚)
*/
//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!");
/**!
* 传感器自测,返回的字符串表明自检结果
* mode:
* BMM150_SELF_TEST_NORMAL // 普通自测,测试X,Y,Z轴是否连接,是否短路
* BMM150_SELF_TEST_ADVANCED // 高级自测,测试z轴数据的准确性
*/
Serial.println(bmm150.selfTest(BMM150_SELF_TEST_NORMAL));
/**!
* 设置传感器的执行模式
* opMode:
* 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的内容
*/
bmm150.setOperationMode(BMM150_POWERMODE_NORMAL);
/**!
* 设置预置模式,使用户更简单的配置传感器来获取地磁数据
* presetMode:
* BMM150_PRESETMODE_LOWPOWER // 低功率模式,获取少量的数据 取均值
* BMM150_PRESETMODE_REGULAR // 普通模式,获取中量数据 取均值
* BMM150_PRESETMODE_ENHANCED // 增强模式,获取大量数据 取均值
* BMM150_PRESETMODE_HIGHACCURACY // 高精度模式,获取超大量数据 取均值
*/
bmm150.setPresetMode(BMM150_PRESETMODE_HIGHACCURACY);
/**!
* 设置获取地磁数据的速率,速率越大获取越快(不加延时函数)
* 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
*/
bmm150.setRate(BMM150_DATA_RATE_30HZ);
/**!
* 使能xyz轴的测量,默认设置为使能不需要配置,禁止后获取xyz轴的地磁数据不准确
* 如果想配置更多参数请参考.h文件中的 setMeasurementXYZ() 函数
*/
bmm150.setMeasurementXYZ();
/**!
* 获取配置的数据速率 单位:HZ
*/
uint8_t rate = bmm150.getRate();
Serial.print("rate is "); Serial.print(rate); Serial.println(" HZ");
/**!
* 获取 x y z 轴的使能状态,返回字符串为使能的状态
*/
Serial.println(bmm150.getMeasurementStateXYZ());
/**!
* 获取传感器的执行模式,返回字符串为传感器的执行模式
*/
Serial.println(bmm150.getOperationMode());
/**!
* 软件复位,软件复位后先恢复为挂起模式,而后恢复为睡眠模式,suspend mode下不能软件复位
*/
bmm150.softReset(); // After software reset, resume sleep mode, (Suspended mode cannot be reset)
}
void loop()
{
/**!
* 获取传感器的执行模式,返回字符串为传感器的执行模式
*/
Serial.println(bmm150.getOperationMode());
delay(1000);
}
结果
样例代码2-获取三轴地磁数据、罗盘角度(getGeomagneticData.ino)
- 选择getGeomagneticData.ino
- 烧录程序
/*!
* @file getGeomagneticData.ino
* @brief 获取三轴地磁数据,获取罗盘角度
* @n "罗盘角度",罗盘方向逆时针旋转到地理北方的夹角大小
* @n 实验现象 xyz三轴的地磁数据和罗盘角度打印在串口上
* @copyright Copyright (c) 2010 DFRobot Co.Ltd (http://www.dfrobot.com)
* @licence The MIT License (MIT)
* @author ZhixinLiu(zhixin.liu@dfrobot.com)
* @version V0.4
* @date 2021-04-21
* @get from https://www.dfrobot.com
* @url https://github.com/dfrobot/DFRobot_BMM150
*/
#include "DFRobot_BMM150.h"
//When using I2C communication, use the following program to construct an object by DFRobot_BMM150_I2C
/*!
* @brief Constructor
* @param pWire I2C controller
* @param I2C address
* i2c 地址选择,CS,SDO引脚连接1代表高电平,0代表低电平,4 种组合为
* 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
*/
DFRobot_BMM150_I2C bmm150(&Wire, I2C_ADDRESS_4);
//When using SPI communication, use the following program to construct an object by DFRobot_BMM150_SPI
#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 //The corresponding silkscreen on the development board is the pin of P2
#endif
/*!
* @brief Constructor
* @param cs Chip selection pinChip selection pin
* spi连接方法
* (SDO<-->MISO) (SDI<-->MOSI)
* (SCK<-->SCK) (PS<--> GND)
* (CS<-->CS 可自定义引脚)
*/
//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!");
/**!
* 设置传感器的执行模式
* opMode:
* 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的内容
*/
bmm150.setOperationMode(BMM150_POWERMODE_NORMAL);
/**!
* 设置预置模式,使用户更简单的配置传感器来获取地磁数据
* presetMode:
* BMM150_PRESETMODE_LOWPOWER // 低功率模式,获取少量的数据 取均值
* BMM150_PRESETMODE_REGULAR // 普通模式,获取中量数据 取均值
* BMM150_PRESETMODE_ENHANCED // 增强模式,获取大量数据 取均值
* BMM150_PRESETMODE_HIGHACCURACY // 高精度模式,获取超大量数据 取均值
*/
bmm150.setPresetMode(BMM150_PRESETMODE_HIGHACCURACY);
/**!
* 设置获取地磁数据的速率,速率越大获取越快(不加延时函数)
* 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
*/
bmm150.setRate(BMM150_DATA_RATE_10HZ);
/**!
* 使能xyz轴的测量,默认设置为使能不需要配置,禁止后获取xyz轴的地磁数据不准确
* 如果想配置更多参数请参考.h文件中的 setMeasurementXYZ() 函数
*/
bmm150.setMeasurementXYZ();
}
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-准备中断功能(magDrdyInterrupt.ino)
- 选择magDrdyInterrupt.ino
- 烧录程序
/*!
* @file magDrdyInterrupt.ino
* @brief 数据准备中断,当数据地磁数据准备好了触发DRDY中断(DRDY中断可以由软件和硬件判断是否产生了中断)
* @n 实验现象 xyz三轴的地磁数据打印在串口上,单位微特斯拉 (uT)
* @n 实验现象 DRDY引脚在产生中断后电平跳变触发主控中断,得到地磁数据
* @copyright Copyright (c) 2010 DFRobot Co.Ltd (http://www.dfrobot.com)
* @licence The MIT License (MIT)
* @author ZhixinLiu(zhixin.liu@dfrobot.com)
* @version V0.3
* @date 2021-04-13
* @get from https://www.dfrobot.com
* @url https://github.com/dfrobot/DFRobot_BMM150
*/
#include "DFRobot_BMM150.h"
//When using I2C communication, use the following program to construct an object by DFRobot_BMM150_I2C
/*!
* @brief Constructor
* @param pWire I2C controller
* @param I2C address
* i2c 地址选择,CS,SDO引脚连接1代表高电平,0代表低电平,4 种组合为
* 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
* DRDY 连接到主控的中断引脚 pin 上
*/
DFRobot_BMM150_I2C bmm150(&Wire, I2C_ADDRESS_4);
//When using SPI communication, use the following program to construct an object by DFRobot_BMM150_SPI
#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 //The corresponding silkscreen on the development board is the pin of P2
#endif
/*!
* @brief Constructor
* @param cs Chip selection pinChip selection pin
* spi方法
* (SDO<-->MISO) (SDI<-->MOSI)
* (SCK<-->SCK) (PS<--> GND)
* (CS<-->CS 可自定义引脚)
* (DRDY<-->pin DRDY连接到主控的中断引脚pin上)
*/
//DFRobot_BMM150_SPI bmm150(/*cs = */BMM150_CS);
volatile uint8_t interruptFlag = 0;
void myInterrupt(void)
{
interruptFlag = 1; // 中断标志
detachInterrupt(0); // 禁止中断
}
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!");
/**!
* 设置传感器的执行模式
* opMode:
* 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的内容
*/
bmm150.setOperationMode(BMM150_POWERMODE_NORMAL);
/**!
* 设置预置模式,使用户更简单的配置传感器来获取地磁数据
* presetMode:
* BMM150_PRESETMODE_LOWPOWER // 低功率模式,获取少量的数据 取均值
* BMM150_PRESETMODE_REGULAR // 普通模式,获取中量数据 取均值
* BMM150_PRESETMODE_ENHANCED // 增强模式,获取大量数据 取均值
* BMM150_PRESETMODE_HIGHACCURACY // 高精度模式,获取超大量数据 取均值
*/
bmm150.setPresetMode(BMM150_PRESETMODE_HIGHACCURACY);
/**!
* 设置获取地磁数据的速率,速率越大获取越快(不加延时函数)
* 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
*/
bmm150.setRate(BMM150_DATA_RATE_10HZ);
/**!
* 使能xyz轴的测量,默认设置为使能不需要配置,禁止后获取xyz轴的地磁数据不准确
* 如果想配置更多参数请参考.h文件中的 setMeasurementXYZ() 函数
*/
bmm150.setMeasurementXYZ();
/**!
* 使能或者禁止数据准备中断引脚,
* 使能后有数据来临DRDY 引脚电平发生变化
* 禁止后有数据来临DRDY 引脚电平不变
* 高极性:高电平为活动电平,默认为低电平,触发中断时电平变为高
* 低极性:低电平为活动电平,默认为高电平,触发中断时电平变为低
* modes:
* DRDY_ENABLE // 使能DRDY
* DRDY_DISABLE // 禁止DRDY
* polatily:
* POLARITY_HIGH // 高极性
* POLARITY_LOW // 低极性
*/
bmm150.setDataReadyPin(DRDY_ENABLE, POLARITY_LOW);
#if defined(ESP32) || defined(ESP8266)||defined(ARDUINO_SAM_ZERO)
/**!
根据设置的DADY引脚极性选择
INPUT_PULLUP // 低极性,设置13号引脚为上拉输入
INPUT_PULLDOWN // 高极性,设置13号引脚为下拉输入
interput io
All pins can be used. Pin 13 is recommended
*/
pinMode(/*Pin */13 ,INPUT_PULLUP);
attachInterrupt(/*interput io*/13, myInterrupt, LOW);
#else
/**! The Correspondence Table of AVR Series Arduino Interrupt Pins And Terminal Numbers
* ---------------------------------------------------------------------------------------
* | | Pin | 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 |
* |-------------------------------------------------------------------------------------------------------------------------------------------|
*/
/**!
根据设置的DADY引脚极性选择
INPUT_PULLUP // 低极性,设置2号引脚为上拉输入
*/
pinMode(/*Pin */2 ,INPUT_PULLUP);
/**!
设置引脚为中断模式
// Open the external interrupt 0, connect INT1/2 to the digital pin of the main control:
function
callback function
state
LOW // 当引脚为低电平后产生中断,进入interrupt函数
*/
attachInterrupt(/*Interrupt No*/0, /*function*/myInterrupt ,/*state*/LOW );
#endif
}
void loop()
{
/**!
* 获取数据准备的状态,用来判断数据是否准备好(软件获取数据准备的状态)
* status:
* true 数据准备好了
* false 数据没有准备好
*/
/*
if(bmm150.getDataReadyState()){
sMagData 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");
Serial.println();
}
*/
/**!
当DRDY io口产生了中断,获取地磁数据(硬件获取数据准备的状态)
重新使能中断
*/
if(interruptFlag == 1){
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");
Serial.println();
interruptFlag = 0;
attachInterrupt(0, myInterrupt ,LOW);
}
delay(100);
}
结果
样例代码4-阈值中断功能(thresholdInterrupt.ino)
- 选择thresholdInterrupt.ino
- 烧录程序
/*!
* @file thresholdInterrupt.ino
* @brief 设置高于/低于阈值触发中断,当相应轴的中断产生时数据会打印在串口上
* @n 实验现象 当xyz轴的地磁数据大于/小于设定的阈值时,三轴的地磁数据打印在串口上,单位:微特斯拉 (uT)
* @n 实验现象 INT引脚在产生中断后电平跳变触发主控中断,得到地磁数据
* @copyright Copyright (c) 2010 DFRobot Co.Ltd (http://www.dfrobot.com)
* @licence The MIT License (MIT)
* @author ZhixinLiu(zhixin.liu@dfrobot.com)
* @version V0.4
* @date 2021-04-21
* @get from https://www.dfrobot.com
* @url https://github.com/DFRobot/DFRobot_BMM150
*/
#include "DFRobot_BMM150.h"
//When using I2C communication, use the following program to construct an object by DFRobot_BMM150_I2C
/*!
* @brief Constructor
* @param pWire I2C controller
* @param I2C address
* i2c 地址选择,CS,SDO引脚连接1代表高电平,0代表低电平,4 种组合为
* 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
* INT 连接到主控的中断引脚pin上
*/
DFRobot_BMM150_I2C bmm150(&Wire, I2C_ADDRESS_4);
//When using SPI communication, use the following program to construct an object by DFRobot_BMM150_SPI
#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 //The corresponding silkscreen on the development board is the pin of P2
#endif
/*!
* @brief Constructor
* @param cs Chip selection pinChip selection pin
* spi连接方法
* (SDO<-->MISO) (SDI<-->MOSI)
* (SCK<-->SCK) (PS<--> GND)
* (CS<-->CS 可自定义引脚)
* (INT<-->pin INT连接到主控的中断引脚pin上)
*/
//DFRobot_BMM150_SPI bmm150(/*cs = */BMM150_CS);
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!");
/**!
* 设置传感器的执行模式
* opMode:
* 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的内容
*/
bmm150.setOperationMode(BMM150_POWERMODE_NORMAL);
/**!
* 设置预置模式,使用户更简单的配置传感器来获取地磁数据
* presetMode:
* BMM150_PRESETMODE_LOWPOWER // 低功率模式,获取少量的数据 取均值
* BMM150_PRESETMODE_REGULAR // 普通模式,获取中量数据 取均值
* BMM150_PRESETMODE_ENHANCED // 增强模式,获取大量数据 取均值
* BMM150_PRESETMODE_HIGHACCURACY // 高精度模式,获取超大量数据 取均值
*/
bmm150.setPresetMode(BMM150_PRESETMODE_HIGHACCURACY);
/**!
* 设置获取地磁数据的速率,速率越大获取越快(不加延时函数)
* 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
*/
bmm150.setRate(BMM150_DATA_RATE_10HZ);
/**!
* 使能xyz轴的测量,默认设置为使能不需要配置,禁止后获取xyz轴的地磁数据不准确
* 如果想配置更多参数请参考.h文件中的 setMeasurementXYZ() 函数
*/
bmm150.setMeasurementXYZ();
/*!
* 设置阈值中断,当某个通道的地磁值高/低于阈值时触发中断
* 高极性:高电平为活动电平,默认为低电平,触发中断时电平变为高
* 低极性:低电平为活动电平,默认为高电平,触发中断时电平变为低
* modes:
* LOW_THRESHOLD_INTERRUPT // 低阈值中断模式,低于阈值时触发中断
* HIGH_THRESHOLD_INTERRUPT // 高阈值中断模式,高于阈值时触发中断
* threshold //阈值范围,默认扩大16倍,例如:低阈值模式下传入阈值1,实际低于16的地磁数据都会触发中断
* polarity:
* POLARITY_HIGH // 高极性
* POLARITY_LOW // 低极性
* 如果想使用更多参数请参考.h文件中的 setThresholdInterrput() 函数
*/
bmm150.setThresholdInterrupt(LOW_THRESHOLD_INTERRUPT, 0, POLARITY_LOW);
#if defined(ESP32) || defined(ESP8266)||defined(ARDUINO_SAM_ZERO)
/**!
根据设置的INT引脚极性选择
INPUT_PULLUP // 低极性,设置13号引脚为上拉输入
INPUT_PULLDOWN // 高极性,设置13号引脚为下拉输入
interput io
All pins can be used. Pin 13 is recommended
*/
pinMode(/*Pin */13 ,INPUT_PULLUP);
attachInterrupt(/*interput io*/13, myInterrupt, LOW);
#else
/**! The Correspondence Table of AVR Series Arduino Interrupt Pins And Terminal Numbers
* ---------------------------------------------------------------------------------------
* | | Pin | 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 |
* |-------------------------------------------------------------------------------------------------------------------------------------------|
*/
/**!
根据设置的INT引脚极性选择
INPUT_PULLUP // 低极性,设置2号引脚为上拉输入
*/
pinMode(/*Pin */2 ,INPUT_PULLUP);
/**!
设置引脚为中断模式
// Open the external interrupt 0, connect INT1/2 to the digital pin of the main control:
function
callback function
state
LOW // 当引脚为低电平后产生中断,进入interrupt函数
*/
attachInterrupt(/*Interrupt No*/0, /*function*/myInterrupt ,/*state*/LOW );
#endif
}
void loop()
{
/**!
* 获取发生阈值中断的数据,和中断的状态 (软件获取数据准备的状态)
* 返回存放地磁数据的结构体,结构体存放三轴当数据和中断状态,
* xyz轴的数据为NO_DATA时未触发中断
* 如果想查看中断状态请查看.h文件
*/
/*
sThresholdData 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();
*/
/**!
当INT io口产生了中断,获取阈值中断的数据(硬件获取阈值中断的状态)
*/
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)||defined(ARDUINO_SAM_ZERO)
attachInterrupt(13, myInterrupt, LOW);
#else
attachInterrupt(0, myInterrupt ,LOW);
#endif
}
delay(100);
}
结果
树莓派使用教程
准备
-
硬件
- 树莓派4代B型(或类似)主控板 x 1
- BMM150三轴数字地磁传感器 x 1
- 若干杜邦线 x 1
-
软件
接线图
- 将模块与树莓派按照连线图相连。I2C地址默认为0x13.
安装驱动
- 启动树莓派的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
- 下载BMM150驱动库。在终端中,依次键入如下指令,并回车:
cd Desktop
git clone https://github.com/DFRobot/DFRobot_BMM150
样例代码
- 样例代码1-获取配置状态(get_all_state.py)
- 样例代码2-获取三轴地磁数据、罗盘角度(get_geomagnetic_data.py)
- 样例代码3-准备中断功能(data_ready_interrupt.py)
- 样例代码4-阈值中断功能(threshold_interrupt.py)
样例代码1-获取配置状态(get_all_state.py)
- 在终端中,键入如下指令并回车,运行样例代码:
cd DFRobot_BMM150/python/raspberrypi/examples
cd get_all_state
python get_all_state.py
结果
样例代码2-获取三轴地磁数据、罗盘角度(get_geomagnetic_data.py))
- 在终端中,键入如下指令并回车,运行样例代码:
cd DFRobot_BMM150/python/raspberrypi/examples
cd get_geomagnetic_data
python get_geomagnetic_data.py
结果
样例代码3-准备中断功能(data_ready_interrupt.py)
- 在终端中,键入如下指令并回车,运行样例代码:
cd DFRobot_BMM150/python/raspberrypi/examples
cd data_ready_interrupt
python data_ready_interrupt.py.py
结果
样例代码4-阈值中断功能(threshold_interrupt.py)
- 在终端中,键入如下指令并回车,运行样例代码:
cd DFRobot_BMM150/python/raspberrypi/examples
cd threshold_interrupt
python threshold_interrupt.py
结果
常见问题
还没有客户对此产品有任何问题,欢迎通过qq或者论坛联系我们!
更多问题及有趣的应用,可以 访问论坛 进行查阅或发帖。