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の使い方を習得するのにあたっては、以下の書籍を参考にさせていただきました。
ごく基本的なところから、かなり複雑なスケッチや、ネットワーク接続など、比較的高度なものまで、つまづかずに読み進めていけるような構成になっており、大変わかりやすい本です。