こんにちは。えーちゃんです。
M5Stackでミニカーを作る過程紹介第2弾ということで、今回はM5Stackの画面にアバターを表示していきます。
世の中の匠な方の中では、M5Stackの画面にアバターを表示したミニロボットを作るのがトレンドだそうです。
ミニカーの機能には全く関係ないですが、ライブラリの使い方の練習としてかわいいのでアバター表示してみましょう。
また実装にあたりちょっと困ったことがあって、同じ現象に遭った人の助けになれば幸いです。
環境
M5Stackの種類はM5GO、開発環境はPlatformIO IDEです。
プロジェクトの作成
アバター表示用のプロジェクトを作成しましょう。
プロジェクトの作り方や簡単なプログラムの動かし方は前回記事にまとめていますのでこちらをご参照ください!
ライブラリの追加
M5Stackのモニタにアバターを表示するためのライブラリ「M5Stack-Avatar」と、
M5シリーズを動かすためのライブラリ「M5Unified」をプロジェクトに追加しましょう。
どちらもPlatformIOのライブラリ管理機能から追加できます。
「M5Unified」は様々なM5シリーズを動かすために使える汎用ライブラリです。
サポートの都合上「M5Stack-Avatar」を使う際は「M5Stack」ライブラリではなくこちらを使います。
またPlatformIOでは各プロジェクトフォルダは独立した環境になっていて、過去に使ったことのあるライブラリでも
新しくプロジェクトを作ったらまた追加する必要があります。
M5Stack-Avatarのgithubリンクはこちらです
github.com
顔を表示するコード
ライブラリのフォルダの中にサンプルコードがあるのでそのまま使っていきましょう!
プロジェクト内のライブラリの中身は.pio/libdeps/フォルダの中に入っています。
.pio/libdeps/m5stack-core-esp32/M5Stack-Avatar/examples/basics/basics.inoというファイルがあります。
これが基本のサンプルコードです。
ちなみに.inoというのはArduinoIDE用のファイルの拡張子です。そのままmain.cppにコピペしてあげればPlatformIOで動きます。
コードの中身を見ていきますが、説明いらないほど短いです。
#include <M5Unified.h> // M5シリーズを動かすためのプログラムを読み込みます。 #include <Avatar.h> // アバターを表示するだけのプログラムを読み込みます。 // アバターを表示するためのクラスを定義します。 using namespace m5avatar; Avatar avatar; void setup() { M5.begin(); // M5Stack本体の初期化をします。 avatar.init(); // アバターを描画します。 } void loop() { // ループ処理部分には何も書かなくても自動でアバターが描画され続けます。 }
これだけです。アバター表示用クラスのなかにループ処理中の動きも書かれているのでこれだけで使うことができます!
あとはビルドして、プログラムをM5Stackにアップロードしましょう。
アバターがふよふよしたり、まばたきしたりしてとってもかわいいです!
表情を変えてみよう
avatar.setExpression(m5avatar::Expression::Happy);と書くことでアバターの表情を変えられます。
全種の表情をローテーションさせてみます。
#include <M5Unified.h> #include <Avatar.h> using namespace m5avatar; Avatar avatar; void setup() { M5.begin(); avatar.init(); } void loop() { // 2秒ごとに表情を変えます。 avatar.setExpression(m5avatar::Expression::Happy); delay(2000); avatar.setExpression(m5avatar::Expression::Angry); delay(2000); avatar.setExpression(m5avatar::Expression::Sleepy); delay(2000); avatar.setExpression(m5avatar::Expression::Sad); delay(2000); avatar.setExpression(m5avatar::Expression::Doubt); delay(2000); avatar.setExpression(m5avatar::Expression::Neutral); delay(2000); }
おしゃべりさせてみよう
M5Stackにアバターが表示できて嬉しい限りですがまだまだ終わりません。
続いてアバターにおしゃべりさせてみましょう。
M5Stack上で動かすことができる合成音声ライブラリAquesTalk ESP32を使って、M5Stackを喋らせることができます。
AquesTalk は株式会社アクエストが販売している合成音声ライブラリです。
無料で使用することができる評価版を使っていきます。評価版はマ行とナ行が全て「ヌ」になる制限がありますが、
ライセンスを購入することで制限を解除できます。
ライブラリのダウンロード
AquesTalkはPlatformIOのライブラリ管理機能から利用することができません。
以下の公式サイトから直接評価版プログラムをダウンロード+解凍しましょう。
https://www.a-quest.com/products/aquestalk_esp32.html
ライブラリを使うための準備
.pio/libdeps/m5stack-core-esp32/M5Stack-Avatar/lib/AquesTalkTTSというフォルダがあります。
そっくりそのままプロジェクトフォルダのlibディレクトリにコピーします。
AquesTalkTTSフォルダの中にはAquesTalkTTS.hというヘッダファイル(変数や関数の名前を定義するファイル)と
AquesTalkTTS.cppというソースファイル(プログラム本体)が含まれています。
これらをプロジェクトのlibディレクトリに置いておくことでライブラリとして扱えるようになります。
同じ名前のファイルがダウンロードしてきたAquesTalkESP32フォルダにもあり、そちらを使っても大丈夫です。
続いてダウンロードしたAquestalk ESP32の中身をプロジェクトフォルダの中に配置していきます。
src/esp32/libaquestalk.a とsrc/aquestalk.hを以下のように配置しましょう。
libaquestalk.a libフォルダへ
aquestalk.h プロジェクト直下のlib/AquesTalkTTSフォルダへ
最終的にこんな感じになっていればOKです
libaquestalk.aはAquesTalkの本体です。AquesTalkTTSのようなソースコードでなくてすでにビルドされた状態です。
このような.a形式のファイルを扱うためには、プロジェクトフォルダの中にあるplatform.iniに以下のように付け足す必要があります。
これはlibaquestalk.aを使うための記述です。
build_flags = -laquestalk -Llib/
微修正
※2023年3月7日現在の状況です。将来的に改善される可能性もあります。
このままでは動かない部分があるので微修正していきます。
まず、.pio/libdeps/m5stack-core-esp32/M5Stack-Avatar/src/tasks/LipSync.hを開きます。
24行目を以下のように修正します。min関数に与える引数の型を修正しています。
【修正前】
float open = min(1.0, f);
【修正後】
float open = min(1.0f, f);
こちらを修正したら、一度main.cppの適当な行に#ifdef IDF_VERと打ってみてください。
VSCode上でIDF_VERにカーソルを合わせると、 IDF_VERに入っている値を見ることができます。
変数IDF_VER何かしらの値が変数に入っていた場合は次の修正も行なってください。図のようになった場合修正が必要です。
この機能を使うためにはVSCodeにC/C++拡張機能が入っている必要があります。
次に先ほどコピペしたlib/AquesTalkTTS/AquesTalkTTS.cppを開きます。
213行目を以下のように修正します。
【修正前】
.communication_format = (i2s_comm_format_t)I2S_COMM_FORMAT_I2S_MSB,
【修正後】
.communication_format = (i2s_comm_format_t)I2S_COMM_FORMAT_STAND_MSB,
こちらはスピーカーとM5Stack基板の通信方法を指定する部分なのですが、
M5Stackの基板であるESP32のバージョンが1系か2系かによって通信方法が異なります。
1系の通信方法がI2S_COMM_FORMAT_I2S_MSB、2系の通信方法がI2S_COMM_FORMAT_STAND_MSBです。
この通信方法の指定が間違っていると、エラーはでないのにM5Stackが喋らない、口パク状態になります。
この現象の原因がわからなくて苦労しました。エラーがでない不具合って一番厄介ですよね・・・
以下のサイトに今回の現象について詳細な解説がありとても助かりました。興味ある方はご覧ください。
Arduino-ESP32 ver2でもI2S経由で内蔵DACを利用 - Qiita
おしゃべりさせるコード
これでようやくM5Stackを喋らせる準備が整いました。
.pio/libdeps/m5stack-core-esp32/M5Stack-Avatar/examples/talk/talk.inoを開き、中身をそのままmain.cppにコピペしましょう。
Aボタンを押すと「こんにちは」としゃべってくれるプログラムです。
吹き出しがでたり、アバターの口が動いたりととてもかわいいです。
#include <AquesTalkTTS.h> // AquesTalkをESP32で使うためのプログラムを読み込みます。 #include <Avatar.h> // アバター表示用プログラムを読み込みます。 #include <M5Unified.h> // M5Stackを操作するためのプログラムを読み込みます。 #include <tasks/LipSync.h> // セリフに合わせてアバターの口を動かすプログラムを読み込みます。 using namespace m5avatar; // AquesTalkのライセンスキーを入力します。ライセンスがある場合はライセンスキーを入力します。 // ライセンスキーがない場合は適当な文字列を入力します。 const char* AQUESTALK_KEY = "XXXX-XXXX-XXXX-XXXX"; Avatar avatar; void setup() { int iret; M5.begin(); // M5Stackを初期化します。 iret = TTS.create(AQUESTALK_KEY); // アバターを喋らせるためのクラスを定義します。 M5.Lcd.setBrightness(30); // M5Stackの画面明るさを設定します。 M5.Lcd.clear(); // M5Stack画面を初期化します。 avatar.init(); // アバターを描画します。 avatar.addTask(lipSync, "lipSync"); // セリフに合わせて口を動かすよう設定します。 } void loop() { M5.update(); // M5Stack本体の情報を取得します。 if (M5.BtnA.wasPressed()) { // ボタンAが押されたとき TTS.play("konnichiwa", 80); // 「こんにちは」と速度80でいいます。 avatar.setSpeechText("Hello"); // セリフの吹き出しを表示します。 delay(1000); // 1秒待ちます。(これをいれないと吹き出しがすぐ消えてしまいます。) avatar.setSpeechText(""); // セリフの吹き出しを消します。 } }
ここまで読んでいただき、ありがとうございました。
今回の内容は以上です。このアバターを表示するだけですごいかわいいしテンションが上がります。
ぜひみなさまもM5Stack-Avatarとともに良きM5Stack ライフをお過ごしください!
次回はモーター編です。モーターを回したりミニカーを組み立てたりしましょう。
宣伝!
弊社で開催しているデータサイエンティスト養成講座第七期が現在受講生募集中です。
こちらはAIってなんなの?使ってみたいけどよくわからないよ??という方向けの半年間の講座です。
わたしも前職まではAIよくわからん!って感じだったのですがこちらの講座を受けてなんとか仕事ができています。
機械学習やAIの基礎を勉強し、最終的には受講生のグループに分かれた開発演習を行います。
AIって何?という全くの初心者でも、自分でデータを集めてモデルを組めるようになれたと好評の講座です。
もし気になる!という方がいらっしゃいましたら下記講座HPからを詳しい内容を見てみてください!