M5StickCでUIFlow入門 その5 加速度計とグラフィック

現時点の情報です。最新情報はM5StickC非公式日本語リファレンスを確認してみてください。

概要

前回はif文のみで終わってしまいましたが、今回は加速度計のグラフ表示を行いたいと思います。

加速度計とは?

単位時間あたりの速度の変化をあらわします。といっても、よくわからないと思うのですが、M5StickCが動いた方向への加速と減速を計測した数値です。

どの方向に動いたかを、X軸、Y軸、Z軸であらわします。M5StickCを縦に持った場合に上下方向がY軸、左右方向がX軸、前後方向がZ軸になります。

これはあとで動かしながら試してみるとわかりやすいです。

加速度

どれだけ速度が変化したかを加速度と表現し、単位にはG(ジー)を使います。1Gは物を自然落下させた場合の加速度になります。落下する速度よりも加速が遅いと1G以下の数字で、加速が早いと1G以上の数字になります。

速度の変化ですので、速度がいくら早くても加速も減速もしていない場合には0Gになります。左右への加速度であるX軸では、右側に加速する場合にはプラスの加速度。左側に加速する場合にはマイナスの加速度になります。

注意しないといけない点として、加速度計は重力の影響をつねに受けています。常に地面に向かって重力が発生し、下向きに1Gの加速度が発生しています。

そのため、M5StickCを縦に持ったときに下向きに発生しているので、何も動かしていなくてもY軸は-1Gになります。

M5StickCを右側に倒した場合、M5StickCのX軸でいうと右側のプラス方面が地面になるので、なにも動かしていなくてもX軸は1Gになります。

つまり、動かしていなくても地面に向かって常に1Gが発生してしまうので気をつけてください。中途半端に傾けた場合には、いろいろな軸に1Gが分散して発生します。

グラフィック制御

M5StickCは横80ドット、縦160ドットの画面があります。M5StickCを縦に使った場合には、左上の座標が(x=0, y=0)になり、右上の座標が(x=79, y=0)、左下の座標が(x=0, y=159)、右下の座標が(x=79, y=159)になります。

座標は0からはじまるので注意してください。

加速度をグラフに描いてみる

ざっくりとX軸の加速度をグラフに描いてみたいと思います。左右にM5StickCを揺らした場合に、左右に揺れるようなグラフにします。

まず加速度ですが、ジャットコースターでの加速度でも3Gから5Gです。そのため、通常は-5Gから+5Gぐらいまでの範囲が測定できれば問題ありません。

M5StickCを縦に使った場合、横が80ドットですので、左右に40ドットずつと考えると、1Gあたらい8ドットで、5Gの場合40ドットとなります。

停止しているときには、X軸の加速度が0Gで、グラフが中心に来ますのでx=40になります。つまり、X軸の加速度がマイナスの場合には、x座標が40より小さくなり、X軸の加速度がプラスの場合には40より大きくなるように計算をしてグラフを描画していきます。

ちょっとわかりにくいですが、上記のプログラムになります。Y座標の保存ように変数「drawY」を定義して、最初に0をセットしています。

そのあとにずっとで、加速度を取得して8倍したあとに整数に変換してから40を足したX座標とdrawYのY座標に対して、白色で点を描画しています。

その後drawYを1増やして、グラフの描画を下にずらします。最後にこのままだと動作が早すぎるので、20ミリ秒停止をしています。

さて、動かしてみてください。動いたらM5StickCを横に動かしてみてください。

上記のように動かしたときに加速度が変化しましたでしょうか?

ただ、グラフが一番下に到達したあとに、動きが止まってしまいましたね。これを次で修正したいと思います。

グラフのリセット

もしの処理を追加しました。Y座標は159までですので、160以上になったらリセットします。リセットの処理は画面をクリアしてから、Y座標を0に戻します。

これで、一番したまでグラフが到達したら、画面がクリアして、一番上にグラフが戻ると思います。

さて、この状態で左右に思いっきり振ってみてください。ある一定以上のGには到達できないと思います。画面の端までいくと5Gですが、おそらく半分以下のところまでしかいかないと思います。どうやらUIFlowの加速度センサーは-2Gから+2Gまでの範囲しか測定できないようです。

倍率の見直し

2Gまでですので、40ドットで割ると1Gあたり20ドットです。現在8倍しているところを20倍に変更する必要があります。

また、ピクセルのところで計算をしていますが、ちょっとわかりにくいので変数に切り出してみます。

あたらしく「drawX」変数を作って、そこに代入するときに計算をしています。変数にする必要はないのですが、複雑な計算をした場合には、一度変数に代入をしておくと、画面にその数値をテストで表示することもできるので、便利です。

これで動かしてみると、思いっきり振った場合に画面端っこまでグラフが描画されてます。さて、この状態だとグラフの点がバラけて、きれいなグラフにならないと思います。

描画速度が遅いことが原因なので、20ミリ秒の停止をもっと小さい数値に変更します。

高速化

最後の停止時間だけ変更してあります。10ミリになったので、先程の倍の速度でグラフが描画されると思います。0とか5ミリ秒にしてみるともっときれいにグラフが描画されるはずですが、すぐに画面から消えてしまいます。

この段階で、M5StickCを左右に倒してみてください。そうすると動かしていないのに、グラフの線が左右のどちらかに移動したと思います。

完全に横に倒すと重力で1Gが地面の方向に追加されるのがわかると思います。

応用

一気に複雑になっていますが、タイマーを使った例です。最初に「タイマーが呼び出されたとき」ブロックを設置して、呼び出された場合にはLEDを消す処理が入っています。

「ずっと」の処理の先頭で、「もし」ブロックが追加されています。条件値としてはX軸の加速度の絶対値が1.5以上の場合です。絶対値はマイナスの値でもプラスに変換します。そのため1.5G以上の加速度の変化があると処理を行います。

処理はLEDをつけてから、タイマーを500ミリ秒でワンショットで呼び出します。これは500ミリ秒後に1度だけタイマー処理を呼び出すという意味になります。

これで、1.5G以上の衝撃などがあると、LEDが500ミリ秒点灯するプログラムになりました。できあがったプログラムは以下のアップしておきました。

タイマーを使わないで、LEDをONにしてから500ミリ秒停止して、LEDをOFFにするような処理でも構いませんが、その場合にはLEDがONの場合にグラフ描画が止まってしまいます。

まとめ

今回はX軸の加速度でしたが、他の軸に変更して試してみてください。また、1.5G以上でLEDをONにしていましたが、M5StickCを横に倒した状態で動かすと、より少ない動きでもLEDがONになります。

これは横に倒したことで、重力の1GがX軸に追加されているため、0.5Gの加速度で反応してしまうようになっています。

このように加速度は重力の影響を受けるのでちょっと使いにくいところもあります。前回との差分や、移動平均などを使って加速度の検知を調整することもできますが、今回はそこまではやりません。

コメントする

メールアドレスが公開されることはありません。

管理者承認後にページに追加されます。公開されたくない相談はその旨本文に記載するかTwitterなどでDM投げてください。またスパム対策として、日本語が含まれない投稿は無視されますのでご注意ください。