概要
GR-ADZUKIにデジタルコンパスを搭載して方角を調べてみましょう!
準備
ハードウェア
GR-ADZUKI、USBケーブル(マイクロBタイプ)、HMC5883Lデジタルコンパスを用意してください。
デジタルコンパスを以下のように接続してください。GR-ADZUKIのスライドスイッチの下側が[ Sketch ]になっていることを確認してください。
ソフトウェア
デジタルコンパスはS4Aで使用できないため、ここではWebコンパイラを使用します。Webコンパイラの基本的な使い方は 「Webコンパイラでスケッチ」を参照してください。
また、IDE for GRでもお試し可能です。IDE for GRの基本的な使い方については「IDE for GRでArduinoスケッチ!」を参照してください。
HMC5883L用ライブラリのインポート
Adafruitのライブラリを使います。以下のリンクからzipに圧縮された2つのライブラリをダウンロードしてください。
WebコンパイラでGR-ADZUKIのプロジェクトを作成後、プロジェクトのルートからアップロードを行います。zipファイルのままアップロードしてください。
なお、IDE for GRでもライブラリをインポートできますが、library.propertiesというファイルを削除してからインポートしてください。削除しないと「Missing 'core-dependencies' from library」というエラーが発生します。
2つのライブラリをアップロードすると以下のようにプロジェクトツリーに表示されます。
サンプルプログラム
以下のようにプロジェクトツリーのAdafruit_HMC5883_Unifiedフォルダのexamplesにあるmagsensor.inoを開き、すべてをコピーします。
以下のようにgr_sketch.cppを開き、#include<Arduino.h>の下にペーストしてください。
ビルド実行後、adzuki_sketch.binファイルをGR-ADZUKIに書き、シリアルモニターで出力を確認してみましょう。以下のようにX,Y,Zの磁束密度(uT:テスラ)と、X,Yから求めた方位角が表示されます。
上の図の例では359.51になっていますが、HMC5883LのXがほぼ北に向いていることを示しています。
センサー出力のタイミングを考慮する
HMC5883Lはセンサー出力の準備ができたタイミングで、以下のようにDRDY信号にパルスを発生します。約65ms間隔のパルスが確認できます。
GR-ADZUKIのINT2(ピン25)を使用して、このパルスに合わせてセンサーの値を取得することができます。以下はサンプルプログラムです。実行すると方位角が出力されます。
/*GR-ADZUKI Sketch Template Version: V2.01*/
#include <Arduino.h>
/***************************************************************************
This is a library example for the HMC5883 magnentometer/compass
Designed specifically to work with the Adafruit HMC5883 Breakout
http://www.adafruit.com/products/1746
*** You will also need to install the Adafruit_Sensor library! ***
These displays use I2C to communicate, 2 pins are required to interface.
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing products
from Adafruit!
Written by Kevin Townsend for Adafruit Industries with some heading example from
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/>.
***************************************************************************/
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_HMC5883_U.h>
/* Assign a unique ID to this sensor at the same time */
Adafruit_HMC5883_Unified mag = Adafruit_HMC5883_Unified(12345);
bool g_sensor_flag;
void displaySensorDetails(void)
{
sensor_t sensor;
mag.getSensor(&sensor);
Serial.println("------------------------------------");
Serial.print ("Sensor: "); Serial.println(sensor.name);
Serial.print ("Driver Ver: "); Serial.println(sensor.version);
Serial.print ("Unique ID: "); Serial.println(sensor.sensor_id);
Serial.print ("Max Value: "); Serial.print(sensor.max_value); Serial.println(" uT");
Serial.print ("Min Value: "); Serial.print(sensor.min_value); Serial.println(" uT");
Serial.print ("Resolution: "); Serial.print(sensor.resolution); Serial.println(" uT");
Serial.println("------------------------------------");
Serial.println("");
delay(500);
}
void sensor_rdy(){
digitalWrite(10, HIGH);
g_sensor_flag = true;
}
void setup(void)
{
Serial.begin(9600);
Serial.println("HMC5883 Magnetometer Test"); Serial.println("");
pinMode(25, INPUT_PULLUP);
attachInterrupt(2, sensor_rdy, FALLING);
g_sensor_flag = false;
/* Initialise the sensor */
if(!mag.begin())
{
/* There was a problem detecting the HMC5883 ... check your connections */
Serial.println("Ooops, no HMC5883 detected ... Check your wiring!");
while(1);
}
/* Display some basic information on this sensor */
displaySensorDetails();
}
void loop(void)
{
/* Get a new sensor event */
if(g_sensor_flag == true){
sensors_event_t event;
mag.getEvent(&event);
float heading = atan2(event.magnetic.y, event.magnetic.x);
if(heading < 0) heading += 2*PI;
if(heading > 2*PI) heading -= 2*PI;
float headingDegrees = heading * 180/M_PI;
Serial.print("Heading (degrees): "); Serial.println(headingDegrees);
g_sensor_flag = false;
}
}