Ansifa 发表于 2011-9-10 20:49:57

Arduino学习笔记A3 - Arduino连接HMC5883L三轴电子罗盘传感器

Arduino连接HMC5883L三轴电子罗盘传感器
用途:测量地磁方向,测量物体静止时候的方向,测量传感器周围磁力线的方向。注意,测量地磁时候容易受到周围磁场影响,

主芯片HMC5883三轴磁阻传感器特点(抄自网上):
1,数字量输出:I2C数字量输出接口,设计使用非常方便。
2,尺寸小: 3x3x0.9mm LCC封装,适合大规模量产使用。
3,精度高:1-2度,内置12位A/D,OFFSET, SET/RESET 电路,不会出现磁饱和现象,不会有累加误差。
4,支持自动校准程序,简化使用步骤,终端产品使用非常方便。
5,内置自测试电路,方便量产测试,无需增加额外昂贵的测试设备。
6,功耗低:供电电压1.8V, 功耗睡眠模式-2.5uA 测量模式-0.6mA



连接方法:
只要连接VCC,GND,SDA,SCL四条线。[*]Arduino GND -> HMC5883L GND[*]Arduino 3.3V -> HMC5883L VCC[*]Arduino A4 (SDA) -> HMC5883L SDA[*]Arduino A5 (SCL) -> HMC5883L SCL

(注意,接线是A4,A5,不是D4,D5)



程序编写:[*]下载HMC5883L库文件。下载地址:http://soft2.wmzhe.com/download/AnsifaArduino/HMC5883L.zip[*]解压HMC5883L库文件到arduino文件夹:arduino-0022\libraries下面。[*]编写以下程序,下载下面测试程序到arduino:
#include <Wire.h>
#include <HMC5883L.h>
HMC5883L compass;
void setup()
{
Serial.begin(9600);
Wire.begin();
compass = HMC5883L();
compass.SetScale(1.3);
compass.SetMeasurementMode(Measurement_Continuous);
}
void loop()
{
MagnetometerRaw raw = compass.ReadRawAxis();
MagnetometerScaled scaled = compass.ReadScaledAxis();
float xHeading = atan2(scaled.YAxis, scaled.XAxis);
float yHeading = atan2(scaled.ZAxis, scaled.XAxis);
float zHeading = atan2(scaled.ZAxis, scaled.YAxis);
if(xHeading < 0) xHeading += 2*PI;
if(xHeading > 2*PI) xHeading -= 2*PI;
if(yHeading < 0) yHeading += 2*PI;
if(yHeading > 2*PI) yHeading -= 2*PI;
if(zHeading < 0) zHeading += 2*PI;
if(zHeading > 2*PI) zHeading -= 2*PI;
float xDegrees = xHeading * 180/M_PI;
float yDegrees = yHeading * 180/M_PI;
float zDegrees = zHeading * 180/M_PI;
Serial.print(xDegrees);
Serial.print(",");
Serial.print(yDegrees);
Serial.print(",");
Serial.print(zDegrees);
Serial.println(";");
delay(100);
}


打开Arduino串口监视器即可看到结果(X平面角度,Y平面角度,Z平面角度):


dongxiaown 发表于 2014-1-11 10:47:37

我按照上面的做了,为什么还是出错啊,求大神解答:

F:\arduino\arduino-1.0-windows\arduino-1.0\libraries\HMC5883L\HMC5883L.cpp:23:23: error: WProgram.h: No such file or directory
F:\arduino\arduino-1.0-windows\arduino-1.0\libraries\HMC5883L\HMC5883L.cpp: In member function 'void HMC5883L::Write(int, int)':
F:\arduino\arduino-1.0-windows\arduino-1.0\libraries\HMC5883L\HMC5883L.cpp:110: error: 'class TwoWire' has no member named 'send'
F:\arduino\arduino-1.0-windows\arduino-1.0\libraries\HMC5883L\HMC5883L.cpp:111: error: 'class TwoWire' has no member named 'send'
F:\arduino\arduino-1.0-windows\arduino-1.0\libraries\HMC5883L\HMC5883L.cpp: In member function 'uint8_t* HMC5883L::Read(int, int)':
F:\arduino\arduino-1.0-windows\arduino-1.0\libraries\HMC5883L\HMC5883L.cpp:118: error: 'class TwoWire' has no member named 'send'
F:\arduino\arduino-1.0-windows\arduino-1.0\libraries\HMC5883L\HMC5883L.cpp:129: error: 'class TwoWire' has no member named 'receive'

ck59505 发表于 2011-10-19 22:08:03

LZ好啊,我想问问如果我用的是HMC5843 ,应该还是一样的吧,就稍微改改就好了。。。

还有就是   if(xHeading < 0) xHeading += 2*PI;
if(xHeading > 2*PI) xHeading -= 2*PI;
if(yHeading < 0) yHeading += 2*PI;
if(yHeading > 2*PI) yHeading -= 2*PI;
if(zHeading < 0) zHeading += 2*PI;
if(zHeading > 2*PI) zHeading -= 2*PI;
这一段是不是把,x,y,z局限于一定的范围呢。。。。新人,求指教。。。多些LZ了

ck59505 发表于 2011-10-20 15:32:23

本帖最后由 ck59505 于 2011-10-20 15:43 编辑

ck59505 发表于 2011-10-19 22:08 static/image/common/back.gif
LZ好啊,我想问问如果我用的是HMC5843 ,应该还是一样的吧,就稍微改改就好了。。。

还有就是   if(xHea ...

哦,谢谢啦,还有我弱弱的问问。。。PI表示的是Arduino从传感器的来的数据吗,随着物体的移动,传来的PI值就不相同
额。。还是说是 π。。。

黑马 发表于 2012-3-3 13:11:06

ck59505 发表于 2011-10-20 15:32 static/image/common/back.gif
哦,谢谢啦,还有我弱弱的问问。。。PI表示的是Arduino从传感器的来的数据吗,随着物体的移动,传来的P ...

PI是圆周率,其实这个库文件已经把能做的都做了,直接读就行,这一大坨代码无非是变变数据的格式

Randy 发表于 2012-3-7 11:54:49

好东西,但是不知道这些数字是怎么分析的呢?

树·水·风 发表于 2012-3-7 16:15:48


试问一下上面的模块和你使用的模块有什么区别吗?因为上面只有4个接口,而且没有针脚,要自己焊接挺麻烦的。

弘毅 发表于 2012-3-7 17:50:46

树·水·风 发表于 2012-3-7 16:15 static/image/common/back.gif
试问一下上面的模块和你使用的模块有什么区别吗?因为上面只有4个接口,而且没有针脚,要自己焊接挺麻烦的 ...

这种模块,只能3.3V供电,没有上拉电阻,所以连接arduino板子,上拉电阻需要手工接。其他没区别

树·水·风 发表于 2012-3-7 19:08:18

弘毅 发表于 2012-3-7 17:50 static/image/common/back.gif
这种模块,只能3.3V供电,没有上拉电阻,所以连接arduino板子,上拉电阻需要手工接。其他没区别

哦,谢谢。我在淘宝上搜,有引脚的要贵很多,自己又没有焊接的经验,有点囧啊

Randy 发表于 2012-4-28 11:36:56

本帖最后由 Randy 于 2012-4-28 11:49 编辑

最近在玩这个东西,刚刚测试了一下。我也来提供一下测出地磁场角度的程序!/*
HMC5883L_Example.pde - Example sketch for integration with an HMC5883L triple axis magnetomerwe.
Copyright (C) 2011 Love Electronics (loveelectronics.co.uk)

This program is free software: you can redistribute it and/or modify
it under the terms of the version 3 GNU General Public License as
published by the Free Software Foundation.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.If not, see <http://www.gnu.org/licenses/>.

*/

// Reference the I2C Library
#include <Wire.h>
// Reference the HMC5883L Compass Library
#include <HMC5883L.h>

// Store our compass as a variable.
HMC5883L compass;
// Record any errors that may occur in the compass.
int error = 0;

// Out setup routine, here we will configure the microcontroller and compass.
void setup()
{
// Initialize the serial port.
Serial.begin(9600);

Serial.println("Starting the I2C interface.");
Wire.begin(); // Start the I2C interface.

Serial.println("Constructing new HMC5883L");
compass = HMC5883L(); // Construct a new HMC5883 compass.
   
Serial.println("Setting scale to +/- 1.3 Ga");
error = compass.SetScale(1.3); // Set the scale of the compass.
if(error != 0) // If there is an error, print it out.
    Serial.println(compass.GetErrorText(error));

Serial.println("Setting measurement mode to continous.");
error = compass.SetMeasurementMode(Measurement_Continuous); // Set the measurement mode to Continuous
if(error != 0) // If there is an error, print it out.
    Serial.println(compass.GetErrorText(error));
}

// Our main program loop.
void loop()
{
// Retrive the raw values from the compass (not scaled).
MagnetometerRaw raw = compass.ReadRawAxis();
// Retrived the scaled values from the compass (scaled to the configured scale).
MagnetometerScaled scaled = compass.ReadScaledAxis();

// Values are accessed like so:
int MilliGauss_OnThe_XAxis = scaled.XAxis;// (or YAxis, or ZAxis)

// Calculate heading when the magnetometer is level, then correct for signs of axis.
float heading = atan2(scaled.YAxis, scaled.XAxis);

// Once you have your heading, you must then add your 'Declination Angle', which is the 'Error' of the magnetic field in your location.
// Find yours here: http://www.magnetic-declination.com/
// Mine is: 2� 37' W, which is 2.617 Degrees, or (which we need) 0.0456752665 radians, I will use 0.0457
// If you cannot find your Declination, comment out these two lines, your compass will be slightly off.
float declinationAngle = 0.0457;
heading += declinationAngle;

// Correct for when signs are reversed.
if(heading < 0)
    heading += 2*PI;
   
// Check for wrap due to addition of declination.
if(heading > 2*PI)
    heading -= 2*PI;
   
// Convert radians to degrees for readability.
float headingDegrees = heading * 180/M_PI;

// Output the data via the serial port.
Output(raw, scaled, heading, headingDegrees);

// Normally we would delay the application by 66ms to allow the loop
// to run at 15Hz (default bandwidth for the HMC5883L).
// However since we have a long serial out (104ms at 9600) we will let
// it run at its natural speed.
// delay(66);
}

// Output the data down the serial port.
void Output(MagnetometerRaw raw, MagnetometerScaled scaled, float heading, float headingDegrees)
{
   Serial.print("Raw:\t");
   Serial.print(raw.XAxis);
   Serial.print("   ");   
   Serial.print(raw.YAxis);
   Serial.print("   ");   
   Serial.print(raw.ZAxis);
   Serial.print("   \tScaled:\t");
   
   Serial.print(scaled.XAxis);
   Serial.print("   ");   
   Serial.print(scaled.YAxis);
   Serial.print("   ");   
   Serial.print(scaled.ZAxis);

   Serial.print("   \tHeading:\t");
   Serial.print(heading);
   Serial.print(" Radians   \t");
   Serial.print(headingDegrees);
   Serial.println(" Degrees   \t");
}结果是这样的,问了HEAVEN的意思!




下面我又测了另外一个的结果,感觉奇怪,楼主懂什么原因?


Randy 发表于 2012-4-28 11:48:18

树·水·风 发表于 2012-3-7 19:08 static/image/common/back.gif
哦,谢谢。我在淘宝上搜,有引脚的要贵很多,自己又没有焊接的经验,有点囧啊

焊接这几个针非常的简单,慢慢来!

darkorigin 发表于 2012-6-1 16:59:40

树·水·风 发表于 2012-3-7 19:08 static/image/common/back.gif
哦,谢谢。我在淘宝上搜,有引脚的要贵很多,自己又没有焊接的经验,有点囧啊

不用焊,找个粗的排针,插进去就好,一般过孔都会有镀层。排针插进去和焊接差不读牢固,电信号也非常好(毕竟镀金层的导电能力还是很不错的)

darkorigin 发表于 2012-6-1 17:15:09

楼主的代码用了,很爽,呵呵
纠结了3天了,就是为了测试新买的10轴模块的好坏
之前用MWC代码测试之后唯独就是HMC5883L的读数不正常,经过这个库文件和楼主的代码,测试很好,呵呵

darkorigin 发表于 2012-6-1 17:16:15

本帖最后由 darkorigin 于 2012-6-1 17:19 编辑

弘毅 发表于 2012-3-7 17:50 static/image/common/back.gif
这种模块,只能3.3V供电,没有上拉电阻,所以连接arduino板子,上拉电阻需要手工接。其他没区别

arduino不是自带了3.3v的口么?VCC接上去可以不?

另外, 感谢鸟版,感谢管理员弘毅大哥,感谢黑马版主,嘿嘿,最近讨教的东西太多了,你们的代码我也是一遍接一遍的“剽窃”。。。慢慢消化吧,呵呵,感谢能从你们这里学到东西嘿嘿!

Randy 发表于 2012-6-11 11:58:32

darkorigin 发表于 2012-6-1 17:16 static/image/common/back.gif
arduino不是自带了3.3v的口么?VCC接上去可以不?

另外, 感谢鸟版,感谢管理员弘毅大哥,感谢黑马版 ...

可以的,arduino板子上的3V3就是一好NCP1117转换出来所得的电压!可以直接使用!

cosailer 发表于 2012-6-16 16:06:29

用HMC5883L读数结果不正常,误差很大。就是手动偏转90读的话,读数变化不是90度,有时候是120度,也有的时候是140度,非常诡异,大家有没有遇到过类似的情况?
页: [1] 2 3 4 5 6 7 8
查看完整版本: Arduino学习笔记A3 - Arduino连接HMC5883L三轴电子罗盘传感器