かみやんの技術者ブログ

主にプログラムの話です

磁気センサー HMC1052Lを接続

今日は、2軸 磁気センサーのHMC1052L(これ)をSH7125に接続し、ファームウェアを書いて、PC側のGUIプログラムも書いた。

まずHMC1052のOUT1(X軸)とOUT2(Y軸)をSH7125のAD2とAD3に接続。Set/ResetピンをSH7125のPE3に接続した。電源は、マイコンの電源5Vをそのまま供給。
このSparkfunの基板では、オペアンプで100倍に増幅されている模様。この基板からの出力は、5V入力の場合、磁気0のとき2.5V。X軸とY軸の2出力。が、なぜかX軸は2.5V付近で、回転させると多少電圧が変わるものの、Y軸が0.3Vぐらいで変化しない。Set/Resetピンの使い方がなにかあるのかな?といろいろ試すが変わらず。結局、この基板は、自分がピンヘッダを半田付けするときに熱で壊したか、静電気で壊したか、ショートさせたか、なんらかの理由で壊してしまったのだろう(もしくは最初から壊れていた)。ということで、もう一枚、同じ基板を購入。

2枚目では、ピンヘッダを自分で半田付けする前に、テスターで試験。うむX軸、Y軸ともに2.5V付近だ。というわけで1枚目は壊していた模様。

この基板のSet/Resetピンは、磁気センサーIC内に滞留している磁気をキャンセルするためのスイッチらしいのだが、どういうときにパルスを与えろというのが、データシートを読んでもさっぱり分からなかった。とりあえず、パルスを与えなくても、起動時に1回だけ与えても、A/Dスキャン1回ごとにパルスを与えても大差なかった。

一応、SparkfunのフォーラムにA/Dスキャン1回ごとにパルスを与えよ(High-Low-Scan)とあった(これ)ので、一応そう実装しておいた。

ファームウェアのコードは下記のような感じ

    //コンパス
    SetPin(PinNoPE3,HIGH);
    Sleep(1);
    SetPin(PinNoPE3,LOW);
    Sleep(1);
    
    PrintToSerial(PORT,"OD t=%d L=%d R=%d CX=%d CY=%d\r\n",now,left,right,
        GetADRaw(AD_COMPASS_X),GetADRaw(AD_COMPASS_Y));

ロータリーエンコーダのカウント値と一緒に50ms毎にPCに送ることにした。

で、PCに届いたX軸、Y軸の値をExcelでグラフで表示してみたところ、全然2.5Vが原点でないことが判明。

上図、Excelでグラフ化したところ。原点より上にオフセットしている。また、最後のあたりで強力な磁力を受けているのが分かる。
ということで、AibiUI(PC側のGUIソフト)に、磁気ベクトル表示機能をつけてみたところ、やはり原点からずれている。これでは全然方位を指さない。
というわけで、AibiUIにキャリブレーション機能をつけた。使い方は、キャリブレーション画面を表示して、センサーを1回転させて円を描かせて、確定ボタンでその円の中心がオフセット値となる。

表示してみた感想としては、とにかくブルブルベクトルがぶれる。
そもそも5Vを供給したときに原点が2.5V付近だが、地磁気程度の弱い磁力では、±0.15Vぐらいしか変化しない。つまり2.35Vが南で2.65Vが北みたいな。で、AD変換としてはSH7125は、10bitのAD変換器であり、±34程度(整数値)しか変化しないので、その荒さで円を書くのでガタツキができる。HMC1052Lのデータシートにも「12〜16bitぐらいのA/D変換器を使うと良い。3度程度の精度でよいなら10bitとかでもよいけど」みたいなことが書いてある。
この基板、オペアンプで100倍に増幅した値で出力してくれているが、地磁気限定とすれば2000倍ぐらいに増幅して欲しいところ(オペアンプは1段で2000倍は無理?)。もしくは、自分で16bitのA/Dコンバータチップを外付けして精度を上げるか。
あと、ブルブル震える原因としては、マイコン近くでノイズが発生していて拾っているのか、センサーの性能としてこんなもんなのか、室内だからいろいろ電磁波が飛んでいるのか。そういうのも考えられるかもしれない。
逆に、この基板を使ってみて、を!これは使える。と思ったのが、磁気ベクトルが得られるので、ベクトルの長さが大きすぎるときは、近くに金属や大電流が流れていて地磁気がちゃんと取れていないということが分かること。つくばチャレンジのコースでは、地面に電線が通っていて一部地磁気センサーが使えない場所があると去年の報告であったので。

次回試走会には間に合わないが、HMC6352(これ)も試してみたいな。こっちはI2Cでキャリブレーション機能付き。