ホーム > カテゴリ > ロボット・電子工作・マイコン >

3軸地磁気センサー(HMC5883L)の使い方 [Arduino]

XYZの3軸による「デジタルコンパス」モジュールの使い方です。

今回のスケッチでは簡易的な8方位「北、東、南、西、北東、東南、南西、北西」をシリアルモニターへ表示します。

使用部品・材料

総額で約1,170円です。(Arduino本体の値段を除く)

部品/材料値段備考
ブレッドボード¥270秋月電子の通販コード(P-00315)
HMC5883L使用 デジタルコンパスモジュール 3軸地磁気センサ DIP化キット¥600秋月電子の通販コード(K-09705)
I2Cバス用双方向電圧レベル変換モジュール(FXMA2102)¥200秋月電子の通販コード(M-05825)
方位磁石(コンパス)¥100100円ショップ

私は100円ショップの「方位磁石」でキャリブレーション(位置調整)をしましたので、高価な方位磁石がある方はそちらに合わせると良いと思います。

配線図

HMC5883Lの裏面にある「JP1」はハンダを盛って結線します。結線する事でSCL/SDAが2.2kΩでプルアップされます。

次は公式の「使い方説明書」より引用(AE_HMC5883L_DEMO.zip)

上記はHMC5883Lモジュールの基板(表)に表示されているシンボルの拡大図です。ここに表示されている「X軸の矢印方向が方位」となります。

スケッチ(プログラム)

シリアルモニターに「方位」及び「3軸座標/角度データ」を表示します。

#include <Wire.h>

// デバイスアドレス(スレーブ)
uint8_t DEVICE_ADDRESS = 0x1E;  

// キャリブレーション用(調整用)
// ※「地域」及び「コンパスの性能」によって異なるので適宜、変更して下さい。
float N = 325; // 北(North)
float E = 139; // 東(East)
float S = 192; // 南(South)
float W = 252; // 西(West)  
float ambiguous = 15; // 誤差±15度

// 角度の範囲を0-360度にする
float range360(float value){
  if(value >= 360){ return  value - 360;  }    
  if(value < 0)   { return  360 + value;  }
  return value;
}

void setup() {

  Serial.begin(9600); 
  
  // マスタとしてI2Cバスに接続する
  Wire.begin();       
 
  // Mode Register(測定モード) 
  Wire.beginTransmission(DEVICE_ADDRESS);  
    // Mode Registerのアドレス    
    Wire.write(0x02);
    // 測定モードを連続測定モードにする
    // 00 連続測定モード
    // 01 単位測定モード(デフォルト)
    //    ※1度だけ測定後、アイドルモードとなる
    // 10,11 アイドルモード
    Wire.write(0x00);  
  Wire.endTransmission();
}
 
void loop() {
    
  // XYZレジスタ用のテーブル(6byte)
  uint8_t RegTbl[6];  
   
  // 6byteのデータを取得する
  for (int i=0; i< 6; i++){
    // 各XZYの先頭アドレスに移動する
    Wire.beginTransmission(DEVICE_ADDRESS);
      Wire.write(0x03 + i);
    Wire.endTransmission();
    
    // デバイスへ1byteのレジスタデータを要求する
    Wire.requestFrom(DEVICE_ADDRESS, 1);
      
    while (Wire.available() == 0 ){}
    RegTbl[i] = Wire.read();
  }

  // データを各XYZの値に変換する
  int16_t x = (((int16_t)RegTbl[0]) << 8) | RegTbl[1];
  int16_t z = (((int16_t)RegTbl[2]) << 8) | RegTbl[3];
  int16_t y = (((int16_t)RegTbl[4]) << 8) | RegTbl[5];  
  
  // X,Y軸の位置からラジアンを算出する
  float rad = atan2(y,x); 
  
  // XYZの3軸のうち、X軸方向の角度
  // ※X軸方向の詳細は記事を参照ください。
  float degree = rad * 180 / M_PI;  
  if(degree <0){
    degree = 360 + degree;
  }

  // 誤差(±15度)
  float hi = range360(degree + ambiguous);
  float lo = range360(degree - ambiguous);

  // 北東南西 
  Serial.print("方位:");  
  bool  orientation= false;
  if(N >= lo && N <= hi){
    Serial.print("北 ");
    orientation = true;
  }else if(E >= lo && E <= hi){
    Serial.print("東 ");
    orientation = true;
  }else if(S >= lo && S <= hi){
    Serial.print("南 ");
    orientation = true;
  }else if(W >= lo && W <= hi){
    Serial.print("西 ");
    orientation = true;
  }

  // 北東/東南/南西/北西
  if(!orientation){
    if(N <= degree || E >= degree){
      Serial.print("北東");
    }else if(E <= degree && S >= degree){
      Serial.print("東南");    
    }else if(S <= degree && W >= degree){
      Serial.print("南西");    
    }else if(W <= degree && N >= degree){
      Serial.print("北西");          
    }
  }

  Serial.print(" (以下、調整前データ → ");
  Serial.print("X:");
  Serial.print(x);  
  Serial.print(" Y:");
  Serial.print(y);  
  Serial.print(" Z:");
  Serial.print(x);  
  Serial.print(" 方位角:");
  Serial.print(degree);  
  
  Serial.println(")");
  delay(1000);
}

地磁気センサーなので本来(*1)は「方位磁石」と同じ地磁気での北(磁北)を差しています。磁北は地図上の北(真北)とは異なります。この差を磁気偏差(Magnetic declination)と呼ぶようです。

この磁北は真北より西側(国内では約5から10度)に向いています。磁北線は国土地理院地図の[機能][設定][磁北線]で確認する事が可能です。(ズーム11以上の場合)

※1 このHMC5883Lの各値はキャリブレーション(調整)が必要です。

Wikipedeiaで補足:磁北とは(Wikipedeia)

最後に

今回のスケッチでは地域によって異なる「磁北」は考慮せずに「±15度の誤差」を使用して簡易的なデジタルコンパスとしています。

高精度な方位が必要な場合は適宜、コードを変更して下さいませ。





掲示板

ArduinoやRaspberry Piなどの電子工作の掲示板を作成しました。質問やわからない事は電子工作 (Arduino・ラズパイ等)でユーザー同士で情報を共有して下さい。

関連記事



公開日:2017年07月01日 最終更新日:2017年07月02日
記事NO:02447