Nefry Advent Calendar 2017 の16日目です。よろしくお願いします。
今夏、Nefry BTのクラウドファンディングを支援してNefry BTをゲットし、Nefry BTにはGroveの端子が4つあるので、せっかくだからGroveのセンサを使ってみようと思いました。
のびすけさんのNefryでGrove加速度センサを触るメモという記事を見て、Nefry BTで加速度センサを使ってみようとしましたが、見事にハマってしまったというお話です。
使用したもの
- Nefry BT
- Grove - 3-Axis Digital Accelerometer(±1.5g)
センサとNefry BTのI2C(D0)ソケットをGroveケーブルで接続します。
Nefry BTにサンプルのスケッチを書いてみた
のびすけさんの記事に書いてある通り、センサを扱うためにSeeedのリポジトリからAccelerometer_MMA7660ライブラリをダウンロード(Download ZIP)し、Arduino IDE上で「ライブラリをインクルード > .ZIP形式のライブラリをインストール」でライブラリをインストールします。
https://github.com/Seeed-Studio/Accelerometer_MMA7660
(Nefry BTを利用する際、こちらのリポジトリからZIPファイルをダウンロードすることはおすすめできません)
Arduino IDEのスケッチの例に「Accelerometer_MMA7660 > MMA7660FC_Demo」があるので、こちらのスケッチをNefry BTに書き込んでみました。
シリアルモニタを見てみるとこんな感じでした。
センサは静止した状態でスクリーンショットを撮りましたが、3軸の加速度の2乗和平方根(つまりノルムの値)が 3.18g
くらいになってしまっています。地球上にいるのならだいたい 1g
になるはずなので、明らかにおかしな状態です。Seeedのページを見ても、やはり仕様通りではありません。
Arduino Unoにサンプルのスケッチを書いてみた
センサの初期不良を疑いましたが、いったんArduino Unoで問題なく動作するか確認してみることにしました。
この写真のようにGroveケーブルにジャンパワイヤーを差し込んで、センサをGroveのベースシールドがないArduino Unoに接続できるようにしました。A4とSDA, A5とSCL, GND, 5Vを接続します。
Nefry BTと同様にスケッチの例「Accelerometer_MMA7660 > MMA7660FC_Demo」をArduino Unoに書き込んでみました。
おそらく正しい値が取れており、センサの初期不良ではなさそうです。
ライブラリのコードを見て修正してみた
となると、ライブラリがおかしいと思われたので、C++の知識はあまりないですがライブラリのコードを見てみることにしました。
すると、 MMA7660::getXYZ
の引数がbool MMA7660::getXYZ(int8_t *x,int8_t *y,int8_t *z)
なのにも関わらず、最後に char
でキャストして4で割って *x
, *y
, *z
に代入していることに気づきました。
キャストの部分に怪しさを感じ、試しに char
でキャストの部分を int8_t
でキャストに変更したところ、Nefry BTでもArduino Unoでも問題なく動作するようになりました。
つぶやいてみた
キャストの動作がArduino UnoとNefry BT(ESP32)とで異なることについて、Twitterでつぶやいたところ、「charがsignedかどうかは処理系依存」ではないか、というご意見をいただきました。byte型の値をchar型のキャストして4で割ってint8_t型の変数に入れるときの挙動がArduino UnoとESP32で違うっぽい🤔 pic.twitter.com/IFoE3g0NqM
— mascii (@mascii_k) 2017年8月13日
なんかESP32の方、charがunsigned charになってるっぽい挙動。コンパイル時にオプション入ってるんちゃうかな。 https://t.co/uJHbz0LVt7
— Kenta IDA (@ciniml) 2017年8月13日
ああ、charがsignedかどうかは処理系依存なのか。Espressifが提供するxtensa用ツールチェインのgccはunsignedなんかな。ARMもunsignedらしい。https://t.co/CSNYEWH40S
— Kenta IDA (@ciniml) 2017年8月13日
学んだこと
- NefryはESP8266、Nefry BTはESP32を使っている以上、Nefryで使えるライブラリがNefry BTでそのまま使えると限らないこと
- 初心者の方は「Nefry BTで」使えることがわかっているセンサ・ライブラリの組み合わせを使うと良さそうです
- 今回のケースのように、Arduino用として公開されているセンサのライブラリをArduinoで使ってみることで問題の切り分け(センサの初期不良なのか、ライブラリの不備なのか、など)ができること
- 「charがsignedかどうかは処理系依存」であること
ちなみに、この加速度センサの使い道は?
8月に開催されたMaker Faire Tokyo 2017で、Seeedさんが同種のセンサで「ゴミ箱のフタの開閉」を検知していたので、そういった使い方があると思われます。加速度センサというより、重力方向センサだと思った方が良さそうです。
修正版ライブラリの公開
SeeedのリポジトリをForkし、修正版を公開していますので、お困りの方はこちらをご利用ください。
https://github.com/mascii/Accelerometer_MMA7660
(20180319追記)
のびすけさんからESP32用サンプルスケッチのPull Requestをいただき、マージいたしました。
https://github.com/mascii/Accelerometer_MMA7660/blob/master/examples/MMA7660_for_ESP32/MMA7660_for_ESP32.ino