久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 16911|回復: 10
打印 上一主題 下一主題
收起左側

Arduino學習3-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 GNDArduino 3.3V -> HMC5883L VCCArduino A4 (SDA) -> HMC5883L SDAArduino A5 (SCL) -> HMC5883L SCL

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



程序編寫:下載HMC5883L庫文件。下載地址: HMC5883L.zip (5.55 KB, 下載次數: 100) 主要程序預覽:
  1. /*
  2. HMC5883L.cpp - Class file for the HMC5883L Triple Axis Magnetometer Arduino Library.
  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 .

  13. WARNING: THE HMC5883L IS NOT IDENTICAL TO THE HMC5883!

  14. */

  15. #include  
  16. #include "HMC5883L.h"

  17. HMC5883L::HMC5883L()
  18. {
  19.   m_Scale = 1;
  20. }

  21. MagnetometerRaw HMC5883L::ReadRawAxis()
  22. {
  23.   uint8_t* buffer = Read(DataRegisterBegin, 6);
  24.   MagnetometerRaw raw = MagnetometerRaw();
  25.   raw.XAxis = (buffer[0] << 8) | buffer[1];
  26.   raw.ZAxis = (buffer[2] << 8) | buffer[3];
  27.   raw.YAxis = (buffer[4] << 8) | buffer[5];
  28.   return raw;
  29. }

  30. MagnetometerScaled HMC5883L::ReadScaledAxis()
  31. {
  32.   MagnetometerRaw raw = ReadRawAxis();
  33.   MagnetometerScaled scaled = MagnetometerScaled();
  34.   scaled.XAxis = raw.XAxis * m_Scale;
  35.   scaled.ZAxis = raw.ZAxis * m_Scale;
  36.   scaled.YAxis = raw.YAxis * m_Scale;
  37.   return scaled;
  38. }

  39. int HMC5883L::SetScale(float gauss)
  40. {
  41.         uint8_t regValue = 0x00;
  42.         if(gauss == 0.88)
  43.         {
  44.                 regValue = 0x00;
  45.                 m_Scale = 0.73;
  46.         }
  47.         else if(gauss == 1.3)
  48.         {
  49.                 regValue = 0x01;
  50.                 m_Scale = 0.92;
  51.         }
  52.         else if(gauss == 1.9)
  53.         {
  54.                 regValue = 0x02;
  55.                 m_Scale = 1.22;
  56.         }
  57.         else if(gauss == 2.5)
  58.         {
  59.                 regValue = 0x03;
  60.                 m_Scale = 1.52;
  61.         }
  62.         else if(gauss == 4.0)
  63.         {
  64.                 regValue = 0x04;
  65.                 m_Scale = 2.27;
  66.         }
  67.         else if(gauss == 4.7)
  68.         {
  69.                 regValue = 0x05;
  70.                 m_Scale = 2.56;
  71.         }
  72.         else if(gauss == 5.6)
  73.         {
  74.                 regValue = 0x06;
  75.                 m_Scale = 3.03;
  76.         }
  77.         else if(gauss == 8.1)
  78.         {
  79.                 regValue = 0x07;
  80.                 m_Scale = 4.35;
  81.         }
  82.         else
  83.                 return ErrorCode_1_Num;
  84.         
  85.         // Setting is in the top 3 bits of the register.
  86.         regValue = regValue << 5;
  87.         Write(ConfigurationRegisterB, regValue);
  88. }

  89. int HMC5883L::SetMeasurementMode(uint8_t mode)
  90. {
  91.         Write(ModeRegister, mode);
  92. }

  93. void HMC5883L::Write(int address, int data)
  94. {
  95.   Wire.beginTransmission(HMC5883L_Address);
  96.   Wire.send(address);
  97.   Wire.send(data);
  98.   Wire.endTransmission();
  99. }

  100. uint8_t* HMC5883L::Read(int address, int length)
  101. {
  102.   Wire.beginTransmission(HMC5883L_Address);
  103.   Wire.send(address);
  104.   Wire.endTransmission();
  105.   
  106.   Wire.beginTransmission(HMC5883L_Address);
  107.   Wire.requestFrom(HMC5883L_Address, length);

  108.   uint8_t buffer[length];
  109.   if(Wire.available() == length)
  110.   {
  111.           for(uint8_t i = 0; i < length; i++)
  112.           {
  113.                   buffer[i] = Wire.receive();
  114.           }
  115.   }
  116.   Wire.endTransmission();

  117.   return buffer;
  118. }

  119. char* HMC5883L::GetErrorText(int errorCode)
  120. {
  121.         if(ErrorCode_1_Num == 1)
  122.                 return ErrorCode_1;
  123.         
  124.         return "Error not defined.";
  125. }
復制代碼


解壓HMC5883L庫文件到arduino文件夾:arduino-0022libraries下面。編寫以下程序,下載下面測試程序到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平面角度):


分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏2 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:114115 發表于 2016-4-14 02:54 | 只看該作者
最近實在太忙,就先單獨把我的八字校準程序貼上來。
其實很簡單,我沒去管Z軸,如果想要更高的精度,需要加一個加速度傳感器,我剛好沒有。

我的整個校準分2個子函數:calibRead() 和 calibration()

參照官方HMC5883L的程序先把該定義的變量定義好。
  1.     HMC5883L digicomp;
  2.      
  3.     float X_max = 0.0;  //X軸最大讀數
  4.     float X_min = 0.0;  //X軸最小讀數
  5.      
  6.     float Y_max = 0.0;  //Y軸最大讀數
  7.     float Y_min = 0.0;  //Y軸最小讀數
  8.      
  9.     float X_offset = 0.0;  //X軸偏移
  10.     float Y_offset = 0.0;  //Y軸偏移
  11.      
  12.     void calibRead() //指南針讀數
  13.     {
  14.             MagnetometerScaled scaled2 = digicomp.ReadScaledAxis();
  15.      
  16.             if (  (abs(scaled2.XAxis) < 500) && (abs(scaled2.YAxis) < 500) && (abs(scaled2.ZAxis) < 500)) //這行對于我很重要,能過濾掉很多干擾,增加校準的精度。
  17.             {  //下面幾行就是讀取到每個軸的最大值和最小值,然后算出相應的偏移量
  18.                 if(scaled2.XAxis > X_max) {X_max = scaled2.XAxis;}
  19.                 if(scaled2.YAxis > Y_max) {Y_max = scaled2.YAxis;}
  20.      
  21.                 if(scaled2.XAxis < X_min) {X_min = scaled2.XAxis;}
  22.                 if(scaled2.YAxis < Y_min) {Y_min = scaled2.YAxis;}
  23.      
  24.                 X_offset = (X_max + X_min) / 2.0;
  25.                 Y_offset = (Y_max + Y_min) / 2.0;
  26.             }
  27.     }
  28.      
  29.     void calibration()
  30.     {
  31.             int i = 0;
  32.             digitalWrite(motor1EnPin, 0);  // 定義轉彎方向,對于我的小車來說是左轉,逆時針方向
  33.             digitalWrite(motor2EnPin, 1);
  34.      
  35.             analogWrite(motor1, 80);  // 啟動馬達開始轉動
  36.             analogWrite(motor2, 80);
  37.      
  38.             while(i < 1000)  // 逆時針方向循環讀取XY軸每個方向的值,然后算出相應的偏移量
  39.             {  calibRead();
  40.                 delay(10);
  41.                 i++;
  42.             }
  43.      
  44.             i = 0;
  45.             digitalWrite(motor1EnPin, 1);  // 右轉小車,順時針方向
  46.             digitalWrite(motor2EnPin, 0);
  47.      
  48.             while(i < 1000)  // 再順時針方向方向旋轉測算偏移量
  49.             {  calibRead();
  50.                 delay(10);
  51.                 i++;
  52.             }
  53.      
  54.             analogWrite(motor1, 0);  // 停止小車,校準完成
  55.             analogWrite(motor2, 0);
  56.     }
  57.      
  58.     float readCompass()  //得到偏移了就可以讀數了
  59.     {
  60.             MagnetometerScaled scaled = digicomp.ReadScaledAxis();
  61.      
  62.             float heading = atan2(scaled.YAxis - Y_offset, scaled.XAxis - X_offset);  // 讀數的時候直接減掉偏移量就可以了
  63.      
  64.             //float declinationAngle = 36.36/1000.0;  [這幾行是考慮磁偏角的,除非真的是想
  65.             //heading = heading + declinationAngle;    找地理北極,不然對方向判斷用處不大]
  66.      
  67.             if(heading < 0)  heading += 2*PI;
  68.             if(heading > 2*PI)  heading -= 2*PI;
  69.      
  70.             float headingDegrees = heading * 180/M_PI;
  71.      
  72.             return headingDegrees;
  73.     }
復制代碼

嚴格來說這個傳感器讀出來的僅僅是三軸方向磁場強度而已,角度是算出來的。另外他對磁場感應很靈敏,周圍有金屬就會有干擾,拿塊金屬在他周圍轉轉就能看到讀數很大的變化,所以校準還是很有必要的。

手機的話因為畫8字能很快測得XY的偏移,所以方法就叫8字校準。小車的話因為可以旋轉,就沒必要真的去走8字,直接轉圈就可以了。這是我的理解。
回復

使用道具 舉報

板凳
ID:114115 發表于 2016-4-14 02:54 | 只看該作者
上傳一個HMC5883L庫文件,放在C:\Program Files (x86)\Arduino\libraries就可運行,ARDUINO 1.0.6版本的三軸傳感器。代碼詳見1樓。

    HMC5883L新頭文件: HMC5883L.rar (5.14 KB, 下載次數: 41)
回復

使用道具 舉報

地板
ID:114115 發表于 2016-4-14 02:55 | 只看該作者
焊接還是很簡單的,個人玩買個可調溫和恒溫的電烙鐵,最好60W的,升溫快,焊接前先將烙鐵頭附錫(其實一般新電烙鐵都需要先附錫,每次用完也要附錫防氧化),面板焊接點注意刷好助焊劑(可以用松香+酒精自己調,酒精要純度高的工業酒精大概酒精和松香1:0.2就差不多了,然后刷到要焊接的引腳和PCB板上),最后直接焊錫絲點烙鐵頭刷引腳(不要擔心連線,先讓焊錫全部下到引腳上,最后拿烙鐵刷一邊,焊錫會自己焊接到點,最好讓板子稍微傾斜,自上而下刷,這樣多余的錫會流到最下邊,然后拿烙鐵點掉就好了),最后用酒精棉擦洗焊點(將多余助焊劑洗掉),檢查焊點是否有連接,如果不確定用鑷子刮一刮就好了。(烙鐵使用要快點快提,這樣錫會自己成非常漂亮的形狀,不要長時間點焊點)

PCB板是不會附著焊錫的,所以不用擔心焊不好,其實很簡單,關鍵烙鐵要好,個人用我覺得黃花907調溫恒溫烙鐵就好,淘寶上很便宜,反正我自己用的就很不錯。。。。

最后,烙鐵頭要多買幾個不同樣式的,以應對不同焊點。。

------------------------

另,最近發現一個HMC5883的問題,一并記這兒:最近買了幾片HMC5883L模塊,結果被坑了,賣家沒說不能用在5V系統,只說能5V供電,以為在MEGA2560上能用,結果讀數據有問題,一開始是讀出來不更新,每次復位更新一次數據,后來發現上拉電阻不是裝的PCB上印的4.7K,裝的是10K,換成4.7K后,可以連續讀數據,但讀一斷時間后就會死機,以為程序有問題,查來查去,后來發現以前買的模塊能正常讀,仔細比較兩個模塊,發現新買的模塊沒有電平轉換電路,以HMC5883L的IIc的1.8V電平直接接5V系統,不死才怪,所以5V系統買這個模塊一定要買GY-271型號,有兩個小6腳芯片的,一個是LDO,一個是雙MOS做電平轉換,只有一個LDO的模塊只能用在3.3V或1.8V系統。
回復

使用道具 舉報

5#
ID:148138 發表于 2016-11-15 21:32 | 只看該作者
5893也出來了
回復

使用道具 舉報

6#
ID:165193 發表于 2017-2-18 00:07 | 只看該作者
回復有黑幣嗎
回復

使用道具 舉報

7#
ID:24730 發表于 2017-3-2 16:50 | 只看該作者
51黑有你更精彩
回復

使用道具 舉報

8#
ID:1 發表于 2017-3-2 17:06 | 只看該作者

回復是沒有的 只能通過發布文件 管理員審核通過后 才會發放
回復

使用道具 舉報

9#
ID:230088 發表于 2017-8-31 16:24 | 只看該作者
回復有黑幣么?
回復

使用道具 舉報

10#
ID:326549 發表于 2019-5-30 15:51 | 只看該作者
fatal error: ../Wire/Wire.h: No such file or directory #include "../Wire/Wir
請問這是怎么回事
回復

使用道具 舉報

11#
ID:514567 發表于 2019-6-7 12:00 | 只看該作者
很厲害
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 色资源在线观看 | 亚洲 欧美 激情 另类 校园 | 在线一区 | 美女在线一区二区 | 久草视频在线播放 | 日韩精品一区二区三区中文字幕 | 国产精品国产精品国产专区不卡 | 亚洲最色网站 | 黄色毛片免费 | 国产成人麻豆免费观看 | 久久久精品一区 | 亚洲综合在线播放 | 另类 综合 日韩 欧美 亚洲 | 国产精品夜夜夜一区二区三区尤 | 日本三级网站在线观看 | 亚洲在线免费 | 91欧美精品 | 欧美日韩一本 | 日韩精品一区在线 | 99热在线免费 | 女女爱爱视频 | 一道本视频 | 中文字幕国产在线 | 欧洲一区二区三区 | 亚洲精品二区 | 国产一级视频在线播放 | xxxcom在线观看| 伊人网站在线 | av黄色在线 | 欧美久久久久久 | 羞羞视频在线观看 | 久久蜜桃av一区二区天堂 | 国产天天操 | 国产精品一区二区在线播放 | 欧美久久免费观看 | 国产视频久久久 | 亚洲午夜视频 | 午夜三级在线观看 | 日日摸夜夜爽人人添av | 国产欧美在线 | 成人性视频在线 |