ImageAvatarLitePlus for M5Stack Core2 and M5Stack Fire
ImageAvatarLiteは右目のパーツを使って、左目を反転表示させます。したがって、同じ目しか表現できません。ImageAvatarLitePlusではパーツ数が増えますが、左右の目を異なるデザインで表示することが可能です。
ドキュメントも行き届いていません。その点はご了承ください。
あらかじめ用意した画像ファイル(BMP)とJSONファイルの設定を組み合わせてAvatarを作成できるアプリです。
- VSCode(Ver.1.55.1)
- PlatformIO
srcフォルダとmain.cppの名前を揃えて変更してください。
src -> M5Core2ImageAvatarLitePlus
main.cpp -> M5Core2ImageAvatarLitePlus.ino
Arduino-esp32はVer.2.0.3で動作確認しています。
バージョンについてはplatformio.iniを見てください。
メモリの都合上PSRAMが必要なのでM5Stack Core2とM5Stack Fireのみを対象にしています。 4bitBMPを使用し、カラーパレットを使用することにより他の機種でも動きますが手順が複雑なのでCore2及びFireのみとします。
- SDカードのルートにdataにあるフォルダ(bmp,json)をコピー
- jsonフォルダの下記の2ファイルを設定します。
- M5AvatarLitePSystem.json
- M5AvatarLitePServo.json
- プログラムを書き込むとAvatarが起動します。
- Bluetoothスピーカーとして機能します。「ESP32」というデバイスをペアリングすると音を再生可能です。
- ボタンA
- クリック
アバターの切り替え - 長押し
サーボテスト
- クリック
- ボタンB
- クリック
ボリュームアップ - 長押し
サーボ駆動のON/OFF切り替え
- クリック
- ボタンC
- クリック
ボリュームダウン - 長押し
アバターの表情切り替え
- クリック
dataフォルダ内にあるファイル及びフォルダをSDカードのルートにコピーしてください。
-
- /bmp_slime/
BMPファイル(サンプルのbmp_slimeでは全部で11ファイル) - /bmp_puipui/
- /bmp_jacko/
- /bmp_slime/
- /json/
- M5AvatarLitePSystem.json
一番最初に読み込まれる設定ファイル - M5AvatarLiteP00.json
顔文字アバターの設定ファイル - M5AvatarLiteP01.json
TAという顔のの設定ファイル - M5AvatarLiteServo.json(※サーボを使う場合)
- M5AvatarLitePSystem.json
main.cppの下記の行を変更するとJSONファイルとBMPファイルの収納場所をSDかSPIFFSか指定できます。SPIFFSに置くと開発するときにVSCodeからUploadできるようになり、SDカードを抜き差しして書き換える手間が省けます。
fs::FS json_fs = SD; // JSONファイルの収納場所(SPIFFS or SD)
fs::FS bmp_fs = SD; // BMPファイルの収納場所(SPIFFS or SD)
ESP32 with VS Code and PlatformIO: Upload Files to Filesystem (SPIFFS)
一番最初に読み込まれる設定ファイルです。サンプルでは3つまで定義してあります。(最大8つ)
{
"volume" : 100, // 起動時のボリューム
"lcd_brightness" : 50, // LCDの明るさ
"avatar_json": {
"filename" : [
"/json/M5AvatarLiteP00.json", // countで設定した数に対応するAvatar定義を作成
"/json/M5AvatarLiteP01.json",
"/json/M5AvatarLiteP02.json" // 3つ以上増やすときは末尾に「,」を追加
// .... ,
// .
// "/json/M5AvatarLite07.json" // 最大8まで
]
},
"bluetooth_device_name" : "ESP32", // Bluetoothスピーカーのデバイス名
"bluetooth_reconnect" : false, // 起動時にBluetoothを再接続するかどうか(接続先が変わる場合はfalse推奨)
"servo_json" : "/json/M5AvatarLiteServo.json", // サーボの設定ファイル
"servo_random_mode" : true, // 起動時にサーボを動かすかどうか
"auto_power_off_time" : 0, // USBからの電源供給が止まった後にCore2の電源を切るまでの時間(0は電源OFFしません。)
"led_lr" // GoBottomのLEDBarをステレオで表示するかの切り替え(0:Stereo, 1:LeftOnly, 2:RightOnly)
}
自分で24bitか16bitのBMPファイルを用意すると好きな画像をAvatar化することが可能です。
サンプルの画像ファイルは全て24bitBMPファイルでWindows標準のペイントソフトを利用しています。
開いた状態と閉じた状態の2種類×表情の数だけ必要です。(デザインが同じ場合は流用も可能)
目と口の透明化したい部分は透明色(M5AvatarLiteConfig.json)で塗りつぶします。サンプルでは緑(0x00FF00)になっています。
下記を参考にして、JSONファイルを書き換えてください。
{
"expression": [ // 表情(デフォルトは最大8パターンまで)
"normal",
"laugh",
"cry",
"sleepy"
],
"sprite_info": {
"psram": "true", // PSRAMの使用有無(8bit以上ではtrueのまま)
"color_depth": 16, // 使用するBMPのColorDepth
"swap_bytes": 0 // Swap_bytes
},
"color_info": {
"skin" : "0xFF5B00", // 肌の色(未使用)
"eye_white" : "0xFFFFFF", // 白目の色(未使用)
"transparent" : "0x00FF00" // 透明色(sampleでは緑)
},
"fixed_parts": [ // 固定用パーツ(背景のみ)
{
"parts": "head",
"x": 0, // 頭部パーツの描画開始X座標
"y": 0, // 頭部パーツの描画開始Y座標
"w": 320, // 頭部パーツの幅
"h": 240, // 頭部パーツの高さ
"filename": "/bmp_kaomoji/head.bmp" // 頭部パーツのファイル名
}
],
"mouth": [ // 口のパーツ設定(表情の数だけ必要)
{
"normal": { // 表情 normal
"x": 160, // 口パーツの描画中心X座標
"y": 190, // 口パーツの描画中心Y座標
"w": 72, // 口パーツの幅
"h": 72, // 口パーツの高さ
"filename": {
"open": "/bmp_kaomoji/mouth_op_normal.bmp", // 開いた口
"close": "/bmp_kaomoji/mouth_cl_normal.bmp" // 閉じた口
},
"minScaleX": 1.0, // 未使用
"maxScaleX": 1.0, // 未使用
"minScaleY": 0.3, // Y軸の拡大率がこれ以上小さくなると閉じる
"maxScaleY": 1.0 // 未使用
}
},
{
"laugh": { // 口のパーツ設定(laugh)
"x": 160,
"y": 190,
"w": 72,
"h": 72,
"filename": {
"open": "/bmp_kaomoji/mouth_op_laugh.bmp",
"close": "/bmp_kaomoji/mouth_cl_normal.bmp"
},
"minScaleX": 1.0,
"maxScaleX": 1.0,
"minScaleY": 0.3,
"maxScaleY": 1.0
}
},
{
"cry": { // 口のパーツ設定(cry)
"x": 160,
"y": 190,
"w": 72,
"h": 72,
"filename": {
"open": "/bmp_kaomoji/mouth_op_cry.bmp",
"close": "/bmp_kaomoji/mouth_cl_cry.bmp"
},
"minScaleX": 1.0,
"maxScaleX": 1.0,
"minScaleY": 0.3,
"maxScaleY": 1.0
}
},
{
"sleepy": { // 口のパーツ設定(sleepy)
"x": 160,
"y": 190,
"w": 72,
"h": 72,
"filename": {
"open": "/bmp_kaomoji/mouth_op_sleepy.bmp",
"close": "/bmp_kaomoji/mouth_cl_normal.bmp"
},
"minScaleX": 1.0,
"maxScaleX": 1.0,
"minScaleY": 0.3,
"maxScaleY": 1.0
}
}
],
"eye_r": [ // 右目パーツの設定(設定内容は口と一緒)
{
"normal": {
"x": 80,
"y": 120,
"w": 72,
"h": 72,
"filename": {
"open": "/bmp_kaomoji/eye_r_op_normal.bmp",
"close": "/bmp_kaomoji/eye_r_cl_normal.bmp"
},
"minScaleX": 1.0,
"maxScaleX": 1.0,
"minScaleY": 0.3,
"maxScaleY": 1.0
}
},
{
"laugh": {
"x": 80,
"y": 120,
"w": 72,
"h": 72,
"filename": {
"open": "/bmp_kaomoji/eye_r_op_laugh.bmp",
"close": "/bmp_kaomoji/eye_r_cl_laugh.bmp"
},
"minScaleX": 1.0,
"maxScaleX": 1.0,
"minScaleY": 0.3,
"maxScaleY": 1.0
}
},
{
"cry": {
"x": 80,
"y": 120,
"w": 72,
"h": 72,
"filename": {
"open": "/bmp_kaomoji/eye_r_op_cry.bmp",
"close": "/bmp_kaomoji/eye_r_cl_cry.bmp"
},
"minScaleX": 1.0,
"maxScaleX": 1.0,
"minScaleY": 0.3,
"maxScaleY": 1.0
}
},
{
"sleepy": {
"x": 80,
"y": 120,
"w": 72,
"h": 72,
"filename": {
"open": "/bmp_kaomoji/eye_r_op_sleepy.bmp",
"close": "/bmp_kaomoji/eye_r_cl_normal.bmp"
},
"minScaleX": 1.0,
"maxScaleX": 1.0,
"minScaleY": 0.3,
"maxScaleY": 1.0
}
}
],
"eye_l": [ // 左目の設定(設定内容は口と一緒)
{
"normal": {
"x": 240,
"y": 120,
"w": 72,
"h": 72,
"filename": {
"open": "/bmp_kaomoji/eye_r_op_normal.bmp",
"close": "/bmp_kaomoji/eye_r_cl_normal.bmp"
},
"minScaleX": 1.0,
"maxScaleX": 1.0,
"minScaleY": 0.3,
"maxScaleY": 1.0
}
},
{
"laugh": {
"x": 240,
"y": 120,
"w": 72,
"h": 72,
"filename": {
"open": "/bmp_kaomoji/eye_r_op_laugh.bmp",
"close": "/bmp_kaomoji/eye_l_cl_laugh.bmp"
},
"minScaleX": 1.0,
"maxScaleX": 1.0,
"minScaleY": 0.3,
"maxScaleY": 1.0
}
},
{
"cry": {
"x": 240,
"y": 120,
"w": 72,
"h": 72,
"filename": {
"open": "/bmp_kaomoji/eye_r_op_cry.bmp",
"close": "/bmp_kaomoji/eye_r_cl_cry.bmp"
},
"minScaleX": 1.0,
"maxScaleX": 1.0,
"minScaleY": 0.3,
"maxScaleY": 1.0
}
},
{
"sleepy": {
"x": 240,
"y": 120,
"w": 72,
"h": 72,
"filename": {
"open": "/bmp_kaomoji/eye_r_op_sleepy.bmp",
"close": "/bmp_kaomoji/eye_r_cl_normal.bmp"
},
"minScaleX": 1.0,
"maxScaleX": 1.0,
"minScaleY": 0.3,
"maxScaleY": 1.0
}
}
],
"init_param": [ // 最初に描画されるときの設定(特に変更の必要はありませんが表情の数必要です。)
{
"normal": {
"eye_l_ratio": 0.0, // 左目を開く倍率
"eye_r_ratio": 0.0, // 右目を開く倍率
"mouth_ratio": 0.0, // 口を開く倍率
"angle": 0.0, // Avatarの角度(左右に傾きます)
"breath": 0 // Avatarが息遣いする高さ
}
},
{
"laugh": {
"eye_l_ratio": 0.0,
"eye_r_ratio": 0.0,
"mouth_ratio": 0.0,
"angle": 0.0,
"breath": 0
}
},
{
"cry": {
"eye_l_ratio": 0.0,
"eye_r_ratio": 0.0,
"mouth_ratio": 0.0,
"angle": 0.0,
"breath": 0
}
},
{
"sleepy": {
"eye_l_ratio": 0.0,
"eye_r_ratio": 0.0,
"mouth_ratio": 0.0,
"angle": 0.0,
"breath": 0
}
}
]
}
main.cpp冒頭の#define USE_SERVOのコメントを外すとサーボを利用できます。2021/11現在ではスタックチャンでの利用を想定しています。
X軸とY軸の2軸(スタックチャンのパン(x)とチルト(y))で利用できます。/json/フォルダにM5AvatarLiteServo.jsonを置いてください。
{
"initial_settings": {
"x_axis": { // パン
"pin" : 13, // 水平方向のサーボピン番号
"center" : 85, // サーボの中心(初期位置)
"lower" : 0, // サーボの下限角度
"uppder" : 180, // サーボの上限角度
"offset" : 0 // サーボのオフセット
},
"y_axis": { // チルト
"pin" : 14, // 垂直方向のサーボ品番号
"center" : 60, // サーボの中心(初期位置)
"lower" : 30, // サーボの下限角度
"upper" : 90, // サーボの上限角度
"offset" : 0 // サーボのオフセット
}
},
"servo_enable" : "false" // 起動時にサーボを動かすかどうかのフラグ(未使用)
}
このソフトを作成するにあたり、動きや構造の元となったM5Stack-Avatarを作成・公開してくださったmeganetaaan氏に感謝いたします。
ImageAvatarを実現するにあたり優れたパフォーマンス、機能を持ったLovyanGFX,M5Unifiedの作者lovyan03氏に感謝いたします。
ImageAvatar作成するにあたり、 初期の頃からたくさんのアドバイスを頂き、参考にさせていただいたM5Stack_WebRadio_Avatarの作者robo8080氏に感謝いたします。
色々なアドバイスを頂いたtobozo氏に感謝いたします。