Arduino+方位センサー(その2)  うまくいきました!

前回、動かすたびに同じ方位でも値が異なり、うまくいきませんでしたが、
Arduino側でキャリブレーションするようにしたところ、比較的正確に方位を取得できるようになりました。


キャリブレーションといっても以下のような簡単な方法です。
OUT1とOUT2それぞれについて最大値、最小値を測定し、最小値〜最大値の範囲で正規化します。
起動後にゆっくり2回転ほどさせると、正確な方位がとれるようになりました。
I2C版のHMC6352もキャリブレーション機能があるので、キャリブレーションは必須ということなのでしょう。


また、効果があるか良く分からないのですが、値の取得前にSET/RESET端子にパルスを入れるようにしています。
ArduinoのDIGITAL2をSET/RESET端子に接続します(10KΩの抵抗でプルダウン)。


Arduinoスケッチ

// Calibration 初期値は安全な値を適当に設定
int cal_min1 = 488;
int cal_max1 = 515;

int cal_min2 = 463;
int cal_max2 = 489;

void setup()
{
  pinMode(2, OUTPUT);
  Serial.begin(9600);
}

void loop()
{
  // SET/RESET PULSE
  digitalWrite(2, LOW);
  delay(10);
  digitalWrite(2, HIGH);
  delay(10);
  digitalWrite(2, LOW);
  delay(10);

  // 読み取り
  int val1 = analogRead(0);
  int val2 = analogRead(1);

  // キャリブレーション
  if (val1<cal_min1) cal_min1 = val1;
  if (val2<cal_min2) cal_min2 = val2;
  if (val1>cal_max1) cal_max1 = val1;
  if (val2>cal_max2) cal_max2 = val2;
  
  int div1 = (cal_max1 - cal_min1 + 1);
  int div2 = (cal_max2 - cal_min2 + 1);

  float fval1 = (val1 - cal_min1 - div1 / 2.0) / div1;
  float fval2 = (val2 - cal_min2 - div2 / 2.0) / div2;
    
  // 角度(方位)を0〜255に変換
  int at = (atan2(fval1, fval2) + PI ) * 255 / (2*PI);

  Serial.print(at, BYTE);
  
  delay(100);
}


■Processingスケッチ

import processing.serial.*;

Serial myPort;
int val;

void setup() 
{
  size(200, 200);

  myPort = new Serial(this, "COM9", 9600);
  PFont font = createFont("Arial", 12); 
  textFont(font); 
}

void draw()
{
  if ( myPort.available() > 0) {
    val = myPort.read();
  }

  background(0);
  text(str(val), 1, 10); 
  translate(width/2, height/2);
  rotate(val * 2 * PI/255);
  triangle(-10, -40, 10, -40, 0, 40);
}