2013年9月11日水曜日

RaspberryPI + I2C 3軸デジタルコンパスHMC5883L


RaspberryPIにはi2cインターフェースがついていて、i2c経由で色々できるらしい。ということでi2cの面白いセンサーがないかなぁと探していたところ
というのをみつけた。

ロボットにつけて向きを測定したりするのが正しい用途なんだろうけど、センサー固定して地磁気のログをとってみるのも興味深いかもってことでポチリ。

で、少し前に届いてたのを今回触ってみる。

チップにピンヘッダをハンダ付けしてブレッドボードオーン。
GPIOにジャンパーピーン。

ロボット制御のように連続計測するわけじゃないのでDRDYは使用しない。でいいよね。たぶん。



例によって
あたりを参考にRaspberryPIにi2cを設定。

HMC5883Lの仕様の詳細についてはStrawberry Linuxの「3軸ディジタルコンパスモジュール HMC5883L 」のマニュアルを参照。

i2cdetectでチップ認識、アドレス確認
  => 0x1e

動作確認用のIdentification Register読み出しも問題なし
  => 0xa=0x48, 0xb=0x34, 0xc=0x33

pi@raspi2:~$ sudo i2cdetect 1
WARNING! This program can confuse your I2C bus, cause data loss and worse!
I will probe file /dev/i2c-1.
I will probe address range 0x03-0x77.
Continue? [Y/n] 
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- 1e -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --                         
pi@raspi2:~$ sudo i2cget -y 1 0x1e 0x0a b
0x48
pi@raspi2:~$ sudo i2cget -y 1 0x1e 0x0b b
0x34
pi@raspi2:~$ sudo i2cget -y 1 0x1e 0x0c b
0x33

Mode Register(0x02)に0x00を書き込むと連続計測モードになって、
値がData Output Register(0x03〜0x08)に書き込まれる。
データは下記のようにX,Y,Zの16bitずつである。

0x03 X方向MSB

0x04 X方向LSB

0x05 Z方向MSB

0x06 Z方向LSB

0x07 Y方向MSB

0x08 Y方向LSB


Status Register(0x09)の下位1bitが1だと読み込み可能。

デフォルトだと15Hzで更新されるのでコマンドポチポチ打つ分には常に読み込み可能状態。


下位2bit目はLOCKbitで0x03-0x08で読み込んでないRegisterがあると1になる。
全部読むとクリアされる。

LOCK中はRegisterが更新されない(全部Data Register読まないと更新されない)。

pi@raspi2:~$ sudo i2cset -y 1 0x1e 0x00 0xe0 # Configuration A Registerをデフォルトにセット
pi@raspi2:~$ sudo i2cset -y 1 0x1e 0x02 0x00 # Mode Register Continuous modeにセット
pi@raspi2:~$ sudo i2cget -y 1 0x1e 0x09 b    # Status Register 
0x11                                         # => Ready
pi@raspi2:~$ sudo i2cget -y 1 0x1e 0x03 b    # X MSB Register
0x02
pi@raspi2:~$ sudo i2cget -y 1 0x1e 0x04 b    # X LSB Register
0x7d
pi@raspi2:~$ sudo i2cget -y 1 0x1e 0x05 b    # Z MSB Register
0xff
pi@raspi2:~$ sudo i2cget -y 1 0x1e 0x06 b    # Z LSB Register
0x15
pi@raspi2:~$ sudo i2cget -y 1 0x1e 0x07 b    # Y MSB Register
0x00
pi@raspi2:~$ sudo i2cget -y 1 0x1e 0x08 b    # Y LSB Register
0x58
pi@raspi2:~$ sudo i2cget -y 1 0x1e 0x09 b    # Status Register
0x11                                         # => Ready

... ここでブレッドボードを90度動かしてみる ...

pi@raspi2:~$ sudo i2cget -y 1 0x1e 0x03 b    # X MSB Register
0x00
pi@raspi2:~$ sudo i2cget -y 1 0x1e 0x04 b    # X LSB Register
0xba
pi@raspi2:~$ sudo i2cget -y 1 0x1e 0x05 b    # Z MSB Register
0xff
pi@raspi2:~$ sudo i2cget -y 1 0x1e 0x06 b    # Z LSB Register
0x43
pi@raspi2:~$ sudo i2cget -y 1 0x1e 0x07 b    # Y MSB Register
0x01
pi@raspi2:~$ sudo i2cget -y 1 0x1e 0x08 b    # Y LSB Register
0x9d

ブレッドボードを動かすと値が変わったのを確認できた。

ちなみに値はsigned int 16で-2048から2047の範囲。

設定でpositive bias、negative biasかけられるとあるが、uint 16になるという意味なのか、値域はそのままで値にbiasするのか不明。まーデフォルトで。

日本語マニュアルには磁石を近づけるとすぐオーバーフロー(0xff)するとあったけど、近づけると大きく値が変化するもののオーバーフローまでには至らない。

ということでお試し的に十分堪能したので次はログ取りスクリプトを作成しよう。

C言語で作成しようかと思ったけどなんか面倒になったのでRubyでいいや。

リアルタイムじゃなくていいし。

0 件のコメント:

amazonアソシエイト