Help us understand the problem. What is going on with this article?

M5StackGrayでMPU-9250のDMPを使う

More than 1 year has passed since last update.

1. M5Stack

M5Stackはesp32を搭載した開発モジュールです。
カラーディスプレイとボタン3つを備えているのが特徴です。

esp32がBLEとWifiのモジュールを標準搭載しているためか、IoT分野でも開発が盛んなようです。
豊富なArduinoのライブラリとの互換性を持てているのも利点です。

1.1 M5Stack Gray

GrayというモデルがIMU(MPU-9250)を搭載しており、3軸加速度・3軸角速度・3軸地磁気のデータを得ることができます。

1.2 DMP

MPU-9250はDMP(Digital Motion Processer)を備えています。通常は3軸加速度・3軸角速度・3軸地磁気のセンサ値からカルマンフィルタや相補フィルタでセンサフュージョンを行ってクォータニオン(センサの姿勢を表す値)を求めますが、DMPのお陰で自力でこれらを実装せずともクォータニオンを取得することができます。

2. 実装

2.1 PlatformIO

M5Stackにプログラムを書き込むための環境を構築します。マルチプラットフォームであり、vscodeによるIDEの補完が期待できることからPlatformIOを選択しました。
https://platformio.org/

具体的な構築手順はこちらの記事が詳しいです。
M5Stackの開発環境を整える - PlatformIO IDE編

2.2 DMPライブラリ

SparkFunのリポジトリにMPU-9250のDMP用のライブラリがあるのでソースコードを落とします。
sparkfun/SparkFun_MPU-9250-DMP_Arduino_Library

どこに配置するかは任意ですが、私はプロジェクトのlibディレクトリにSparkFun_MPU-9250-DMP_Arduino_Libraryというディレクトリを作り、以下にライブラリのソースファイルやライセンスファイルを配置しました。

root/
 ├ lib/
 │ └ SparkFun_MPU-9250-DMP_Arduino_Library-master/
 │     ├ src/
  │     │  ├ util/
  │     │  ├ MPU9250_RegisterMap.h
  │     │  ├ SparkFunMPU9250-DMP.cpp
  │     │  └ SparkFunMPU9250-DMP.h
  │     ├ LICENSE.md
  │     ├ README.md
  │     ├ keywords.txt
  │     └ library.properties
 └ src/
   └ main.cpp

ライブラリ化されているのでI2Cがどうとか気にせず加速度センサなどの値を読み取ることができます。

DMPを使ってクォータニオンの値をシリアルモニタに表示するExampleが
examples/MPU9250_DMP_Quaternion/MPU9250_DMP_Quaternion.ino
にあるので、全コピーしてmain.cppに貼り付けます。しかし、ペーストしてもコンパイルエラーが出るので以下を直します。

宣言の修正

ExampleがArduino用にに書かれているので、24行目辺りを以下のように直します。

main.cpp
#include <SparkFunMPU9250-DMP.h>

-#define SerialPort SerialUSB
+#define SerialPort Serial
+void printIMUData(void);

MPU9250_DMP imu;

minの定義

ビルドすると以下のようなエラーが出ます。

.pioenvs\m5stack-core-esp32\lib7f8\libSparkFun_MPU-9250-DMP_Arduino_Library-master.a(inv_mpu.c.o):(.literal.mpu_set_sample_rate+0x0): undefined reference to `min'
.pioenvs\m5stack-core-esp32\lib7f8\libSparkFun_MPU-9250-DMP_Arduino_Library-master.a(inv_mpu.c.o): In function `mpu_set_sample_rate':
inv_mpu.c:(.text.mpu_set_sample_rate+0x7c): undefined reference to `min'
.pioenvs\m5stack-core-esp32\lib7f8\libSparkFun_MPU-9250-DMP_Arduino_Library-master.a(inv_mpu.c.o): In function `mpu_load_firmware':
inv_mpu.c:(.text.mpu_load_firmware+0x43): undefined reference to `min'
collect2.exe: error: ld returned 1 exit status
*** [.pioenvs\m5stack-core-esp32\firmware.elf] Error 1

minという関数の定義が無くundefined referenceとなってしまいます。
よくよく見るとinv_mpu.cのL27からのコメントに

inv_mpu.c
/* The following functions must be defined for this platform:
 * i2c_write(unsigned char slave_addr, unsigned char reg_addr,
 *      unsigned char length, unsigned char const *data)
 * i2c_read(unsigned char slave_addr, unsigned char reg_addr,
 *      unsigned char length, unsigned char *data)
 * delay_ms(unsigned long num_ms)
 * get_ms(unsigned long *count)
 * reg_int_cb(void (*cb)(void), unsigned char port, unsigned char pin)
 * labs(long x)
 * fabsf(float x)
 * min(int a, int b)
 */

と書いてあり、minの定義が必要だと書かれています。

min(int a, int b)はaとbの値の小さい方を返す関数と思われます。
inv_mpu.cがincludeしているArduino.hのL187に

Arduino.h
#define _min(a,b) ((a)<(b)?(a):(b))

という同等の定義があるので、これを流用できるようinv_mpu.cのL39辺りに以下の定義を追加します。(3rdパーティのライブラリに自分で手を入れるのは好ましいことではありませんが、こういう場合は仕方ないでしょう。)

inv_mpu.c
#include <Arduino.h>
+#ifndef min
+#define min _min
+#endif
#define MPU9250

これでビルドできるようになるはずです。

2.3 シリアルモニタでの確認

コードのビルドと書き込み後、vscode下部のコンセントみたいなマークをクリックするとシリアルモニタが開けるのでExampleの出力を確認できます。文字化けしている場合はplatformio.iniの末尾にmonitor_speedの設定を加えてください。

platformio.ini
[env:m5stack-core-esp32]
platform = espressif32
board = m5stack-core-esp32
framework = arduino
+monitor_speed = 115200

シリアルモニタが起動できない場合はvscodeを再起動しましょう。
シリアルモニタはコンソール右上のごみ箱のボタンから閉じるのが正しいようです。

これでクォータニオンの値が表示されるようになりました。
無題.png

2.4 補足

キーンとうるさい場合はM5Stackをコードから抜いて電源ボタンを2回押すと電源が切れます。1回押しや長押しだと再起動なので切れません。

3. おわりに

GitHubのリンクです。naninunenoy/m5stack_imu_notifier
各センサデータ+クォータニオンをBLEで飛ばしたり出来れば、やれることの幅が広がりそうですね。

naninunenoy
Unity c#/Swift
moff
介護施設、リハビリ施設用向けアプリを開発・運営するIoTスタートアップ
https://jp.moff.mobi/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした