M5StickCを使って加速度計を作ってみた

クルマやバイクに乗っているとき、加速度が視覚化できたら、運転スキルを磨くのに活用できますよね。

3500円のM5StickC Plusを買って、100行以下の簡単なプログラムを書けば実現できますので、作り方を解説します。

プログラムのポイントは3つです。

  • 加速度センサからのデータ取得
  • 傾き補正
  • チラつきなくディスプレイに表示

それでは始めましょう!

目次

M5StickC Plus 加速度センサの概要

製作物は下の写真になります。

M5StickC Plusのディスプレイに加速度を表示させました。

加速度が発生していないときは、赤い点はグラフ中心に位置し、加速度に応じて赤い点が上方向、減速度に応じて下方向に動きます。

カーブを曲がったときは、横加速度に応じて赤い点が横方向に移動します。

加速度がどれぐらい発生しているかは、円を基準にすれば分かります。一番外側の円を1G (=9.8m/s2)発生線としました。

M5StickCの取り付けは、裏面に両面テープなどで取り付けます。

垂直に取り付けられない場合に備えて、傾きを補正出来るようにしています。

M5StickCのAボタン(M5と書かれているボタン)を押すと傾きが補正され、赤い点がグラフ中央に位置するようになります。

製作方法

プログラム

全体のプログラムは以下のとおりです。

#include <M5StickCPlus.h>
#include <math.h>

TFT_eSprite sprite = TFT_eSprite(&M5.Lcd);

float OFFSET_X = 0, OFFSET_Y = 0, OFFSET_Z = -0.08;
float accX, accY, accZ, accU, accV, accW;
float x, y, z, theta;
int R1 = 20, R2 = 40, R3 = 60;
int X0 = 120, Y0 = 67;

void setup() {
  M5.begin();
  M5.IMU.Init();
  M5.Lcd.setRotation(3);

  // スプライトの作成
  sprite.setRotation(3);
  sprite.createSprite(M5.Lcd.width(), M5.Lcd.height());
}

void loop() {
  sprite.fillRect(0, 0, M5.Lcd.width(), M5.Lcd.height(), BLACK);
  
  // グラフ描画
  sprite.drawCircle(X0, Y0, R1, WHITE);
  sprite.drawCircle(X0, Y0, R2, WHITE);
  sprite.drawCircle(X0, Y0, R3, WHITE);
  sprite.drawLine(X0 - R3 - 10, Y0, X0 + R3 + 10, Y0, WHITE);
  sprite.drawLine(X0, Y0 - R3 - 5, X0, Y0 + R3 + 5, WHITE);

  // 加速度データ取得
  M5.IMU.getAccelData(&x, &y, &z);
  
  accZ = -(x + OFFSET_X);
  accY = -(y + OFFSET_Y);
  accX = -(z + OFFSET_Z);
  accU = accX * sin(theta*PI/180) + accZ * cos(theta*PI/180);
  accV = accY;
  accW = - accX * cos(theta*PI/180) + accZ * sin(theta*PI/180);
  
  sprite.setCursor(0,5,2);
  sprite.printf("X:%5.2fG\nY:%5.2fG\nZ:%5.2fG", accU, accY, accW);
  sprite.fillCircle(X0 + (int)(accV * R3), Y0 - (int)(accU * R3), 8, RED);

  // 傾き補正
  M5.update();
  if(M5.BtnA.wasPressed()){
    accZ = max(min(accZ, 1.0), -1.0);
    theta = 180 / PI * asin(accZ);
  }

  // スプライトを表示画面に転送する
  sprite.pushSprite(0, 0);
  delay(100);
}

プログラムのポイントは3点です。

  • 加速度センサからのデータ取得
  • 傾き補正
  • チラつきなくディスプレイに表示

加速度センサからのデータ取得方法

M5.IMU.Init();
M5.IMU.getAccelData(&x, &y, &z);

accZ = -(x + OFFSET_X);
accY = -(y + OFFSET_Y);
accX = -(z + OFFSET_Z);

加速度センサを初期化した後、getAccelData関数で加速度データを取得することが出来ます。

M5StickCの座標軸は写真のとおりです。

実際に取り付けたときに発生した加速度が分かりやすいよう、前後方向の加速度をaccX、横方向の加速度をaccY、垂直方向の加速度をaccZとし、取得した加速度データを座標変換しました。

私のM5StickCは、z軸の加速度値がオフセットしていましたので、補正をかけています。

傾き補正

M5StickCを垂直に設置しなくても前後方向の加速度を検出出来るよう、傾きを補正します。

傾斜角の求め方

静止した状態での傾斜角は以下式で求めることが出来ます。

$$accZ=g\sin\theta$$

$$\theta=\sin^{-1}(accZ/g)$$

M5StickのボタンA(M5と書かれているボタン)を押した時に傾斜角を求めるようにしました。

M5.update();
if(M5.BtnA.wasPressed()){
  accZ = max(min(accZ, 1.0), -1.0);
  theta = 180 / PI * asin(accZ);
}

前後方向加速度の求め方

M5StickCが傾いているとき、前後方向の加速度は以下式で求めることが出来ます。

$$accU = accX \sin\theta + accZ \cos\theta$$

accU = accX * sin(theta*PI/180) + accZ * cos(theta*PI/180);

チラつきなくディスプレイに表示

取得した加速度データをリアルタイムでディスプレイに表示させますが、工夫しないとチラつきが発生してしまいます。

チラつき防止方法は、別記事で詳細に解説していますので、こちらを参照下さい。

あわせて読みたい
【M5Stack】画面ちらつきのないデジタル時計を作ろう! M5Stackの画面に文字や図形を描画した際、画面がちらついて困っていませんか? 普通に画面描画するプログラムを組むとちらついてしまうんです。 本記事では、TFT_eSprit...
TFT_eSprite sprite = TFT_eSprite(&M5.Lcd);

sprite.createSprite(M5.Lcd.width(), M5.Lcd.height());
sprite.pushSprite(0, 0);

TFT_eSpriteクラスでSpriteを作成した後、Spriteに図形や文字を描画し、pushSprite関数でM5StickCのディスプレイにこのSpriteを表示させることでチラつきを防止します。

スプライトとは、コンピュータ上で動く図形を表現する際に、動かす図形と固定された背景とを別に作成し、ハードウェア上で合成することによって表示を高速化する手法のことである。

IT用語辞典バイナリ

まとめ

以上、M5StickC Plusを使った加速度センサの作り方解説でした。

クルマやバイクにM5StickC Plusを取り付けることで、加速度を視覚化出来ます。

M5StickC Plusは3500円ほどで購入出来るので、気軽に製作トライできますよ。

プログラムのポイントは3つでした。

  • 加速度センサからのデータ取得
  • 傾き補正
  • チラつきなくディスプレイに表示

みなさんの参考になりましたら幸いです。

よかったらシェアしてね!
  • URLをコピーしました!

この記事を書いた人

大学で機械工学を学んだ後、製造業で働く40代の会社員です。
IT系、電気系を学んでこなかった機械系人間が、ゲーム制作、電子工作に奮闘してます。
極力低コストでものづくりを楽しむのがモットー。

目次