找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 6788|回复: 42
打印 上一主题 下一主题
收起左侧

【Arduino】168种传感器模块系列实验(158)---QMC5883L三轴罗盘

[复制链接]
跳转到指定楼层
楼主
37款传感器与模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止37种的。鉴于本人手头积累了一些传感器和执行器模块,依照实践出真知(一定要动手做)的理念,以学习和交流为目的,这里准备逐一动手试试做实验,不管成功与否,都会记录下来---小小的进步或是搞不定的问题,希望能够抛砖引玉。

【Arduino】168种传感器模块系列实验(资料代码+图形编程+仿真编程)
实验一百五十八:QMC5883L电子指南针罗盘模块 三轴磁场传感器GY-271









分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:513258 发表于 2021-1-22 21:40 | 只看该作者


QMC5883L
源于Honeywell的HMC5883L,是一款表面贴装的集成了信号处理电路的三轴磁性传感器,应用场景主要包括罗盘、导航、无人机、机器人和手持设备等一些高精度的场合。HMC5883是霍尼韦尔公司生产的一款地磁场检测芯片,其国产替代产品为QMC5883。这两种芯片基本相似,QMC 5883也是号称得到了霍尼韦尔公司的授权。

回复

使用道具 举报

板凳
ID:513258 发表于 2021-1-23 08:57 | 只看该作者
QMC5883L特征
(1)霍尼韦尔(中国)QMC5883L是一款表面贴装多芯片模块,设计用于具有数字接口的低场磁感应,适用于低成本指南针和磁力计等应用
(2)结合低噪声AMR传感器的12位ADC在±8高斯场中实现5毫高斯场分辨率
(3)低电压运行,低功耗; 支持内置的自检
(4)内置式皮带驱动电路,I2C数字接口,宽磁场范围(+/- 8 oe)
(5)工作电压:3.3v-5v; PCB尺寸:1.3 x 2.3厘米(QMC5883L尺寸:3.0 x 3.0 x 0.9毫米),带有16引脚无铅芯片载体(LCC)




回复

使用道具 举报

地板
ID:513258 发表于 2021-1-23 09:39 | 只看该作者
QMC5883L内部原理图




回复

使用道具 举报

5#
ID:513258 发表于 2021-1-23 09:57 | 只看该作者
QMC5883L是一款多芯片三轴磁传感器。 这个表面贴装的小尺寸芯片集成了磁传感器信号条件ASIC,面向高精度应用,例如无人机,机器人,移动设备中的指南针,导航和游戏个人手持设备。

QMC5883L基于最新的高分辨率,霍尼韦尔AMR技术授权的磁阻技术。结合定制设计的16位ADC ASIC,它具有以下优势:
低噪声,高精度,低功耗,偏移消除和温度补偿。 QMC5883L启用1°至2°指南针航向精度。 I2C串行总线可简化接口。QMC5883L位于3x3x0.9mm3中表面贴装16针焊盘栅格阵列(LGA)封装。

功能
1、3x3x0.9 mm3中的3轴磁阻传感器陆地栅格阵列封装(LGA),保证在扩展的温度范围内工作-40°C至+85°C。
2、具有低噪声AMR传感器的16位ADC实现2毫高斯场分辨率。
3、宽磁场范围(±8高斯)。
4、温度补偿数据输出和温度输出。
5、具有标准模式和快速模式的I2C接口。
6、宽范围工作电压(2.16V至3.6V)和低功耗(75uA)。
7、无铅封装构造。
8、提供软件和算法支持。

优点
1、体积小,适用于高度集成的产品。 信号有已数字化和校准。
2、启用1°至2°度的罗盘航向精度,允许导航和LBS应用。
3、最大化传感器的完整动态范围和分辨率。
4、在宽广的范围内自动保持传感器的灵敏度工作温度范围。
5、用于快速数据通信的高速接口,最大200Hz数据输出速率。
6、兼容电池供电的应用。
7、符合RoHS标准。
8、罗盘航向,硬铁,软铁和自动可用校准库。




回复

使用道具 举报

6#
ID:513258 发表于 2021-1-23 10:23 | 只看该作者
QMC5883L封装3-D视图
箭头指示在正常测量中产生正输出读数的磁场方向组态。




回复

使用道具 举报

7#
ID:513258 发表于 2021-1-23 10:51 | 只看该作者

回复

使用道具 举报

8#
ID:513258 发表于 2021-1-23 10:55 | 只看该作者




回复

使用道具 举报

9#
ID:513258 发表于 2021-1-23 11:08 | 只看该作者
外部连接
双电源连接



回复

使用道具 举报

10#
ID:513258 发表于 2021-1-23 11:10 | 只看该作者

单电源连接



回复

使用道具 举报

11#
ID:513258 发表于 2021-1-23 11:22 | 只看该作者
QMC5883L性能




回复

使用道具 举报

12#
ID:513258 发表于 2021-1-23 11:25 | 只看该作者

回复

使用道具 举报

13#
ID:513258 发表于 2021-1-23 11:27 | 只看该作者

回复

使用道具 举报

14#
ID:513258 发表于 2021-1-23 11:28 | 只看该作者

回复

使用道具 举报

15#
ID:513258 发表于 2021-1-23 11:30 | 只看该作者

回复

使用道具 举报

16#
ID:513258 发表于 2021-1-23 11:32 | 只看该作者



回复

使用道具 举报

17#
ID:513258 发表于 2021-1-23 11:56 | 只看该作者
GY-271 QMC5883L模块 电子指南针罗盘模块 三轴磁场传感器

采用高品质沉金pcb,机器焊接工艺,保证品质
名称:QMC5883L模块(三轴磁场模块)
型号:GY-271使用芯片:QMC5883L
供电电源:3-5v
通信方式:IIC通信协议
测量范围:±1.3-8 高斯



回复

使用道具 举报

18#
ID:513258 发表于 2021-1-23 12:01 | 只看该作者
该模块包括一个最新的高分辨率QMC5883X系列磁阻传感器,一个包含放大功能的ASIC,自动消磁带驱动器,失调消除以及一个12位ADC,可实现1°至2°的罗盘 航向精度。 I2C串行总线可简化接口。电原理图如下。





回复

使用道具 举报

19#
ID:513258 发表于 2021-1-23 12:08 | 只看该作者


引脚功能
VCC + 5V-电源引脚,给它3.3v-5VDC。 对于Arduino,建议5v
GND-接地引脚
SDA和SCL-这些是I2C数据和时钟引脚,用于从模块向微控制器发送和接收数据。 这些引脚上有1万上拉至3.3v引脚。 您可以将这些引脚连接到5V I2C线路,板上有电平转换器,可将引脚安全降低到3V
DRDY-这是“数据就绪”引脚输出。 如果要高速流传输数据(每秒超过100次),则可以在准备好读取数据时收听此引脚。 有关使用DRDY引脚的更多详细信息,请参见数据表,我们不使用它,因为我们读得不快!

Build the circuit
QMC5883L--------------- Uno/Mega2560
VCC------------------- 5V
GND------------------- GND
SCL------------------- A5/ pin21 mega2560
SDA------------------- A4/pin20 mega2560
DRDY------------------ N/C

回复

使用道具 举报

20#
ID:513258 发表于 2021-1-23 13:37 | 只看该作者

QMC5883L模块的几个定义:

AMR Bridge:三轴磁性传感器

MUX:多路复用通道

PGA:可编程控制的传感器信号增益放大器

Signal Conditioning:进行磁场信号校正及补偿的数字模块

ADC:16位的模数转换器

I2C:总线形式

NVM:用于校正的非易失性存储器

SET/RST Driver:用于初始化磁性传感器的内部驱动

Reference:用于内部偏移的电压/电流基准

Clock Gen.:内部振荡器,用于内部操作

POR:上电复位

Temperature Sensor:用于内部精度/偏移的温度传感器,也可以用于测量温度并输出

QMC5883L有两种工作模式:连续测量模式和待命模式。




回复

使用道具 举报

21#
ID:513258 发表于 2021-1-23 13:42 | 只看该作者
QMC5883L模块实验接线示意图




回复

使用道具 举报

22#
ID:513258 发表于 2021-1-23 14:14 | 只看该作者
安装QMC5883库,在网上搜到不少相关的库:
keepworking /Mecha_QMC5883L
https://github.com/keepworking/mecha_qmc5883l











回复

使用道具 举报

23#
ID:513258 发表于 2021-1-24 19:05 | 只看该作者
项目一:简易测量方位角度的实验开源代码



  1. /*
  2.   【Arduino】168种传感器模块系列实验(资料代码+图形编程+仿真编程)
  3.    实验一百五十八:QMC5883L电子指南针罗盘模块 三轴磁场传感器GY-271
  4.   1、安装库:IDE--工具--管理库--搜索“QMC5883L”--安装QMC5883LCompass
  5.   2、项目一:简易测量方位角度
  6.   3、实验接线:
  7.   QMC5883L-------------- UNO
  8.   VCC------------------- 5V
  9.   GND------------------- GND
  10.   SCL ------------------- A5
  11.   SDA------------------- A4
  12.   DRDY------------------ N/C
  13. */

  14. #include <QMC5883LCompass.h>

  15. QMC5883LCompass compass;

  16. void setup() {
  17.   Serial.begin(9600);
  18.   compass.init();

  19. }

  20. void loop() {
  21.   int a;

  22.   // 读取罗盘值
  23.   compass.read();

  24.   // 返回方位角读数
  25.   a = compass.getAzimuth();

  26.   Serial.print("A: ");
  27.   Serial.print(a);
  28.   Serial.println();

  29.   delay(500);
  30. }
复制代码




回复

使用道具 举报

24#
ID:513258 发表于 2021-1-24 19:12 | 只看该作者
实验串口返回情况






回复

使用道具 举报

25#
ID:513258 发表于 2021-1-24 19:25 | 只看该作者
实验场景图




回复

使用道具 举报

26#
ID:513258 发表于 2021-1-24 20:14 | 只看该作者
项目二:简易测量方位角度的实验开源代码(数值在0-11之间,每个数值间隔30度)


  1. /*
  2.   【Arduino】168种传感器模块系列实验(资料代码+图形编程+仿真编程)
  3.    实验一百五十八:QMC5883L电子指南针罗盘模块 三轴磁场传感器GY-271
  4.   1、安装库:IDE--工具--管理库--搜索“QMC5883L”--安装QMC5883LCompass
  5.   2、项目二:简易测量方位角度(数值在0-11之间,每个数值间隔30度)
  6.   3、实验接线:
  7.   QMC5883L-------------- UNO
  8.   VCC------------------- 5V
  9.   GND------------------- GND
  10.   SCL ------------------- A5
  11.   SDA------------------- A4
  12.   DRDY------------------ N/C
  13. */

  14. #include <QMC5883LCompass.h>

  15. QMC5883LCompass compass;

  16. void setup() {
  17.   Serial.begin(9600);
  18.   compass.init();
  19. }

  20. void loop() {
  21.   compass.read();

  22.   byte a = compass.getAzimuth();
  23.   // 根据方位/方位角的方向,此处的输出将是介于0到11之间的值。
  24.   byte b = compass.getBearing(a);
  25.   
  26.   Serial.print("B: ");
  27.   Serial.print(b);
  28.   Serial.println();
  29.   
  30.   delay(250);
  31. }
复制代码



回复

使用道具 举报

27#
ID:513258 发表于 2021-1-24 20:26 | 只看该作者
实验串口返回情况




回复

使用道具 举报

28#
ID:513258 发表于 2021-1-24 20:46 | 只看该作者

知识点:方位角

又称地平经度(Azimuth angle,缩写为Az),是在平面上量度物体之间的角度差的方法之一。是从某点的指北方向线起,依顺时针方向到目标方向线之间的水平夹角,用“度”和“密位”表示。常用于判定方位、指示目标和保持行进方向。


从真子午线起算的为真方位角,通常在精密测量中使用,从磁子午线起算的方磁方位角,在航空、航海、炮兵射击、军队行进时广泛使用,从地形图的坐标纵线起算的为坐标方位角,炮兵使用较多。磁方位角与真方位角的关系式为:磁方位角=真方位角-(±磁偏角)。坐标方位角与磁方位角的关系式为:坐标方位角=磁方位角+ (±磁坐偏角)。


从标准方向的北端起,顺时针方向到直线的水平角称为该直线的方位角。以北点为起算点,由北点开始按顺时针方向计量。方位角的取值范围为0~360度,北点为0°,东点为90°,南点为180°,西点为270°。





回复

使用道具 举报

29#
ID:513258 发表于 2021-1-24 21:05 | 只看该作者
QMC5883L Compass是一个Arduino库,用于将QMC5583L系列模块使用指南针(电子罗盘)功能。支持:

1、获取XYZ轴的值。
2、计算方位角。
3、获得16点方位角轴承方向(0-15)。
4、获取16点方位角轴承名称(N,NNE,NE,ENE,E,ESE,SE,SSE,S,SSW,SW,WSW,W,WNW,NW,NNW)
5、通过滚动平均和最小/最大消除来平滑XYZ读数。
6、任选的芯片组模式。


QMC5883LCompass.cpp 库文件


  1. /*
  2. ===============================================================================================================
  3. QMC5883LCompass.h
  4. Library for using QMC5583L series chip boards as a compass.
  5. Learn more at [https://github.com/mprograms/QMC5883LCompass]
  6. Supports:
  7. - Getting values of XYZ axis.
  8. - Calculating Azimuth.
  9. - Getting 16 point Azimuth bearing direction (0 - 15).
  10. - Getting 16 point Azimuth bearing Names (N, NNE, NE, ENE, E, ESE, SE, SSE, S, SSW, SW, WSW, W, WNW, NW, NNW)
  11. - Smoothing of XYZ readings via rolling averaging and min / max removal.
  12. - Optional chipset modes (see below)
  13. ===============================================================================================================
  14. v1.0 - June 13, 2019
  15. Written by MRPrograms
  16. Github: [https://github.com/mprograms/]
  17. Release under the GNU General Public License v3
  18. [https://www.gnu.org/licenses/gpl-3.0.en.html]
  19. ===============================================================================================================
  20. FROM QST QMC5883L Datasheet [https://nettigo.pl/attachments/440]
  21. -----------------------------------------------
  22. MODE CONTROL (MODE)
  23.         Standby                        0x00
  24.         Continuous                0x01
  25. OUTPUT DATA RATE (ODR)
  26.         10Hz                0x00
  27.         50Hz                0x04
  28.         100Hz               0x08
  29.         200Hz               0x0C
  30. FULL SCALE (RNG)
  31.         2G                  0x00
  32.         8G                  0x10
  33. OVER SAMPLE RATIO (OSR)
  34.         512                 0x00
  35.         256                 0x40
  36.         128                 0x80
  37.         64                  0xC0
  38.   
  39. */



  40. #include "Arduino.h"
  41. #include "QMC5883LCompass.h"
  42. #include <Wire.h>

  43. QMC5883LCompass::QMC5883LCompass() {
  44. }


  45. /**
  46.         INIT
  47.         Initialize Chip - This needs to be called in the sketch setup() function.
  48.        
  49.         @since v0.1;
  50. **/
  51. void QMC5883LCompass::init(){
  52.         Wire.begin();
  53.         _writeReg(0x0B,0x01);
  54.         setMode(0x01,0x0C,0x10,0X00);
  55. }


  56. /**
  57.         SET ADDRESS
  58.         Set the I2C Address of the chip. This needs to be called in the sketch setup() function.
  59.        
  60.         @since v0.1;
  61. **/
  62. // Set I2C Address if different then default.
  63. void QMC5883LCompass::setADDR(byte b){
  64.         _ADDR = b;
  65. }




  66. /**
  67.         REGISTER
  68.         Write the register to the chip.
  69.        
  70.         @since v0.1;
  71. **/
  72. // Write register values to chip
  73. void QMC5883LCompass::_writeReg(byte r, byte v){
  74.         Wire.beginTransmission(_ADDR);
  75.         Wire.write(r);
  76.         Wire.write(v);
  77.         Wire.endTransmission();
  78. }


  79. /**
  80.         CHIP MODE
  81.         Set the chip mode.
  82.        
  83.         @since v0.1;
  84. **/
  85. // Set chip mode
  86. void QMC5883LCompass::setMode(byte mode, byte odr, byte rng, byte osr){
  87.         _writeReg(0x09,mode|odr|rng|osr);
  88. }


  89. /**
  90.         RESET
  91.         Reset the chip.
  92.        
  93.         @since v0.1;
  94. **/
  95. // Reset the chip
  96. void QMC5883LCompass::setReset(){
  97.         _writeReg(0x0A,0x80);
  98. }

  99. // 1 = Basic 2 = Advanced
  100. void QMC5883LCompass::setSmoothing(byte steps, bool adv){
  101.         _smoothUse = true;
  102.         _smoothSteps = ( steps > 10) ? 10 : steps;
  103.         _smoothAdvanced = (adv == true) ? true : false;
  104. }

  105. /**
  106.     SET CALIBRATION
  107.         Set calibration values for more accurate readings
  108.                
  109.         @author Claus N&auml;veke - TheNitek [https://github.com/TheNitek]
  110.        
  111.         @since v1.1.0
  112. **/
  113. void QMC5883LCompass::setCalibration(int x_min, int x_max, int y_min, int y_max, int z_min, int z_max){
  114.         _calibrationUse = true;

  115.         _vCalibration[0][0] = x_min;
  116.         _vCalibration[0][1] = x_max;
  117.         _vCalibration[1][0] = y_min;
  118.         _vCalibration[1][1] = y_max;
  119.         _vCalibration[2][0] = z_min;
  120.         _vCalibration[2][1] = z_max;
  121. }



  122. /**
  123.         READ
  124.         Read the XYZ axis and save the values in an array.
  125.        
  126.         @since v0.1;
  127. **/
  128. void QMC5883LCompass::read(){
  129.         Wire.beginTransmission(_ADDR);
  130.         Wire.write(0x00);
  131.         int err = Wire.endTransmission();
  132.         if (!err) {
  133.                 Wire.requestFrom(_ADDR, (byte)6);
  134.                 _vRaw[0] = (int)(int16_t)(Wire.read() | Wire.read() << 8);
  135.                 _vRaw[1] = (int)(int16_t)(Wire.read() | Wire.read() << 8);
  136.                 _vRaw[2] = (int)(int16_t)(Wire.read() | Wire.read() << 8);

  137.                 if ( _calibrationUse ) {
  138.                         _applyCalibration();
  139.                 }
  140.                
  141.                 if ( _smoothUse ) {
  142.                         _smoothing();
  143.                 }
  144.                
  145.                 //byte overflow = Wire.read() & 0x02;
  146.                 //return overflow << 2;
  147.         }
  148. }

  149. /**
  150.     APPLY CALIBRATION
  151.         This function uses the calibration data provided via @see setCalibration() to calculate more
  152.         accurate readings
  153.        
  154.         @author Claus N&auml;veke - TheNitek [https://github.com/TheNitek]
  155.        
  156.         Based on this awesome article:
  157.         https://appelsiini.net/2018/calibrate-magnetometer/
  158.        
  159.         @since v1.1.0
  160.        
  161. **/
  162. void QMC5883LCompass::_applyCalibration(){
  163.         int x_offset = (_vCalibration[0][0] + _vCalibration[0][1])/2;
  164.         int y_offset = (_vCalibration[1][0] + _vCalibration[1][1])/2;
  165.         int z_offset = (_vCalibration[2][0] + _vCalibration[2][1])/2;
  166.         int x_avg_delta = (_vCalibration[0][1] - _vCalibration[0][0])/2;
  167.         int y_avg_delta = (_vCalibration[1][1] - _vCalibration[1][0])/2;
  168.         int z_avg_delta = (_vCalibration[2][1] - _vCalibration[2][0])/2;

  169.         int avg_delta = (x_avg_delta + y_avg_delta + z_avg_delta) / 3;

  170.         float x_scale = (float)avg_delta / x_avg_delta;
  171.         float y_scale = (float)avg_delta / y_avg_delta;
  172.         float z_scale = (float)avg_delta / z_avg_delta;

  173.         _vCalibrated[0] = (_vRaw[0] - x_offset) * x_scale;
  174.         _vCalibrated[1] = (_vRaw[1] - y_offset) * y_scale;
  175.         _vCalibrated[2] = (_vRaw[2] - z_offset) * z_scale;
  176. }


  177. /**
  178.         SMOOTH OUTPUT
  179.         This function smooths the output for the XYZ axis. Depending on the options set in
  180.         @see setSmoothing(), we can run multiple methods of smoothing the sensor readings.
  181.        
  182.         First we store (n) samples of sensor readings for each axis and store them in a rolling array.
  183.         As each new sensor reading comes in we replace it with a new reading. Then we average the total
  184.         of all (n) readings.
  185.        
  186.         Advanced Smoothing
  187.         If you turn advanced smoothing on, we will select the min and max values from our array
  188.         of (n) samples. We then subtract both the min and max from the total and average the total of all
  189.         (n - 2) readings.
  190.        
  191.         NOTE: This function does several calculations and can cause your sketch to run slower.
  192.        
  193.         @since v0.3;
  194. **/
  195. void QMC5883LCompass::_smoothing(){
  196.         byte max = 0;
  197.         byte min = 0;
  198.        
  199.         if ( _vScan > _smoothSteps - 1 ) { _vScan = 0; }
  200.        
  201.         for ( int i = 0; i < 3; i++ ) {
  202.                 if ( _vTotals[i] != 0 ) {
  203.                         _vTotals[i] = _vTotals[i] - _vHistory[_vScan][i];
  204.                 }
  205.                 _vHistory[_vScan][i] = ( _calibrationUse ) ? _vCalibrated[i] : _vRaw[i];
  206.                 _vTotals[i] = _vTotals[i] + _vHistory[_vScan][i];
  207.                
  208.                 if ( _smoothAdvanced ) {
  209.                         max = 0;
  210.                         for (int j = 0; j < _smoothSteps - 1; j++) {
  211.                                 max = ( _vHistory[j][i] > _vHistory[max][i] ) ? j : max;
  212.                         }
  213.                        
  214.                         min = 0;
  215.                         for (int k = 0; k < _smoothSteps - 1; k++) {
  216.                                 min = ( _vHistory[k][i] < _vHistory[min][i] ) ? k : min;
  217.                         }
  218.                                        
  219.                         _vSmooth[i] = ( _vTotals[i] - (_vHistory[max][i] + _vHistory[min][i]) ) / (_smoothSteps - 2);
  220.                 } else {
  221.                         _vSmooth[i] = _vTotals[i]  / _smoothSteps;
  222.                 }
  223.         }
  224.        
  225.         _vScan++;
  226. }


  227. /**
  228.         GET X AXIS
  229.         Read the X axis
  230.        
  231.         @since v0.1;
  232.         @return int x axis
  233. **/
  234. int QMC5883LCompass::getX(){
  235.         return _get(0);
  236. }


  237. /**
  238.         GET Y AXIS
  239.         Read the Y axis
  240.        
  241.         @since v0.1;
  242.         @return int y axis
  243. **/
  244. int QMC5883LCompass::getY(){
  245.         return _get(1);
  246. }


  247. /**
  248.         GET Z AXIS
  249.         Read the Z axis
  250.        
  251.         @since v0.1;
  252.         @return int z axis
  253. **/
  254. int QMC5883LCompass::getZ(){
  255.         return _get(2);
  256. }

  257. /**
  258.         GET SENSOR AXIS READING
  259.         Get the smoothed, calibration, or raw data from a given sensor axis
  260.        
  261.         @since v1.1.0
  262.         @return int sensor axis value
  263. **/
  264. int QMC5883LCompass::_get(int i){
  265.         if ( _smoothUse )
  266.                 return _vSmooth[i];
  267.        
  268.         if ( _calibrationUse )
  269.                 return _vCalibrated[i];

  270.         return _vRaw[i];
  271. }



  272. /**
  273.         GET AZIMUTH
  274.         Calculate the azimuth (in degrees);
  275.        
  276.         @since v0.1;
  277.         @return int azimuth
  278. **/
  279. int QMC5883LCompass::getAzimuth(){
  280.         int a = atan2( getY(), getX() ) * 180.0 / PI;
  281.         return a < 0 ? 360 + a : a;
  282. }


  283. /**
  284.         GET BEARING
  285.         Divide the 360 degree circle into 16 equal parts and then return the a value of 0-15
  286.         based on where the azimuth is currently pointing.
  287.        
  288.         @since v1.0.1 - function now requires azimuth parameter.
  289.         @since v0.2.0 - initial creation
  290.        
  291.         @return byte direction of bearing
  292. */
  293. byte QMC5883LCompass::getBearing(int azimuth){
  294.         unsigned long a = azimuth / 22.5;
  295.         unsigned long r = a - (int)a;
  296.         byte sexdec = 0;       
  297.         sexdec = ( r >= .5 ) ? ceil(a) : floor(a);
  298.         return sexdec;
  299. }


  300. /**
  301.         This will take the location of the azimuth as calculated in getBearing() and then
  302.         produce an array of chars as a text representation of the direction.
  303.        
  304.         NOTE: This function does not return anything since it is not possible to return an array.
  305.         Values must be passed by reference back to your sketch.
  306.        
  307.         Example:
  308.        
  309.         ( if direction is in 1 / NNE)
  310.        
  311.         char myArray[3];
  312.         compass.getDirection(myArray, azimuth);
  313.        
  314.         Serial.print(myArray[0]); // N
  315.         Serial.print(myArray[1]); // N
  316.         Serial.print(myArray[2]); // E
  317.        
  318.        
  319.         @see getBearing();
  320.        
  321.         @since v1.0.1 - function now requires azimuth parameter.
  322.         @since v0.2.0 - initial creation
  323. */
  324. void QMC5883LCompass::getDirection(char* myArray, int azimuth){
  325.         int d = getBearing(azimuth);
  326.         myArray[0] = _bearings[d][0];
  327.         myArray[1] = _bearings[d][1];
  328.         myArray[2] = _bearings[d][2];
  329. }
复制代码




回复

使用道具 举报

30#
ID:513258 发表于 2021-1-24 21:07 | 只看该作者
QMC5883LCompass.h 库文件

  1. #ifndef QMC5883L_Compass
  2. #define QMC5883L_Compass

  3. #include "Arduino.h"
  4. #include "Wire.h"


  5. class QMC5883LCompass{
  6.        
  7.   public:
  8.     QMC5883LCompass();
  9.         void init();
  10.     void setADDR(byte b);
  11.     void setMode(byte mode, byte odr, byte rng, byte osr);
  12.         void setSmoothing(byte steps, bool adv);
  13.         void setCalibration(int x_min, int x_max, int y_min, int y_max, int z_min, int z_max);
  14.     void setReset();
  15.     void read();
  16.         int getX();
  17.         int getY();
  18.         int getZ();
  19.         int getAzimuth();
  20.         byte getBearing(int azimuth);
  21.         void getDirection(char* myArray, int azimuth);
  22.        
  23.   private:
  24.     void _writeReg(byte reg,byte val);
  25.         int _get(int index);
  26.         bool _smoothUse = false;
  27.         byte _smoothSteps = 5;
  28.         bool _smoothAdvanced = false;
  29.     byte _ADDR = 0x0D;
  30.         int _vRaw[3] = {0,0,0};
  31.         int _vHistory[10][3];
  32.         int _vScan = 0;
  33.         long _vTotals[3] = {0,0,0};
  34.         int _vSmooth[3] = {0,0,0};
  35.         void _smoothing();
  36.         bool _calibrationUse = false;
  37.         int _vCalibration[3][2];
  38.         int _vCalibrated[3];
  39.         void _applyCalibration();
  40.         const char _bearings[16][3] =  {
  41.                 {' ', ' ', 'N'},
  42.                 {'N', 'N', 'E'},
  43.                 {' ', 'N', 'E'},
  44.                 {'E', 'N', 'E'},
  45.                 {' ', ' ', 'E'},
  46.                 {'E', 'S', 'E'},
  47.                 {' ', 'S', 'E'},
  48.                 {'S', 'S', 'E'},
  49.                 {' ', ' ', 'S'},
  50.                 {'S', 'S', 'W'},
  51.                 {' ', 'S', 'W'},
  52.                 {'W', 'S', 'W'},
  53.                 {' ', ' ', 'W'},
  54.                 {'W', 'N', 'W'},
  55.                 {' ', 'N', 'W'},
  56.                 {'N', 'N', 'W'},
  57.         };
  58.        
  59.        
  60.        
  61. };

  62. #endif
复制代码




回复

使用道具 举报

31#
ID:513258 发表于 2021-1-25 10:12 | 只看该作者
实验开源代码,
项目三:通过串口实时绘制电子罗盘方位角的波形



  1. /*
  2.   【Arduino】168种传感器模块系列实验(资料代码+图形编程+仿真编程)
  3.    实验一百五十八:QMC5883L电子指南针罗盘模块 三轴磁场传感器GY-271
  4.   1、安装库:IDE--工具--管理库--搜索“QMC5883L”--安装QMC5883LCompass
  5.   2、项目三:通过串口实时绘制电子罗盘方位角的波形
  6.   3、实验接线:
  7.   QMC5883L-------------- UNO
  8.   VCC------------------- 5V
  9.   GND------------------- GND
  10.   SCL ------------------- A5
  11.   SDA------------------- A4
  12.   DRDY------------------ N/C
  13. */

  14. #include <QMC5883LCompass.h>

  15. QMC5883LCompass compass;

  16. void setup() {
  17.   Serial.begin(9600);
  18.   compass.init();

  19. }

  20. void loop() {
  21.   int a;

  22.   // 读取罗盘值
  23.   compass.read();

  24.   // 返回方位角读数
  25.   a = compass.getAzimuth();

  26.   Serial.print("电子罗盘方位角: ");
  27.   Serial.print(a);
  28.   Serial.println();

  29.   delay(800);
  30. }
复制代码







回复

使用道具 举报

32#
ID:513258 发表于 2021-1-25 10:15 | 只看该作者
用手转动QMC5883L模块,串口输出的实时波形,数值在0--359°之间波动,简单又直观。






回复

使用道具 举报

33#
ID:513258 发表于 2021-1-25 10:17 | 只看该作者
串口输出的实时数值





回复

使用道具 举报

34#
ID:513258 发表于 2021-1-25 11:07 | 只看该作者
QMC5883L Compass库函数的几个使用要点

1、QMC5883L与Arduino Uno / Nano的连接

VCC  O ---- O +5v
GND  O ---- O GND
SCL  O ---- O A5
SDA  O ---- O A4
DRDY O ---- X NOT CONNECTED

2、入门
首先,在程序顶部包括QMC5883L指南针库。

#include <QMC5883LCompass.h>
QMC5883LCompass compass;

然后在setup()函数中添加:

void setup(){
  compass.init();
}

3、获取X,Y或Z轴的数值
要获取X,Y或Z传感器的读数,只需调用所需的功能。

void loop(){
   int x = compass.getX();
   int y = compass.getY();
   int z = compass.getZ();
}

回复

使用道具 举报

35#
ID:513258 发表于 2021-1-25 11:11 | 只看该作者
4、获取方位角的数值
要获取计算出的方位角(罗盘度)值,只需调用getAzimuth();。
void loop(){
   int a = compass.getAzimuth();
}
5、获取方向/方位
QMC5883L指南针库可计算传感器指向的方向范围和方向。您可以调用两个函数。
要获取传感器面向的方向的12点值,可以调用getBearing(azimuth)。这会将罗盘的360度范围划分为12个部分,并按顺时针顺序返回值0-12。在这种情况下,0 = N,4 = E,8 = S,12 =W。如果您希望滚动自己的方向输出功能而不需要计算,则此功能很有用。
void loop(){
   azimuth = compass.getAzimuth();
   byte b = compass.getBearing(azimuth);
}
要获取传感器指向方向的12点文字表示,可以致电getDirection(azimuth);。这将产生一个char数组[3],其中的字母代表每个方向。由于我们无法返回数组,因此需要通过引用传递值。
void loop(){
   azimuth = compass.getAzimuth();
   char myArray[3];
   getDirection(myArray, azimuth);
}
如果要打印这些值,可以这样:
void loop(){
   azimuth = compass.getAzimuth();
   char myArray[3];
   
   getDirection(myArray, azimuth);
   
   Serial.print(myArray[0]);
   Serial.print(myArray[1]);
   Serial.print(myArray[2]);
   Serial.println();
}

回复

使用道具 举报

36#
ID:513258 发表于 2021-1-25 11:35 | 只看该作者
6、更改I2C地址
要在调用compass.setADDR(BYTE_VALUE);之前更改I2C地址呼叫,compass.init();如下所示:


void setup(){
  compass.setADDR(BYTE);
  compass.init();
}


7、更改模式,数据速率,比例,采样率
您还可以更改QMC5583L芯片的模式,灵敏度,采样率和输出率。等等,只需在调用compass.setMode(MODE, ODR, RNG, OSR);后调用即可compass.init()。请注意,每个值必须是一个字节。设置每个模式的值在预设中,并取自QST QMC5583L数据表。





回复

使用道具 举报

37#
ID:513258 发表于 2021-1-25 11:55 | 只看该作者
8、精细QMC5583L传感器输出
在传感器读数似乎反弹的情况下,平滑可以提供帮助。QMC5883L指南针库使用滚动平均值功能来存储(N)个传感器读数并返回每个轴的平均值。该平均还对方位角和方向输出进行平滑处理。


如果启用,该功能的第二部分将采用内部滚动逐步通过的当前替代和替代,将其从总体上中删除。这可以帮助消除在错误的读数中可能发生的替代的高点和低点。


应该注意的是,内置的平滑功能将导致额外的处理时间。


compass.setSmoothing(STEPS, ADVANCED);




在循环之前启用平滑调用。


步骤:int,使结果平滑的步骤数。1到10的有效值。更高的步长等于更平滑,但处理时间缩短。


*:启用此功能将使平滑效果更好,但处理时间缩短。*


void setup(){
  compass.init();
  compass.setSmoothing(10, true);
}



回复

使用道具 举报

38#
ID:513258 发表于 2021-1-25 11:59 | 只看该作者
9、校准QMC5583L传感器
QMC5883LCompass库包含校准功能和实用程序大纲,可帮助您校准QMC5883L芯片。校准是一个两步过程。


步骤1:运行校准程序
a、确保已连接QMC5883L芯片。
b、在示例> QMC5883LCOMPASS>校准下找到随附的校准草图。
c、将校准草图上传到您的arduino,然后打开串行监视器。
d、校准过程开始时,通过移动传感器来伴随屏幕上的指示。
c、收集完所有校准数据后,复制副本的代码


compass.setCalibration(-1537, 1266, -1961, 958, -1342, 1492);




可能需要保存它以备将来参考。


步骤2:使用校正资料
a、项目的程序,将然后复制的代码行直接插入到compass.init()调用下方。
b、照常使用QMC5883LCompass库。

建议您使用提供的校准草图来生成传感器的预设和替代,但也可以使用该


compass.setCalibration(X_MIN, X_MAX, Y_MIN, Y_MAX, Z_MIN, Z_MAX);




函数添加自己的预设和替代。


回复

使用道具 举报

39#
ID:513258 发表于 2021-1-25 13:16 | 只看该作者
实验开源代码
项目四:通过串口实时绘制电子罗盘方位(12等分)的波形
说明:实时数值 0 = N,3 = E,6 = S,9 =W

  1. /*
  2.   【Arduino】168种传感器模块系列实验(资料代码+图形编程+仿真编程)
  3.    实验一百五十八:QMC5883L电子指南针罗盘模块 三轴磁场传感器GY-271
  4.   1、安装库:IDE--工具--管理库--搜索“QMC5883L”--安装QMC5883LCompass
  5.   2、项目四:通过串口实时绘制电子罗盘方位(12等分)的波形
  6.   3、实验接线:
  7.   QMC5883L-------------- UNO
  8.   VCC------------------- 5V
  9.   GND------------------- GND
  10.   SCL ------------------- A5
  11.   SDA------------------- A4
  12.   DRDY------------------ N/C
  13.   4、说明:实时数值 0 = N,3 = E,6 = S,9 =W
  14. */

  15. #include <QMC5883LCompass.h>

  16. QMC5883LCompass compass;

  17. void setup() {
  18.   Serial.begin(9600);
  19.   compass.init();
  20. }

  21. void loop() {
  22.   compass.read();

  23.   byte a = compass.getAzimuth();
  24.   // 根据方位/方位角的方向,此处的输出将是介于0到11之间的值。
  25.   byte b = compass.getBearing(a);
  26.   
  27.   Serial.print("指南针方位: ");
  28.   Serial.print(b);
  29.   Serial.println();
  30.   
  31.   delay(800);
  32. }
复制代码




回复

使用道具 举报

40#
ID:513258 发表于 2021-1-25 14:08 | 只看该作者
用手转动QMC5883L模块,串口输出的指南针方位数值变动实时波形




回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表