「師匠、師匠、師匠〜!」「どうした、魔法使いの弟子よ」
「師匠! 魔法の杖を見つけました」
「ほほう」
「ですが魔法が切れているんです」
「では魔法を復活させるとしよう」
舞浜謹製「魔法の杖」
こちらの魔法の杖、imagemagickの杖と違って現在は魔法らしき現象は発生しません。
中身には単色LEDがいくつかと赤外線LEDと赤外線センサーとマイコン魔法装置が入っております。
発売当時は舞浜魔法の国の中に赤外線通信魔法ポイントが何ヶ所かあり、そこで通信魔法が働くと杖の内部NVRAMに魔法の痕跡が残るものとなっておりました。
魔法を再注入
というわけで、ここにesp32を入れて魔法を仕込みます。
- 単色LEDをマイコン内蔵RGB LED (WS2812Bなど) に交換
- 別のデバイスとBLE通信を行い、色の同期をする
- 9軸IMUを組み込み、TensorFlow Lite for Microcontrollersによるエッジ機械学習(推論)によりジェスチャーを検出する
レシピ
原料
| 部品 | 調達方法例 | 数量 | 概算価格(1台あたりJPY) |
|---|---|---|---|
| 魔法の杖 | (魔法使いの弟子が見つけてくる) | 1 | |
| XIAO ESP32C3 | Seeed Studio XIAO ESP32C3: 開発ツール・ボード 秋月電子通商-電子部品・ネット通販 | 1 | 1000 |
| マイコン搭載LED (5mm砲弾型) | マイコン内蔵RGBLED 5mm PL9823-F5: オプトエレクトロニクス 秋月電子通商-電子部品・ネット通販 | 6 | 300 |
| マイコン搭載LED (表面実装済みモジュール) | マイコン内蔵RGBLEDモジュール: オプトエレクトロニクス 秋月電子通商-電子部品・ネット通販 | 3 | 200 |
| マイコン搭載型IMU | Amazon.co.jp: ICM-20948 ICM20948 家庭用製品および時間位置追跡用の低電力 9 軸モーション センサー モジュール : 産業・研究開発用品 | 1 | 1200 |
| スライドスイッチ | スライドスイッチ 1回路2接点 パネル用: 制御部品・駆動部品 秋月電子通商-電子部品・ネット通販 | 1 | 50 |
| プッシュスイッチ | タクトスイッチ(赤色): 制御部品・駆動部品 秋月電子通商-電子部品・ネット通販 | 1 | 50 |
| 電池 | ICR14500-T PKCELL リチウムリチャージブルバッテリー ICR14500 トップタイプ | 1 | 400 |
| 深圳製基盤(上下2種類) | PCBプロトタイプ&PCBファブリケーションメーカー - JLCPCB | 上下各1 | 300 |
| スプリングピンヘッダ | コンスルー | 2 | 500 |
| 配線材料など | ご家庭の冷蔵庫に余っているものから | ||
| 合計 | (どんぶり勘定) | 4000 |
道具
- tensorflowで機械学習できる計算機
- 家庭用はんだリフロー装置
- リチウムイオン電池用充電モジュール
- BGM: デュカス「魔法使いの弟子」
ハードウェアのポイント
XIAO ESP32C3
XIAOシリーズは小さい上にLiPoから給電ができます。今回はc3ですがc6やs3でもいいでしょう。
IMU ICM2048
BMX055でもいいのですが、Madgwickを全力で回すにはESP32C3では少々心許ないです。
マイコンを内蔵し、Quaternionを簡単に教えてくれるタイプ(BNO055やICM20948)を使用します。
Quatanionは傾斜角によって光り方を変えるために利用していますが、esp32s3, esp32c6といったより高速なESP32を利用する、Quaternionは不要で9軸だけあればいい、エッジ機械学習推論はしない、といった場合ならBMX055でも十分でしょう。
残念ながら、がいためIMUはサイズ的に乗りません。
もし載せた場合、海外の魔法の国に持ち込む場合は法的な手続きが必要となりますね![]()
スライドスイッチ SS-12F16G6
秋月にある中で、この杖の穴にプロコフィエフフィット1するのはこの型番となります。
横のパネル取り付け用の羽根はカットします。
電池 ICR14500
単3サイズですので電池ボックスがそのまま流用できます。
ポリスイッチを挟んで、XIAO ESP32の裏面にある電池用パッドに繋げます。
XIAOでも充電はできるようですが、充電完了表示がなくて怖いので普通のLiION充電器を使用しました。
間違ってもエネループ充電器には入れないように。
スプリングピンヘッダ 2.54mmピッチ2.5mm高
自作キーボード界隈でいうところの「コンスルー」です。
今回は組み込む場所が非常に狭いので、low-profileソケットでも苦労します。
半田で直結してもいいのですが、メンテナンスを考えて採用したのが半田付け不要のこちら。
自作キーボード店の遊舎工房にある2.5mmモデルがXIAO esp32c3の裏向きにちょうど良い高さです。
基盤
元の基盤のサイズをノギスで測りながらkicadをグリグリし、みんな大好き世界の電子工作屋台骨JLCPCBにお願いして作成。10cmを超えるのでちょっとお値段は上がります。
下部LEDはオリジナルと同じ形で作成し、4足LEDのディジーチェーンをします。
上部LEDは表裏両面にチップLEDの手はんだ用モジュールを使っています。片面だけなら自分で表面実装LEDをこんがり焼き上げてもいいのですが、両面となると家庭用リフロー環境では困難です。
仕込み
頑張って杖の中に仕込みます。
微妙に寸法がオーバーして閉じないくて、ここが一番苦労しました...
ソフトウェア
状態遷移
コントロールスレッドとLED制御スレッドを作り、状態遷移させていきます。
LEDスレッドにはxQueueで「次はこの色に何秒で変化してね」「下から上に色を変化」等のコマンドを送りつけます。
BLE通信
protobufなどではなく単純なstructでやり取りします。
色の情報を直接通信させようとするとRGBで24ビットもありますが、乱数のシードを交換することで通信量を削減できます。
乱数も暗号化に使うわけではありませんので、簡単なもので十分です。
エッジ機械学習
TensorFlow Lite for Microcontrollersの古いバージョンには、その名もずばりmagick_wandというexampleがございます。
最新のものとはAPIの書式が違いますが、基本的な構造について参考になります。
今回は1D-CNNに6軸(地磁気を除く)を入れてみました。
基本的な流れは他の事例と同じです。
- esp32側で学習データサンプリングモードを作り、IMUの出力をwifi経由でsyslogとして出すようにする。ボタンを押している間はラベルが1、そうでない時は0とし、タイムスタンプ+6軸の数値を出す。(リアルタイムで出力するとロスするので、メモリに貯めて適度にバッファリング。サンプリングレートを記録しておく)
- 杖を手に持ち、ボタンを押してモーション動作をする、ボタンを離してモーションではない動作をする、を繰り返して学習データを作成(杖を握る角度や左手右手、速度、もつ場所など変更しながら何度も踊る。シュールな光景である(笑)。できれば複数の人間で行う)
- (ここから11までPC上での作業) syslogから学習用データのもととなるcsvを作成
- csvに対して拡張処理を施す
- 2〜4の作業をモーションの数だけ繰り返す
- 各モーションに数値を割り当て、全てのcsvを一つのファイルに連結する
- tensorflowで機械学習し、kerasのモデル(
model.keras)と正規化で使ったパラメータを出力する(json) -
keras.modelを量子化してmodel.hのヘッダー形式に変換 - 正規化のパラメータもヘッダー形式として保存
- esp32の推論プログラムを書き(時刻x計測値の2次元なリングバッファに記録、定期的に
interpreter->Invoke()にかける)、model.hと正規化パラメータを#includeしてコンパイルする - OTAでesp32に書き込む
- esp32の電源を入れ、杖を手に持って人間が踊る
- うまくいかなければ、tensorflowのモデルを書き換えて機械学習からやり直し(step1.のサンプリングレートと推論実行時のサンプリングレートが異なる場合、両者を揃える)
となります。 雑なモデルでもモーション3種類程度なら結構いけますが、精度を求めて試行錯誤するのも楽しいものです。
esp32c3はフラッシュが4MBしかありません。
tflite::AllOpsResolverは諦めて必要なものだけリンクする形で、no_fs設定でかろうじて収まるくらいのテキストサイズとなりました。
これ以上となるとesp32s3 (8MB)などに変更するかOTAを諦める必要があります。
モデルのダイエットについてはこちらが参考になりました。
免責事項・謝辞
舞浜に持ち込んで手荷物検査で押収されるかどうかはわかりません。
このような改造アイテムを販売すると知財上の問題が発生することがあります。詳しくは「知的財産権 リメイク」などで検索してください。
これら及びこれら以外の問題も含めて、本記事の筆者は何ら責任を負いません。
リンク先など参考にさせていただいた資料、プログラム等の作者の皆様に感謝いたします。


