玩转物联网人工智能小车(ESP32):利用HMC5883L电子罗盘模块实现方向感知

摘要:本文介绍使用HMC5883L电子罗盘模块来辨别方向

在前边制作避障小车的时候,大家可能已经发现,虽然两个轮子的驱动信号是一样的,但是小车可能不走直线,走过一端距离之后,小车就会偏向一边。这是由于电机的个体差异导致的,虽然是同一标准、同一批次生产的电动机,但在电气特性上还是存在着些许的差距,经过比较长距离的累积之后,表现出来的就是两个轮子累计转过的圈数不同,小车就会朝一边偏。

小车跑偏的一个解决办法就是通过长距离的测试,找出两个轮子转速的差距,然后调整控制信号PWM的占空比率,让转速慢的轮子占空比率大一些,而转速快的轮子占空比率小一些,就可以在很大程度上改善这个问题了。这种解决办法要经过很多次的测试,才能找到一个比较满意的参数出来。

那么有没有更好的办法呢?能不能让小车自己知道自己在朝哪个方向行驶,自己进行调整呢?答案当然是肯定的。可以给小车安装一个电子罗盘模块,让小车自己知道自己在朝着哪个方向行驶。

我们知道,地球附近的空间遍布着地磁场,地磁场的方向是从地球的地磁北极(地理南极附近)指向地磁南极(地理北极附近),传统的指南针就是利用了地磁场来辨别方向的。基于HMC5883L芯片的电子罗盘模块同样也是利用了这一原理,它通过测量相互垂直的X轴、Y轴和Z轴的磁场的磁通量大小,因为这三个方向的磁通量的矢量和始终指向地磁南极(地理北极附近),所以,就可以计算出HMC5883L电子罗盘模块的水平方向角了,从而可以确定自己的朝向。

和前面的红外测距模块一样,HMC5833L电子罗盘模块也是通过内部寄存器来和外界交互的,通过这些寄存器可以对其设置,也可以得到模块的测量数据。具体的寄存器如下表:

地址

名称

访问

用途

00

配置寄存器A

读/写

采样平均数、数据输出速率和测量配置寄存器

01

配置寄存器B

读/写

增益配置寄存器

02

模式寄存器

读/写

测量模式配置寄存器,连续模式/单一模式(默认)。

03

数据输出X MSB寄存器

通道X测量结果的高位数据。

04

数据输出X LSB寄存器

通道X测量结果的低位数据。

05

数据输出Z MSB寄存器

通道Z测量结果的高位数据。

06

数据输出Z LSB寄存器

通道Z测量结果的低位数据。

07

数据输出Y MSB寄存器

通道Y测量结果的高位数据。

08

数据输出Y LSB寄存器

通道Y测量结果的低位数据。

09

状态寄存器

测量数据状态寄存器。

10

识别寄存器A

用来识别装置

11

识别寄存器B

用来识别装置

12

识别寄存器C

用来识别装置

在这里,需要提醒一下,电子罗盘芯片有HMC5883和QMC5883两个系列,其中前者为进口芯片,后者为国产芯片,两者功能相同。但是,这两个芯片的寄存器定义不同,请在使用时确认相关文档。

对于配置寄存器的详细描述,请参考datasheet中的详细说明。

下面来看一下HMC5883L电子罗盘接口的详细说明:

序号

引脚

含义

1

VCC

电源正极(3-5V)

2

GND

电源负极

3

SCL

IIC串行时钟线

4

SDA

IIC串行数据线

5

DRDY

中断引脚,表明数据准备好了

寄存器看起来很复杂,实际上大多数情况下都不需要你直接去操作寄存器,因为有人已经给你进行了底层的封装,并提供了相应的库函数。打开“Arduino IDE”,安装HMC5883L电子罗盘模块的库函数,选择“Adafruit HMC5883L Unified”,如下图所示:

同样,使用该库函数还是那基本的几个步骤:

  1. 实例化对象
  2. 初始化模块
  3. 读取测量结果
  4. 数据处理显示

在这里,比之前复杂的就是数据处理部分,因为HMC5883L电子罗盘模块所返回的测量值,只是X、Z和Y三个方向的磁通量,因此想要计算方向,还要根据测量出来的X和Y以及你所在地的磁偏角来进行计算。具体的计算方法,请参见程序代码。

使用HMC5883L电子罗盘模块的时候,有个特别需要注意的地方是,固定HMC5883L芯片的时候,要保证它的Z轴是向上的,并且芯片处于水平状态,否则测量出来的结果是不正确的。

测试的代码如下:

#include <Wire.h>

#include <Adafruit_Sensor.h>

#include <Adafruit_HMC5883_U.h>

/* 为对象的实例分配一个唯一ID */

Adafruit_HMC5883_Unified mag = Adafruit_HMC5883_Unified(12345);

void setup(void) 

{

  Serial.begin(115200);

 

  /* 初始化传感器 */

  if(!mag.begin())

  {

    /* 未找到传感器,请检查配置…… */

    Serial.println("未找到传感器,请检查配置……");

    while(1);

  }

}

void loop(void) 

{

  /* 创建一个传感器数据对象 */ 

  sensors_event_t event;

  mag.getEvent(&event);

 

  /* 显示磁向量的值 (单位:uT) */

  Serial.print("X: "); Serial.print(event.magnetic.x); Serial.print("  ");

  Serial.print("Y: "); Serial.print(event.magnetic.y); Serial.print("  ");

  Serial.print("Z: "); Serial.print(event.magnetic.z); Serial.print("  ");Serial.println("uT");

  // 让模块的Z轴向上,并保持模块水平,这样才能得到正确的角度结果

  float heading = atan2(event.magnetic.y, event.magnetic.x);

 

  // 在这里,你必须要设置你所在位置的磁偏角,否则计算出来的结果是错误的

  // 可以使用这个网站查询你的磁偏角: http://www.magnetic-declination.com/

  // 查询到的数值是度,需要转换为弧度

  // 如果查不到你的磁偏角,请把这两行注释掉,那样测量结果会有稍微的偏移

  float declinationAngle = 0.13;

  heading += declinationAngle;

 

  // 符号修正

  if(heading < 0)

    heading += 2*PI;

   

  // 修正后,超过360度了

  if(heading > 2*PI)

    heading -= 2*PI;

   

  // 把弧度转换成角度

  float headingDegrees = heading * 180/M_PI;

 

  Serial.print("偏离正北方角度: "); Serial.println(headingDegrees);

 

  delay(500);

}

程序中已经增加了详细的注释,如果你是从开始学到现在,相信你是能看懂的,在这里就不再解释了。运行结果如下图所示:

好了,关于HMC5883L电子罗盘模块的基本使用就介绍到这里了。

物联沃分享整理
物联沃-IOTWORD物联网 » 玩转物联网人工智能小车(ESP32):利用HMC5883L电子罗盘模块实现方向感知

发表评论