■raspberryPi、通信プロトコルを持っているICだと簡単に接続できるのが面白くてI2Cで3.3V動作するICを買ってきてはつないでる。OSからはi2c-toolsのコマンドが使えて、シェルスクリプトからICを制御できる。既存のライブラリを使ったプログラムを書くのでもなく、コマンドで操作してその出力を加工して求める結果を得るだけなのでずいぶん感覚が違う。
i2cdetect -y 1
でI2Cデバイスのアドレスを確認して(Rev2なので'1')、
i2cget [address] [register]
でデバイスのレジスタを読出し、
i2cset [address] [register] [data]
でデバイスのレジスタに書き込む。
レジスタに読み書きする値はデフォルトでは単なる16進1バイトデータなので、センサーの値として扱うにはさらに加工しなければならない。連続する2つのレジスタ値を上位・下位バイトとして連結して、さらに12バイトだけ取り出したり、2の補数を計算したりする。最初はCでプログラムを組まなければならないかと思ったのですが、perlやrubyなどのインタプリタも使わずコマンドだけで、つまりはシェルスクリプトで処理できました。たとえば0x28レジスタに下位8ビット、0x29に上位8ビットで2の補数形式データの加工は次のように処理します。
export AX_L=`i2cget -y 1 0x19 0x28`
export AX_H=`i2cget -y 1 0x19 0x29`
i2cgetコマンドの出力は'0x'が頭に付くので、これをsedで整形します。
export AX16=`echo ${AX_H}${AX_L} | sed 's/0x//g' | sed 'y/abcdef/ABCDEF/'`
これで頭に0xのつかない16進データが得られるので、dcで計算して2の補数を求めます。2の補数はLMBが1の場合、負数にします。まずdcで10進に変換したあと、ビット数から得られる最大の正の数で割り、1以上であれば負数として変換させています。
export DIG=`echo "16i "$1" 10i p"| dc`
export REC=`expr ${DIG} \> 32768`
if [ "${REC}" = "1" ]
then
RET=`echo ${DIG}" 65536 - p" | dc`
else
RET=`echo ${DIG}" p" | dc`
fi
これで加速度センサの値など読みだせるようになったのですが、どうせなら大きな水平加速度を検出したらメールを出すようにしたら、とか思いました。要するに地震が来たらメールするような仕掛けにするわけですが、これをやるには短い頻度でセンサーを読み続けて「大きな」水平動を検知させなければなりません。それよりは閾値を越えた揺れを検出したら割り込みをかけたほうが扱いやすいです。ただ、i2c-toolsでは割込み待機ができません。もともとi2cのプロトコルに割込みの概念がないので無理もないことです。
そこでwiringPiのライブラリをインストールしました。GPIO割込みでウェイトさせて、割り込み発生後wiringPiのライブラリを使ってI2Cで加速度を読み続けるような実装にする予定。