M5StickCをかたむけて画面上のボールを転がす

M5StickCには、MPU6886という6軸センサが搭載されています。

今回は、このセンサを使って、「M5StickC本体を傾けると、それに応じて、LCDに表示されているボールが転がる」というスケッチを作ってみます。

ひとつひとつのステップごとに、動作確認をしながら、進めていきます。

ボールを表示する

まずは事前準備として、LCDにボール(円)を表示してみます。
今回はM5StickCを横向きで使用します。
画面サイズは横160ピクセル、縦80ピクセルです。

M5StickCに、以下のスケッチを書き込みます。

#include <M5StickC.h>

void setup() {
  M5.begin();
  M5.Lcd.setRotation(1);
  M5.Lcd.fillCircle(10, 40, 10, RED);
  M5.Lcd.fillCircle(80, 40, 10, BLUE);
  M5.Lcd.fillCircle(150, 40, 10, YELLOW);
}

void loop() {
}

結果は以下のとおりで、画面左端に赤、画面中央に青、画面右端に黄色のボールが表示されました。

ボールを動かす

次に、変数「x」でボールの位置情報(X座標)を、変数「v」でボールの速度を定義し、ボールをLCD画面上で、一定速度で左右に動かしてみます。
スケッチは以下のとおりです。

#include <M5StickC.h>

int x = 10;
int v = 1;

void setup() {
  M5.begin();
  M5.Lcd.setRotation(1);
}

void loop() {
  M5.Lcd.fillScreen(BLACK);
  M5.Lcd.fillCircle(x, 40, 10, YELLOW);
  x += v;
  if(x==10) v = 1;
  if(x==150) v = -1;
  delay(10);
}

結果は以下のとおりです。ボールが一定の速度で、左右に動いています。

MPU6886の加速度情報を表示する

6軸センサが採取する加速度情報を確認するために、以下のスケッチを作りました。

#include <M5StickC.h>

float accX = 0.0f;
float accY = 0.0f;
float accZ = 0.0f;

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

void loop() {
  M5.update();
  M5.IMU.getAccelData(&accX, &accY, &accZ);
  Serial.printf("%5.2f,%5.2f,%5.2f\n", accX, accY, accZ);
  delay(100);
}

シリアルプロッタで確認したところ、M5StickCを左右に傾けることによって、2カラム目の値(accY)が変化することがわかりました。

念のため、accYだけを出力するように、スケッチを修正しました。

#include <M5StickC.h>

float accX = 0.0f;
float accY = 0.0f;
float accZ = 0.0f;

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

void loop() {
  M5.update();
  M5.IMU.getAccelData(&accX, &accY, &accZ);
  Serial.printf("%5.2f\n", accY);
  delay(100);
}

シリアルプロッタに表示させた結果は、以下のとおりです。M5StickCを左右に傾けることによって、値が変化しています。
なお、本体を右に傾ける(左側を上げる)とプラス、左に傾ける(右側を上げる)とマイナス、水平にしているとゼロになります。

M5StickCの傾きに応じた位置情報を表示する

先ほどのスケッチで採取した加速度情報から、M5StickCの傾きに応じた速度、位置情報を計算し、シリアルプロッタに位置情報を表示させてみます。

#include <M5StickC.h>

float accX = 0.0f;
float accY = 0.0f;
float accZ = 0.0f;
float x = 0.0f;
float v = 0.0f;

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

void loop() {
  M5.update();
  M5.IMU.getAccelData(&accX, &accY, &accZ);
  v += accY;
  x += v;
  Serial.printf("%5.2f\n", x);
  delay(100);
}

結果は以下のとおりで、M5StickCの傾きに応じて、位置情報が変動していることがわかります。

完成(傾きに応じてボールをころがす)

ここまで作ってきたスケッチと、先ほど事前確認した、ボールを動かすスケッチを組み合わせて、M5StickCの傾きに応じて、ボールを動かします。
スケッチは以下のとおりです。ボールが画面の左端、右端にいる時には、ボールが画面からはみ出ないように、速度「v」をゼロに、位置情報「x」をその座標に固定しています。

#include <M5StickC.h>

float accX = 0.0f;
float accY = 0.0f;
float accZ = 0.0f;
float x = 80.0f;
float v = 0.0f;

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

void loop() {
  M5.update();
  M5.IMU.getAccelData(&accX, &accY, &accZ);
  v += accY;
  x += v;
  if(x>=150.0) { v=0.0; x=150.0; }
  if(x<=10.0) { v=0.0; x=10.0; }
  M5.Lcd.fillScreen(BLACK);
  M5.Lcd.fillCircle((int)x, 40, 10, YELLOW);
  delay(20);
}

結果は以下のとおりです。M5StickCの傾きに応じて、黄色いボールが自然にころがっています。

M5StickCの6軸センサとLCDを使うことで、比較的簡単に、視覚的にも結構おもしろいスケッチを作ることができました。

なお、私がM5Stack、M5StickCの使い方を習得するのにあたっては、以下の書籍を参考にさせていただきました。


ごく基本的なところから、かなり複雑なスケッチや、ネットワーク接続など、比較的高度なものまで、つまづかずに読み進めていけるような構成になっており、大変わかりやすい本です。


このサイトで書いている、M5Stackシリーズ(M5Stack、M5StickCなど)に関するブログ記事を、「さとやまノート」という別のブログページに、あらためて整理してまとめました。

他のM5Stackシリーズの記事にも興味のある方は「さとやまノート」をご覧ください。