使用Arduino和HMC5883L磁力计的数字罗盘_hmc5883l模块 制作指南针-程序员宅基地

技术标签: # Arduino 项目  

原文:https://circuitdigest.com/microcontroller-projects/digital-compass-with-arduino-and-hmc5883l-magnetometer

使用Arduino和HMC5883L磁力计的数字罗盘

ARDUINO的

经过**阿斯温斯·拉吉(Aswinth Raj)** 2018年11月6日
在这里插入图片描述

人脑由复杂的结构层构成,可帮助我们成为地球上的优势物种。例如,大脑中的内嗅皮层可以为您提供方向感,帮助您轻松导航到您不熟悉的地方。但是与我们不同的是,机器人和无人驾驶Ariel车辆需要某种东西来获得这种方向感,以便他们能够在新的地形和风景中自动进行操纵。不同的机器人使用不同类型的传感器来完成此任务,但是最常用的是磁力计,它可以告知机器人当前所处的地理方向。这不仅可以帮助机器人感应方向,还可以按照预定的方向和角度转弯。

由于传感器可以指示北,南,东和西的地理信息,因此我们人类也可以在需要时使用它。因此,在本文中,让我们尝试了解磁力计传感器的工作原理以及如何将其与Arduino等微控制器接口。在这里,我们将构建一个很酷的数字罗盘,它会通过发出指向北方向的LED来帮助我们找到方向。这款数字指南针是由PCBGOGO精巧地在PCB上制成的,以便下次野外出行时可以携带它,并希望我迷路只是为了用这个东西找到回家的路。让我们开始吧。

Arduino指南针项目所需的材料

  • Arduino Pro迷你版
  • HMC5883L磁力计传感器
  • LED灯-8号
  • 470Ohm电阻器– 8号
  • 桶杰克
  • 像PCBgogo这样的可靠PCB制造商
  • 迷你FTDI编程器
  • 电脑/笔记本电脑

什么是磁力计,它如何工作?

在深入探讨电路之前,让我们先了解一下磁力计及其工作原理。顾名思义,“电磁”一词并不是指奇迹中那种疯狂的突变体,他可以通过在空中弹钢琴来控制金属。哦!但是我喜欢那个他很酷的家伙。

磁力计实际上是一种设备,可以感应地球的磁极并据此指出方向。众所周知,地球是一块带有北极和南极的球形磁铁。并因此而产生磁场。磁力计感测到该磁场,并根据磁场的方向可以检测出我们所面对的方向。

HMC5883L传感器模块如何工作

作为磁力计传感器HMC5883L具有相同的功能。它上面有霍尼韦尔(中国)的HMC5883L IC。该IC具有3种磁阻材料,它们沿x,y和z轴排列。流过这些材料的电流量对地球磁场很敏感。因此,通过测量流过这些材料的电流的变化,我们可以检测到地球磁场的变化。一旦吸收了磁场的变化,就可以通过I2C协议将这些值发送到任何嵌入式控制器,例如微控制器或处理器。

由于传感器通过感应磁场来工作,因此如果在附近放置金属,则输出值将受到很大影响。可以利用这种行为将这些传感器也用作金属探测器。注意不要将磁铁靠近该传感器,因为来自磁铁的强磁场可能会触发传感器上的错误值。

HMC5883L和QMC5883L之间的区别

对于许多初学者来说,围绕这些传感器存在一个普遍的困惑。这是因为某些供应商(实际上是大多数供应商)出售了QMC5883L传感器,而不是霍尼韦尔的原始HMC5883L。这主要是因为QMC5883L比HMC5883L模块便宜。可悲的是,这两个传感器的工作方式略有不同,并且不能对两个传感器使用相同的代码。这是因为两个传感器的I2C地址不同。本教程中给出的代码仅适用于QMC5883L常用的传感器模块。
在这里插入图片描述
磁力计QMC5883L

要知道您所使用的传感器型号,您只需仔细查看IC本身,以读取上面写的内容。如果写的是类似L883的东西,那就是HMC58836L;如果写的是类似DA5883的话,那就是QMC5883L IC。下图显示了这两个模块,以方便进行低估。
在这里插入图片描述

Arduino数字指南针电路图

基于Arduino的Digital Compass的电路非常简单,我们只需要将HMC5883L传感器与Arduino接口并将8个LED连接到Arduino Pro mini的GPIO引脚即可。完整的电路图如下所示
在这里插入图片描述
传感器模块具有5个引脚出其中的DRDY(数据准备好)未在我们的项目,因为我们正在操作在连续模式中的传感器使用。Vcc和接地引脚用于从Arduino板以5V为模块供电。的SCL和SDA是I2C通信总线线路分别连接到Arduino临迷你的A4和A5 I2C引脚。由于模块本身在线路上具有上拉电阻,因此无需在外部添加它们。

为了说明方向,我们使用了8个LED,它们全部通过470欧姆的限流电阻连接到Arduino的GPIO引脚。完整电路由9V电池通过桶形插孔供电。该9V直接提供给Arduino的Vin引脚,并使用Arduino上的板载稳压器将其调节为5V。然后使用此5V电压为传感器和Arduino供电。

制作用于数字罗盘的PCB

电路的想法是将8个LED圆形放置,以便每个LED指向所有8个方向,分别是北,东北,东,东南,南,西南,西和西北。因此,就此而言,将它们整齐地排列在面包板上或什至在穿孔板上是不容易的。为该电路开发PCB将使其看起来更整洁且易于使用。因此,我打开了PCB设计软件,将LED和电阻器排列成整齐的圆形图案,并连接了走线以形成连接。完成后,我的设计如下所示。您也可以从下面给出的链接下载Gerber文件。

  • 下载用于数字罗盘PCB的Gerber文件
    在这里插入图片描述
    我将其设计为双面板,因为我希望将Arduino放在PCB的底部,以免破坏PCB顶部的外观。如果您担心必须为双面PCB付出高昂的价格,那么请耐心等待。

现在,我们的设计已经准备就绪,是时候制作它们了。要完成PCB非常简单,只需执行以下步骤

第1步: 进入www.pcbgogo.com,如果这是您第一次,请注册。然后,在“ PCB原型”选项卡中,输入PCB的尺寸,层数和所需的PCB数。我的PCB是80cm×80cm,所以标签如下
在这里插入图片描述

*第2步:单击立即报价***按钮继续。您将进入一个页面,在该页面上可以根据需要设置一些其他参数,例如使用的轨道间距等材料。但是大多数情况下,默认值都可以正常工作。我们在这里唯一需要考虑的是价格和时间。如您所见,构建时间仅为2-3天,而我们的PSB只需花费$ 5。然后,您可以根据需要选择一种首选的运输方式。
在这里插入图片描述

**步骤3:**最后一步是上传Gerber文件并继续付款。为确保流程顺利进行,PCBGOGO在继续付款之前会验证您的Gerber文件是否有效。这样,您可以确保您的PCB易于制造,并且能够按承诺达到您的要求。

组装PCB

订购该板后,几天后便到达了我手中,尽管快递员装在贴有整齐标签的包装好的盒子中,而且像往常一样,PCB的质量很棒。我分享了以下几张木板的图片,供您判断。
在这里插入图片描述
我打开了焊锡棒,开始组装电路板。由于脚印,焊盘,通孔和丝网印刷的形状和尺寸都非常合适,因此我组装电路板没有问题。拆箱后仅需10分钟即可准备好板子。

焊接后板子的几张图如下所示。
在这里插入图片描述

编程Arduino

现在我们的硬件已经准备好了,让我们研究一下必须上载到Arduino板上的程序。该代码的目的是从QMC5883L磁力计传感器读取数据并将其转换为度数(0到360)。一旦知道了度数,就必须打开指向特定方向的LED。我在此程序中使用的方向是北。因此,无论您身在何处**,板上的LED都会发光,并且LED的方向将指示“北”方向**。一旦可以稍后计算出另一个方向,就可以知道一个方向。

数字指南针项目的完整代码可在此页面的末尾找到。包含库之后,您可以直接将其上载到板上,并且可以开始使用了。但是,如果您想进一步了解代码中实际发生的情况,请进一步阅读。

如前所述,我们正在使用QMC5883L IC,要与该IC通信,我们需要知道其寄存器的I2C地址,该地址可在其数据表中找到。但幸运的是,所有这些工作已经完成,并由Github上名为keepworking的一个人打包为一个库。因此,您只需单击链接以获取ZIP文件,即可**下载QMC5883L的库**。然后,可以通过遵循Sketch-> Include Library-> Add .ZIP library将这个ZIP文件添加到您的Arduino IDE中。

添加库后,我们可以继续执行程序。我们**通过包含所需的库文件开始该程序,**如下所示。线库用于启用I2C通信,而MechaQMC5883是我们刚刚添加到Arduino的库。该库包含有关如何与EMC5883L传感器通信的所有信息。

#include <Wire.h> //导线库使用用于I2C通信
#include <MechaQMC5883.h> // QMC5883库,自从设备是QMC583而不是HMC5883

在下一行中,我们为正在使用的传感器创建一个对象名称。我用过***qmc***这个名字,但可以是任何您喜欢的名字。

MechaQMC5883 qmc ; //为snsor创建一个对象名称,我将其命名为qmc

接下来,我们进入全局变量声明。在这里,由于我们有8个LED作为输出,因此很难通过引脚名称来引用每个LED,因此我们使用数组选项来引用所有LED。数组的名称是ledPins,变量led_count是我们拥有的led的数量。它从0开始。

int ledPins [] = {2,3,4,5,6,7,8,9}; // LED连接到的输出引脚的阵列
char led_count = 7; // LED引脚总数

在*void setup*函数内部,我们还初始化了I2C通信,串行通信和传感器。然后,我们将所有LED引脚声明为输出引脚。由于我们使用了数组,因此通过使用for循环并在for循环中进行导航很容易引用所有引脚,如下所示。

void setup(){ 
  Wire.begin(); //开始I2C通讯
  Serial.begin(9600); //开始串行通讯
  qmc.init(); //初始化QMC5883传感器

  for(int thisPin = 0; thisPin <= led_count; thisPin ++){//遍历数组
    pinMode(ledPins [thisPin],OUTPUT);//将它们中所有引脚声明为输出  } 
}

在无限循环的循环中,我们必须传感器**获取x,y和z的值,**并计算传感器当前面对的程度。要读取x,y和z的值,请使用以下行

int x,y,z; 
qmc.read(&x,&y,&z); //从传感器获取X,Y和Z的值

下面显示了计算航向度的公式。由于我们不会沿z轴旋转指南针,因此我们不会考虑该值。仅当IC平面像我们的设置一样朝上时,才可以使用此公式。计算航向后,该值将在-180到180范围内,就像在所有数字罗盘中一样,我们必须将其转换为0到360。

int heading= atan2(x,y)/0.0174532925; //使用带有以下公式的X和Y参数计算度数
//将结果转换为0到360 
  if(heading <0)
  heading + = 360; 
  heading= 360-heading;

最后一步是在辉光北方向的LED指示。为此,我们有一系列if条件语句,其中检查当前度数在什么范围内,并根据该值打开LED。代码如下所示

//根据标题的值打印调试结果,并使相应的LED发光。
if (heading > 338 || heading < 22)
  {
    Serial.println("NORTH");
    digitalWrite(ledPins[0],HIGH);
  }

  if (heading > 22 && heading < 68)
  {
    Serial.println("NORTH-EAST");
    digitalWrite(ledPins[7],HIGH);
  }

  if (heading > 68 && heading < 113)
  {
    Serial.println("EAST");
    digitalWrite(ledPins[6],HIGH);
  }

  if (heading > 113 && heading < 158)
  {
    Serial.println("SOUTH-EAST");
    digitalWrite(ledPins[5],HIGH);
  }

  if (heading > 158 && heading < 203)
  {
    Serial.println("SOUTH");
    digitalWrite(ledPins[4],HIGH);
  }

  if (heading > 203 && heading < 248)
  {
    Serial.println("SOTUH-WEST");
    digitalWrite(ledPins[3],HIGH);
  }

  if (heading > 248 && heading < 293)
  {
    Serial.println("WEST");
    digitalWrite(ledPins[2],HIGH);
  }

  if (heading > 293 && heading < 338)
  {
    Serial.println("NORTH-WEST");
    digitalWrite(ledPins[1],HIGH);
  }

通过查看下表,可以了解代码值背后的逻辑。基本上,我们计算所面对的方向,并预测北向,并使相应的LED发光。

方向 方向对应的度数 该方向的范围
0°/ 360° > 338°或<22°
东北 45° 22°至68°
东方的 90° 68°至113°
东南部 135° 113°至158°
180° 158°至203°
西南 225° 203°至248°
西 170° 248°至293°
西北 315° 293°至338°

该程序的最后一部分是设置必须更新结果的速度。我创建了500毫秒的延迟,然后关闭了所有LED,以从void循环中的第一个开始重新启动。但是,如果您需要更快的更新,则可以进一步减少延迟。

  delay(500); 的LED每//更新位置ALF秒
//关闭所有的LED
    for(int thisPin = 0; thisPin <= led_count; thisPin ++){ 
     digitalWrite(ledPins[thisPin],LOW); 
  }

测试数字指南针

因为我们已经使用了Arduino pro mini,所以我们需要一个FTDI板之类的外部编程器来上载程序。上载程序后,您应该注意到板上的一个LED发光,该LED发光的方向将是NORTH方向
在这里插入图片描述

然后,您可以通过旋转面板来进行操作,并检查LED是否仍指向北方向。之后,您可以随时使用9V电池为设置供电,并检查您所面对的方向。可以在下面的视频中找到数字指南针的完整功能。您可能会注意到,如果靠近电路板的地方有一块重金属,或者即使沿Z轴旋转电路板,这些值也会出错。有一些方法可以解决此问题,这是另一篇教程。

希望您喜欢本教程并从中学到了一些有用的东西。如果是,则将积分转给赞助此职位的PCBGOGO,因此请尝试一下您的PCB。像往常一样,将您的想法发表在下面的评论部分。

代码

/*
 * Program for Arduino Digital Compass using QMC5883
 * Project by: Aswinth Raj
 * Dated: 1-11-2018
 * Website: www.circuitdigest.com
 * Lib. from https://github.com/keepworking/Mecha_QMC5883L
 * WARNING: This code works only for QMC5883 Sensor which is commonly being sold as HMC5883 read article to find the actual name of the sensor you have.
 */

#include <Wire.h> //Wire Librarey for I2C communication 
#include <MechaQMC5883.h> //QMC5883 Librarey is added since mine is QMC583 and not HMC5883

MechaQMC5883 qmc; //Create an object name for the snsor, I have named it as qmc

int ledPins[] = {
    2,3,4,5,6,7,8,9}; //Array of output pin to which the LED is connected to
char led_count = 7; //Total number of LED pins 

  
void setup() {
    
  Wire.begin(); //Begin I2C communication 
  Serial.begin(9600); //Begin Serial Communication 
  qmc.init(); //Initialise the QMC5883 Sensor 

  for (int thisPin=0; thisPin <= led_count; thisPin++){
     //Navigate through all the pins in array 
    pinMode(ledPins[thisPin],OUTPUT); //Declare them as output 
  }

}

void loop() {
     //Infinite Loop
  int x,y,z;
  qmc.read(&x,&y,&z); //Get the values of X,Y and Z from sensor 
  
  int heading=atan2(x, y)/0.0174532925; //Calculate the degree using X and Y parameters with this formulae 

 //Convert result into 0 to 360
  if(heading < 0) 
  heading+=360;
  heading = 360-heading;
  
  Serial.println(heading); //Print the value of heading in degree for debugging 

//Based on the value of heading print the result for debugging and glow the respective LED.
  if (heading > 338 || heading < 22)
  {
    
    Serial.println("NORTH");
    digitalWrite(ledPins[0],HIGH);
  }
  if (heading > 22 && heading < 68)
  {
    
    Serial.println("NORTH-EAST");
    digitalWrite(ledPins[7],HIGH);
  }
  if (heading > 68 && heading < 113)
  {
    
    Serial.println("EAST");
    digitalWrite(ledPins[6],HIGH);
  }
  if (heading > 113 && heading < 158)
  {
    
    Serial.println("SOUTH-EAST");
    digitalWrite(ledPins[5],HIGH);
  }
  if (heading > 158 && heading < 203)
  {
    
    Serial.println("SOUTH");
    digitalWrite(ledPins[4],HIGH);
  }
  if (heading > 203 && heading < 248)
  {
    
    Serial.println("SOTUH-WEST");
    digitalWrite(ledPins[3],HIGH);
  }
  if (heading > 248 && heading < 293)
  {
    
    Serial.println("WEST");
    digitalWrite(ledPins[2],HIGH);
  }
  if (heading > 293 && heading < 338)
  {
    
    Serial.println("NORTH-WEST");
    digitalWrite(ledPins[1],HIGH);
  }

  delay(500); // update position of LED for every alf seconds 
//Turn off the all the LED 
    for (int thisPin=0; thisPin <= led_count; thisPin++){
    
     digitalWrite(ledPins[thisPin],LOW);
  }
}
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/acktomas/article/details/115950022

智能推荐

oracle 12c 集群安装后的检查_12c查看crs状态-程序员宅基地

文章浏览阅读1.6k次。安装配置gi、安装数据库软件、dbca建库见下:http://blog.csdn.net/kadwf123/article/details/784299611、检查集群节点及状态:[root@rac2 ~]# olsnodes -srac1 Activerac2 Activerac3 Activerac4 Active[root@rac2 ~]_12c查看crs状态

解决jupyter notebook无法找到虚拟环境的问题_jupyter没有pytorch环境-程序员宅基地

文章浏览阅读1.3w次,点赞45次,收藏99次。我个人用的是anaconda3的一个python集成环境,自带jupyter notebook,但在我打开jupyter notebook界面后,却找不到对应的虚拟环境,原来是jupyter notebook只是通用于下载anaconda时自带的环境,其他环境要想使用必须手动下载一些库:1.首先进入到自己创建的虚拟环境(pytorch是虚拟环境的名字)activate pytorch2.在该环境下下载这个库conda install ipykernelconda install nb__jupyter没有pytorch环境

国内安装scoop的保姆教程_scoop-cn-程序员宅基地

文章浏览阅读5.2k次,点赞19次,收藏28次。选择scoop纯属意外,也是无奈,因为电脑用户被锁了管理员权限,所有exe安装程序都无法安装,只可以用绿色软件,最后被我发现scoop,省去了到处下载XXX绿色版的烦恼,当然scoop里需要管理员权限的软件也跟我无缘了(譬如everything)。推荐添加dorado这个bucket镜像,里面很多中文软件,但是部分国外的软件下载地址在github,可能无法下载。以上两个是官方bucket的国内镜像,所有软件建议优先从这里下载。上面可以看到很多bucket以及软件数。如果官网登陆不了可以试一下以下方式。_scoop-cn

Element ui colorpicker在Vue中的使用_vue el-color-picker-程序员宅基地

文章浏览阅读4.5k次,点赞2次,收藏3次。首先要有一个color-picker组件 <el-color-picker v-model="headcolor"></el-color-picker>在data里面data() { return {headcolor: ’ #278add ’ //这里可以选择一个默认的颜色} }然后在你想要改变颜色的地方用v-bind绑定就好了,例如:这里的:sty..._vue el-color-picker

迅为iTOP-4412精英版之烧写内核移植后的镜像_exynos 4412 刷机-程序员宅基地

文章浏览阅读640次。基于芯片日益增长的问题,所以内核开发者们引入了新的方法,就是在内核中只保留函数,而数据则不包含,由用户(应用程序员)自己把数据按照规定的格式编写,并放在约定的地方,为了不占用过多的内存,还要求数据以根精简的方式编写。boot启动时,传参给内核,告诉内核设备树文件和kernel的位置,内核启动时根据地址去找到设备树文件,再利用专用的编译器去反编译dtb文件,将dtb还原成数据结构,以供驱动的函数去调用。firmware是三星的一个固件的设备信息,因为找不到固件,所以内核启动不成功。_exynos 4412 刷机

Linux系统配置jdk_linux配置jdk-程序员宅基地

文章浏览阅读2w次,点赞24次,收藏42次。Linux系统配置jdkLinux学习教程,Linux入门教程(超详细)_linux配置jdk

随便推点

matlab(4):特殊符号的输入_matlab微米怎么输入-程序员宅基地

文章浏览阅读3.3k次,点赞5次,收藏19次。xlabel('\delta');ylabel('AUC');具体符号的对照表参照下图:_matlab微米怎么输入

C语言程序设计-文件(打开与关闭、顺序、二进制读写)-程序员宅基地

文章浏览阅读119次。顺序读写指的是按照文件中数据的顺序进行读取或写入。对于文本文件,可以使用fgets、fputs、fscanf、fprintf等函数进行顺序读写。在C语言中,对文件的操作通常涉及文件的打开、读写以及关闭。文件的打开使用fopen函数,而关闭则使用fclose函数。在C语言中,可以使用fread和fwrite函数进行二进制读写。‍ Biaoge 于2024-03-09 23:51发布 阅读量:7 ️文章类型:【 C语言程序设计 】在C语言中,用于打开文件的函数是____,用于关闭文件的函数是____。

Touchdesigner自学笔记之三_touchdesigner怎么让一个模型跟着鼠标移动-程序员宅基地

文章浏览阅读3.4k次,点赞2次,收藏13次。跟随鼠标移动的粒子以grid(SOP)为partical(SOP)的资源模板,调整后连接【Geo组合+point spirit(MAT)】,在连接【feedback组合】适当调整。影响粒子动态的节点【metaball(SOP)+force(SOP)】添加mouse in(CHOP)鼠标位置到metaball的坐标,实现鼠标影响。..._touchdesigner怎么让一个模型跟着鼠标移动

【附源码】基于java的校园停车场管理系统的设计与实现61m0e9计算机毕设SSM_基于java技术的停车场管理系统实现与设计-程序员宅基地

文章浏览阅读178次。项目运行环境配置:Jdk1.8 + Tomcat7.0 + Mysql + HBuilderX(Webstorm也行)+ Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。项目技术:Springboot + mybatis + Maven +mysql5.7或8.0+html+css+js等等组成,B/S模式 + Maven管理等等。环境需要1.运行环境:最好是java jdk 1.8,我们在这个平台上运行的。其他版本理论上也可以。_基于java技术的停车场管理系统实现与设计

Android系统播放器MediaPlayer源码分析_android多媒体播放源码分析 时序图-程序员宅基地

文章浏览阅读3.5k次。前言对于MediaPlayer播放器的源码分析内容相对来说比较多,会从Java-&amp;amp;gt;Jni-&amp;amp;gt;C/C++慢慢分析,后面会慢慢更新。另外,博客只作为自己学习记录的一种方式,对于其他的不过多的评论。MediaPlayerDemopublic class MainActivity extends AppCompatActivity implements SurfaceHolder.Cal..._android多媒体播放源码分析 时序图

java 数据结构与算法 ——快速排序法-程序员宅基地

文章浏览阅读2.4k次,点赞41次,收藏13次。java 数据结构与算法 ——快速排序法_快速排序法