はじめに
M5Stack grayに入っている9軸IMUのMPU9250を動かしてみました。
少しハマった点があったので内容を残しておきます。
ただし、試した時期に依存した問題もあるのでその点はご了承ください。
MPU9250
3軸加速度、3軸ジャイロ、3軸地磁気が組み合わさった9軸センサーです。
いわゆるよくあるx,y,z軸の加速度センサーです。
この記事では加速度のみ扱います。
開発環境
Arduino IDE
M5Stackライブラリの取得
Arduino IDEのボードマネージャーから取得したM5Stack-Core-ESP32ではMPU9250は動作しませんでした。(2018/10/18現在の情報)
参考
Doesn't work sample sketch "MP9250BasicAHRS" on M5Stack Gray
I2C周りにトラブルがあるようなので、最新をgitHubからcloneして入れます。(安定版ではないので他の問題が発生する可能性はあります。)
https://github.com/espressif/arduino-esp32
インストール方法は下記参照
arduino-esp32のインストール方法(Windows)
clone先
C:\Users\UserName\Documents\Arduino\hardware\espressif\esp32
サンプルを動かしてみる
まずはM5Stackのスケッチ例にMPU9250を動かせるものがあるのでそれを実際に動かしてみます。
スケッチ例/M5Stack/Modules/MPU9250/MPU9250BasicAHRS
MPU9250のセンサー値がLCDに表示されればOKです。
キャリブレーション
calibrateMPU9250()
がキャリブレーションを実行しています。
サンプルではsetup()
内で呼ばれています。
// Calibrate gyro and accelerometers, load biases in bias registers
IMU.calibrateMPU9250(IMU.gyroBias, IMU.accelBias);
この関数を呼ぶとMPU9250の不揮発領域にオフセット値を保存するようなので、一度キャリブレーション実行後は呼ぶ必要はありません。
私はキャリブレーション時はX,Yを水平(M5StackのLEDを上向き)にして実行しました。その後は基本calibrateMPU9250()
はコメントアウトしています。
加速度の取得
MPU9250はジャイロ・地磁気も取れますが、とりあえず加速度だけ使ってみます。
加速度はIMU.ax,ay,azに格納されています。
IMU.ax = (float)IMU.accelCount[0]*IMU.aRes;
IMU.ay = (float)IMU.accelCount[1]*IMU.aRes;
IMU.az = (float)IMU.accelCount[2]*IMU.aRes;
#M5Stackの置いた向きを検出
ここまでで、加速度が検出出来ているので、M5Stackを置いた向きを検出するコードを書きます。
例えば、静止している状態でLCD上向きにすると、理想的には
Z : 1000mG, X,Y : 0mG
となります。
ただし誤差があるので、適当にしきい値を設けてどちらを向いているか確認します。
ACCEL_THR_MAX は下向き(ほぼ1000mG)かかる方向を検出するためのしきい値。
const static uint32_t ACCEL_THR_MAX = 700;
const static uint32_t ACCEL_THR_MIN = 300;
if(az >= ACCEL_THR_MAX && abs(ax) <= ACCEL_THR_MIN && abs(ay) <= ACCEL_THR_MIN){
//DETECT_FRONT
}
これを全方向分書くとM5Stackを倒した向きを加速度センサーで検出出来ます。
if( ax >= ACCEL_THR_MAX && abs(ay) <= ACCEL_THR_MIN && abs(az) <= ACCEL_THR_MIN){
//DETECT_LEFT
}else if(ax <= -ACCEL_THR_MAX && abs(ay) <= ACCEL_THR_MIN && abs(az) <= ACCEL_THR_MIN){
//DETECT_RIGHT
}else if(ay >= ACCEL_THR_MAX && abs(ax) <= ACCEL_THR_MIN && abs(az) <= ACCEL_THR_MIN){
//DETECT_TOP
}else if(ay <= -ACCEL_THR_MAX && abs(ax) <= ACCEL_THR_MIN && abs(az) <= ACCEL_THR_MIN){
//DETECT_BOTTOM
}else if(az >= ACCEL_THR_MAX && abs(ax) <= ACCEL_THR_MIN && abs(ay) <= ACCEL_THR_MIN){
//DETECT_FRONT
}else if(az <= -ACCEL_THR_MAX && abs(ax) <= ACCEL_THR_MIN && abs(ay) <= ACCEL_THR_MIN){
//DETECT_BACK
}else{
//not update
}
サンプル
検出するM5Stackの向きによってAvatarで喋る・表情が変わるサンプルを作りました。