极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 107187|回复: 118

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

  [复制链接]
发表于 2011-9-10 20:49:57 | 显示全部楼层 |阅读模式
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
1.jpg


连接方法:
只要连接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)



    程序编写:

    #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平面角度):
    3.jpg

    HMC5883L.zip (5.55 KB, 下载次数: 2956)
  • 评分

    参与人数 1 +3 收起 理由
    弘毅 + 3 赞一个!

    查看全部评分

    回复

    使用道具 举报

    发表于 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'
    回复 支持 2 反对 0

    使用道具 举报

    发表于 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了

    点评

    楼上正解  发表于 2013-9-4 01:13
    是的,其实就是将负数和超过360度的,转换回0~360°而已  发表于 2011-10-20 10:25
    回复 支持 反对

    使用道具 举报

    发表于 2011-10-20 15:32:23 | 显示全部楼层
    本帖最后由 ck59505 于 2011-10-20 15:43 编辑
    ck59505 发表于 2011-10-19 22:08
    LZ好啊,我想问问如果我用的是HMC5843 ,应该还是一样的吧,就稍微改改就好了。。。

    还有就是   if(xHea ...


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

    使用道具 举报

    发表于 2012-3-3 13:11:06 | 显示全部楼层
    ck59505 发表于 2011-10-20 15:32
    哦,谢谢啦,还有我弱弱的问问。。。PI表示的是Arduino从传感器的来的数据吗,随着物体的移动,传来的P ...

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

    使用道具 举报

    发表于 2012-3-7 11:54:49 | 显示全部楼层
    好东西,但是不知道这些数字是怎么分析的呢?
    回复 支持 反对

    使用道具 举报

    发表于 2012-3-7 16:15:48 | 显示全部楼层
    10530-01c.jpg
    试问一下上面的模块和你使用的模块有什么区别吗?因为上面只有4个接口,而且没有针脚,要自己焊接挺麻烦的。
    回复 支持 反对

    使用道具 举报

    发表于 2012-3-7 17:50:46 | 显示全部楼层
    树·水·风 发表于 2012-3-7 16:15
    试问一下上面的模块和你使用的模块有什么区别吗?因为上面只有4个接口,而且没有针脚,要自己焊接挺麻烦的 ...


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

    使用道具 举报

    发表于 2012-3-7 19:08:18 | 显示全部楼层
    弘毅 发表于 2012-3-7 17:50
    这种模块,只能3.3V供电,没有上拉电阻,所以连接arduino板子,上拉电阻需要手工接。其他没区别

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

    使用道具 举报

    发表于 2012-4-28 11:36:56 | 显示全部楼层
    本帖最后由 Randy 于 2012-4-28 11:49 编辑

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

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

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

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

    13. */

    14. // Reference the I2C Library
    15. #include <Wire.h>
    16. // Reference the HMC5883L Compass Library
    17. #include <HMC5883L.h>

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

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

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

    29.   Serial.println("Constructing new HMC5883L");
    30.   compass = HMC5883L(); // Construct a new HMC5883 compass.
    31.    
    32.   Serial.println("Setting scale to +/- 1.3 Ga");
    33.   error = compass.SetScale(1.3); // Set the scale of the compass.
    34.   if(error != 0) // If there is an error, print it out.
    35.     Serial.println(compass.GetErrorText(error));
    36.   
    37.   Serial.println("Setting measurement mode to continous.");
    38.   error = compass.SetMeasurementMode(Measurement_Continuous); // Set the measurement mode to Continuous
    39.   if(error != 0) // If there is an error, print it out.
    40.     Serial.println(compass.GetErrorText(error));
    41. }

    42. // Our main program loop.
    43. void loop()
    44. {
    45.   // Retrive the raw values from the compass (not scaled).
    46.   MagnetometerRaw raw = compass.ReadRawAxis();
    47.   // Retrived the scaled values from the compass (scaled to the configured scale).
    48.   MagnetometerScaled scaled = compass.ReadScaledAxis();
    49.   
    50.   // Values are accessed like so:
    51.   int MilliGauss_OnThe_XAxis = scaled.XAxis;// (or YAxis, or ZAxis)

    52.   // Calculate heading when the magnetometer is level, then correct for signs of axis.
    53.   float heading = atan2(scaled.YAxis, scaled.XAxis);
    54.   
    55.   // Once you have your heading, you must then add your 'Declination Angle', which is the 'Error' of the magnetic field in your location.
    56.   // Find yours here: http://www.magnetic-declination.com/
    57.   // Mine is: 2&#65533; 37' W, which is 2.617 Degrees, or (which we need) 0.0456752665 radians, I will use 0.0457
    58.   // If you cannot find your Declination, comment out these two lines, your compass will be slightly off.
    59.   float declinationAngle = 0.0457;
    60.   heading += declinationAngle;
    61.   
    62.   // Correct for when signs are reversed.
    63.   if(heading < 0)
    64.     heading += 2*PI;
    65.    
    66.   // Check for wrap due to addition of declination.
    67.   if(heading > 2*PI)
    68.     heading -= 2*PI;
    69.    
    70.   // Convert radians to degrees for readability.
    71.   float headingDegrees = heading * 180/M_PI;

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

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

    80. // Output the data down the serial port.
    81. void Output(MagnetometerRaw raw, MagnetometerScaled scaled, float heading, float headingDegrees)
    82. {
    83.    Serial.print("Raw:\t");
    84.    Serial.print(raw.XAxis);
    85.    Serial.print("   ");   
    86.    Serial.print(raw.YAxis);
    87.    Serial.print("   ");   
    88.    Serial.print(raw.ZAxis);
    89.    Serial.print("   \tScaled:\t");
    90.    
    91.    Serial.print(scaled.XAxis);
    92.    Serial.print("   ");   
    93.    Serial.print(scaled.YAxis);
    94.    Serial.print("   ");   
    95.    Serial.print(scaled.ZAxis);

    96.    Serial.print("   \tHeading:\t");
    97.    Serial.print(heading);
    98.    Serial.print(" Radians   \t");
    99.    Serial.print(headingDegrees);
    100.    Serial.println(" Degrees   \t");
    101. }
    复制代码
    结果是这样的,问了HEAVEN的意思!

    HMC5883L数字副本.jpg


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


    14.jpg

    点评

    这个做法太简单了,没有考虑磁场传感器的零偏,以及姿态的影响。只能说,能指示出东南西北,要说指向精度就谈不上了。  发表于 2015-1-28 15:33

    评分

    参与人数 1 +30 收起 理由
    Ansifa + 30 解释不错,哈哈

    查看全部评分

    回复 支持 反对

    使用道具 举报

    发表于 2012-4-28 11:48:18 | 显示全部楼层
    树·水·风 发表于 2012-3-7 19:08
    哦,谢谢。我在淘宝上搜,有引脚的要贵很多,自己又没有焊接的经验,有点囧啊

    焊接这几个针非常的简单,慢慢来!
    回复 支持 反对

    使用道具 举报

    发表于 2012-6-1 16:59:40 | 显示全部楼层
    树·水·风 发表于 2012-3-7 19:08
    哦,谢谢。我在淘宝上搜,有引脚的要贵很多,自己又没有焊接的经验,有点囧啊

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

    使用道具 举报

    发表于 2012-6-1 17:15:09 | 显示全部楼层
    楼主的代码用了,很爽,呵呵
    纠结了3天了,就是为了测试新买的10轴模块的好坏
    之前用MWC代码测试之后唯独就是HMC5883L的读数不正常,经过这个库文件和楼主的代码,测试很好,呵呵
    回复 支持 反对

    使用道具 举报

    发表于 2012-6-1 17:16:15 | 显示全部楼层
    本帖最后由 darkorigin 于 2012-6-1 17:19 编辑
    弘毅 发表于 2012-3-7 17:50
    这种模块,只能3.3V供电,没有上拉电阻,所以连接arduino板子,上拉电阻需要手工接。其他没区别


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

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

    使用道具 举报

    发表于 2012-6-11 11:58:32 | 显示全部楼层
    darkorigin 发表于 2012-6-1 17:16
    arduino不是自带了3.3v的口么?VCC接上去可以不?

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

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

    使用道具 举报

    发表于 2012-6-16 16:06:29 | 显示全部楼层
    用HMC5883L读数结果不正常,误差很大。就是手动偏转90读的话,读数变化不是90度,有时候是120度,也有的时候是140度,非常诡异,大家有没有遇到过类似的情况?
    回复 支持 反对

    使用道具 举报

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

    本版积分规则

    Archiver|联系我们|极客工坊 ( 浙ICP备09023225号 )

    GMT+8, 2020-1-21 00:04 , Processed in 0.056592 second(s), 30 queries .

    Powered by Discuz! X3.4 Licensed

    © 2001-2017 Comsenz Inc.

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