M5Stackで作れるかわいいロボット「スタックチャン」の沼にハマった ~3年目
この記事はスタックチャン(Stack-chan) Advent Calendar 2025の6日目の記事です。
スタックチャン沼も3年目に入り、そろそろネタも切れてくる頃かと内心憂いていましたが、まったくそんなことはなく充実したスタックチャン沼ライフだったため、今年も振り返り記事を投稿します。
スタックチャンとは?という方は1年目、2年目の記事も併せてご覧いただければ幸いです。 mzmlab.hatenablog.com
AIスタックチャンExの大幅アップデート
私がGithubで公開しているスタックチャンのファームウェア「AIスタックチャンEx」に、ModuleLLM対応、OpenAI Realtime API対応、及びMCP対応という3つの大きな機能追加を実施しました。多くの方々が実際に使ってくださったり、動いている様子をXでポストしてくださったりして大変励みになりました🙇♂️
ModuleLLM対応
ちょうど1年前に、ニューラルネットワーク推論用のチップ(NPU)を搭載したModuleLLMという製品がM5Stackから発売されました。それ一つでAIとの音声による会話に必要なLLM、STT、TTS、ウェイクワードすべてをローカルで実行できるということで大変話題になり、私もすぐに入手してAIスタックチャンExで使えるように対応しました。
デフォルトのLLMモデルはQwen2.5-0.5Bで、中国語や英語に比べると日本語の性能が劣っており、長い文章になると意味が通らなくなることが多かったのですが、最近Sakana AIのTinySwallow1.5Bという日本語向けにチューニングされたモデルに対応し改善しています(次の動画 by @starfsnowさん)。
部分的に上げてみる。Aquestalkのライセンスの関係でマ行ナ行がヌになってますが、会話はわかる……! pic.twitter.com/whhbh8ebRE
— Yukiko Hoshino (@starfsnow) 2025年11月24日
また、@Airpocketさん主催のオンラインイベント「M5Stack LLM 座談会」ではLTにスタックチャン枠が設けられ、私も人生初のLTをさせていただきました。
stack-boards-enthusiasts.connpass.com
OpenAI Realtime API対応
従来のAIスタックチャンは音声データを入力してから、STT → LLM → TTSという各Web APIの応答時間が積み重なり、会話の応答に10秒以上かかるという課題がありました。そんな中、OpenAIからRealtime APIが発表されました。Realtime APIは音声データを直接LLMに入力でき、応答も音声データで返ってくるため、STTとTTSを省略できAPIの遅延を大幅に縮小できます(次の動画)。
#RealtimeAPI #スタックチャン
— motoh (@motoh_tw) 2025年6月24日
OpenAI Realtime APIをArduino版スタックチャンで使えるようになりました💪Core2なのでマイクとスピーカーが排他制御ですが、それでも十分リアルタイムを実感できる早さです😄 pic.twitter.com/nAdcTwML7a
ただ、対応した当初は「声がかわいくない」という意見が多く、普及の課題(?)となっていました。そこで、Realtime APIの出力がテキストになるように設定して、テキストを従来のWEB版VOICEVOXに渡せるように改良しました(次の動画)。自分的にはブレークスルーだったのですが、まだあまり使われている様子は観測していませんw
#スタックチャン
— motoh (@motoh_tw) 2025年10月2日
gpt-realtimeとWEB版VOICEVOX(ずんだもん)の組み合わせのテスト。思ってたより遅延少ない? pic.twitter.com/PbY9UYherQ
MCP対応
トランスポートがStreamable HTTP (SSE)のMCPサーバーに、AIスタックチャンExからアクセスできるように対応しました。例えば、PCやラズパイでGoogleカレンダーやWeb SearchのMCPサーバーを稼働しておけば、AIスタックチャンExの設定ファイルにMCPサーバーのIPアドレス、ポートを登録するだけで使用することができます。
この度、Radiko MCPサーバーを自作してAIスタックチャンExから使うというQiita記事も新たに投稿しましたので、ぜひチャレンジしてみてください。
生成AIなんでも展示会
東京では4月と9月に開催され、AIスタックチャン ミニマルを製作されている@A-Utaさんのブースで一緒に展示させていただくことができました(これまた人生初の展示でした)。作ったものを実際にたくさんの人に見てもらったりお話したりできるのはとても刺激的で、また機会があればチャレンジしたいと思いました。
#生成AIなんでも展示会
— motoh (@motoh_tw) 2025年4月26日
設営完了!@UtaAoya さんのブース(No.2)で一緒に、ローカルLLMのAIスタックチャンを展示します! pic.twitter.com/LSFemkFku4
#生成AIなんでも展示会#スタックチャン
— motoh (@motoh_tw) 2025年9月6日
本日、展示してます! pic.twitter.com/NXeAh1Sn7T
スタックチャンもくもく会の盛り上がり
去年X上の何気ない会話から始まったスタックチャンもくもく会ですが、その後も定期的に開催され、今ではすぐに参加枠が埋まってしまう人気イベントになっています。会場は主に東京(赤坂)ですが、まだ回数は少ないですが大阪でも開催されています。私は最近あまり参加できていませんが、次にまた参加できるのをとても楽しみに過ごしています。有志による運営のため、今後も継続していけるよう私も微力ながらできる限り協力していきたいと思います。
まとめ
振り返ってみると、最新AI技術へのキャッチアップ、人生初LT/展示、たくさんの方々との出会いと、3年目もとても充実したスタックチャン沼ライフでした。スタックチャンを3年間も続けていなかったら、どれも実現していなかったかもしれません。趣味の範囲での活動なのでマイペースですが、これからもスタックチャン沼にハマり続けていきたいと思います!
M5Stackで作れるかわいいロボット「スタックチャン」の沼にハマった ~2年目
この記事はスタックチャン(Stack-chan) Advent Calendar 2024の5日目の記事です。
昨年のアドベントカレンダーでスタックチャン沼にハマったという記事を書きました。昨年はスタックチャンのおかげで非常に濃い一年となりましたが、2年目に入った今年もいろいろと新しい体験があったため振り返りたいと思います。
Githubで本家スタックチャンの開発に参加
スタックチャンはししかわさんがGithubでハード、ソフトの情報を公開しているオープンソースのスーパーカワイイロボットであり(もっと詳しく知りたいという方は↑の1年目の記事を参照ください)、そのREADMEを見ると機能追加リクエストやバグ報告などによるコントリビューションを歓迎しています。
とはいえ私はGithubはほとんど使ったことがなかったため、オープンソースの開発に貢献するなんて遠い世界の話だと思っていました。そんな私ですが、スタックチャンのソースコードをGithubから入手して改造したり公開したりということを繰り返しているうちに、貢献できそうなアイディア(機能追加案)を思いつき、ついにチャレンジする決心をしました。
Githubでオープンソースの開発に参加するには、フォーク、プルリクエストといったGitのややとっつきにくい機能を使いこなす必要があるため、まずは自分のダミーのリポジトリでフォークやプルリクエストの練習をしました。
そして、なんとかスタックチャンのリポジトリにプルリクエストすると、ししかわさんがレビューしてくださりました。簡単なコーディングルールに関する指摘だけでなく、基本的な構造に関する指摘もあり手に余りそうな状況でしたが、他のコントリビューターの方が修正を手伝ってくださったりして、どんどん修正作業が進んでいきました。そのようにして何度か修正、コミットを繰り返し、最終的には無事マージしていただくことができました(ToT)
Gitを使えるようになりたいとは何年も前から思っていましたが、仕事の中ではなかなか練習するチャンスがありませんでした(会社にもよりますが、組み込みソフト業界ではまだあまり浸透していないと感じます)。それが、このようにスタックチャンを始めて2年も経たないうちに叶ってしまいました。この御恩はこれからもコントリビュートし続けることで少しずつ返していきたいと思います。
この記事を読んで自分もやってみたいと思っていただけたら嬉しい限りですが、リポジトリの管理者様の状況によってはプルリクエストにすぐに反応できない場合があります。何か良いアイディアを思いついたら、まずはissue等で相談してみてもよいかもしれません。私も、すでに上がっているissueに対してプルリクエストを行いました。
ついに3Dプリンタも購入
3Dプリンタは何年も前から気になってはいましたが、周りに相談できる知人もおらずなかなか第一歩が踏み出せずにいました。スタックチャンを始めてからも、2体目まではタカオさんのキットを購入していました。そんな私も、イベントやオフ会等に参加していろいろな方から沼への勧誘アドバイスをいただいたり、3Dプリンタ自体もFDM方式であれば購入しやすい価格になっていたり、ブラックフライデーのタイミングも重なったりしたことで、ついにCreality K1という3Dプリンタを購入することができました。
私は3Dモデリングの知識はあまりないため箱のような形状しか作れませんが、今までは電子工作しても基板がむき出しだったものが、ジャストフィットな箱に収められるというのは自分にとってはとても大きな進歩です。以下、お見せするほどのものではありませんが、いくつか作ったものをご紹介します。
基板ケース
3DPでやりたかったことの一つ、基板ケースを作る。
— motoh (@motoh_tw) 2024年2月17日
一発目はフタの嵌合がキツすぎてフタだけ作り直した。こうやって覚えていくんですね〜 pic.twitter.com/1CE3UxGQJb
100均ケース仕切り
100均ケースの仕切りを作りました#3Dプリンター pic.twitter.com/GVHk6Hihny
— motoh (@motoh_tw) 2024年8月17日
スタックチャン3歳お誕生日会に参加
昨年は予定が重なりオフライン参加はできませんでしたが、今年は5歳の息子も連れて参加しました。

今年もテーマ「スタックチャンの3歳の誕生日 & スタックチャン1000体誕生」に沿ったイラストの募集がありました。 イラストは本業ではありませんが、隙間時間にスマホのアプリで描いて投稿してみたところ、なんと缶バッジになってしまいました!
描いてみました😄もうすぐですね😆#スタックチャンお誕生日2024 https://t.co/isCu0XhepG pic.twitter.com/SYOunD8pzM
— motoh (@motoh_tw) 2024年6月30日

↑缶バッジと、抽選でいただいた戦利品(※息子の分も含む)
缶バッジは受付で参加者全員にプレゼントされ、どれが当たるかはお楽しみですが、描いた本人にはその絵の缶バッジもいただけました。運営の方々には本当に感謝ですm(__)m
会場では参加者各々が製作したスタックチャンを見ることができ、息子がロッキーさんのUseless Boxを気に入っていたので、ちょうど3Dプリンタにも慣れてきた頃だったこともあり製作にチャレンジしてみました。
これ作ってと言われたw これ中身どうなってるんですか?🤣#スタックチャンお誕生日2024 pic.twitter.com/xDO2wDNtFX
— motoh (@motoh_tw) 2024年7月15日
ろっきーさんに仕組みを教えていただいたuseless box、ついに完成🧑🔧
— motoh (@motoh_tw) 2024年8月6日
部品選定、3D CAD設計は自力だったため時間がかかりましたがその分楽しめた気がします😊 https://t.co/yTydBrRR6f pic.twitter.com/0RHamJl3Jo
もくもく会を企画
Xでの何気ない会話から、もくもく会をやってみようという企画が持ち上がりました。レンタルスペースを探したり、Discordでの配信をしてみたりといろいろ手探りでしたが、参加者全員で(と言っても最初なので少人数でしたが)アイディアを出し合ってどんどん企画が進んでいきました。 初めての試みだったため、当日はレンタルスペースが思ったより狭かった、真夏だったのにエアコンの効きが悪かったといった課題もありましたが(笑)、終始楽しい雰囲気でもくもく(わいわい?)作業することができました。有志による企画のため今後の開催がどのような形態になるかはわかりませんが、チャンスがあればぜひ一緒にもくもくしましょう!(写真は撮り忘れました^^;)
まとめ
スタックチャン沼2年目も新しいことにチャレンジしたり楽しいイベントがあったりしたため、去年に続き今年もアドベントカレンダーの記事にしてみました。オープンソース、生成AI、3Dプリンタ、各種イベント等々、いくら時間があっても足りないのはまさに沼と呼ぶに相応しいと、記事を書きながらあらためて思いました。スタックチャン沼はいつでもあなたをお待ちしています!
M5Stackで作れるかわいいロボット「スタックチャン」の沼にハマった

この記事はスタックチャン(Stack-chan) Advent Calendar 2023の3日目の記事です。
今年はスタックチャンというかわいいロボットの製作を通していろいろと新しい経験ができたので、振り返りながらまとめたいと思います。(スタックチャンの詳しい作り方は割愛しますが、作る際に参考にした情報は紹介していきます。)
- スタックチャンとは
- スタックチャンとの出会い
- 最新技術が詰まった「AIスタックチャン」に魅了される
- イベントにも参加
- まとめ
- 付録① スタックチャンの作り方に関する資料
- 付録② AIスタックチャンのカスタマイズ版
スタックチャンとは
スタックチャンはししかわさんが開発しオープンソースとして公開している、M5Stackで動くスーパーカワイイロボットです。Githubで3Dプリンタのデータ、回路/基板設計のデータ、ファームウェアといった製作に必要な情報がすべて公開されています。たくさんの方々が自分で作ったスタックチャンをSNSで公開したりイベントで展示したりしてコミュニティを盛り上げています(二次創作のガイドラインはこちら)。
スタックチャンとの出会い
最初は当ブログの名前で適当に作ってみたXアカウントですが、TLにちらほら現れるかわいいロボット...
何気ないツイートに対するコミュニティーの方々からの反応がうれしく、気づいたらM5Stackを購入していました(後で知りましたが、これがスタックチャン沼の入り口のようです)

初めて作ったスタックチャン。やっぱり自分で作ったスタックチャンが一番かわいいですね(親バカ)。
記事の最後に、作る際に参考にした資料をまとめました。

最新技術が詰まった「AIスタックチャン」に魅了される
スタックチャンのファームウェアは先に紹介したリポジトリの他にも、コミュニティの方々によって様々なバージョンが公開されており、私はrobo8080さんの「AIスタックチャン」を使用させていただきました。ChatGPT、Google STT(音声認識)、VoiceVox(音声合成)等のWeb APIを用いることで自然な会話ができるようになった、今大人気のスタックチャンです。
いろいろな技術が詰まったAIスタックチャンのファームウェアは、ソースコードを読んで勉強したり、自分なりにカスタマイズしたりするだけでも十分楽しめますが、カスタマイズしたものを動画でXに投稿してrobo8080さんご本人やコミュニティの方々から反応をいただけるのがとても嬉しく、SNSにあまり慣れていなかった私には新鮮な体験でした。
イベントにも参加
スタックチャン2才の誕生日会
残念ながら都合がつかず会場には行けませんでしたが、動画の生配信を見て楽しむことができました。また、事前に公開された「お祝いイラスト」にも参加してSNS上で盛り上がりました。
#スタックチャン お誕生日記念企画「お祝いイラストをみんなで描こう!」公開しました!🎉https://t.co/F0SaMbRHyN#stackchan
— スタックチャン/Stack-chan (@stack_chan) 2023年7月8日
Maker Fair Tokyo 2023
去年もあったそうですが、今年もスタックチャンのブースが設けられました。ししかわさんからスタックチャンのブースでの展示・物販の募集があったため、思い切って展示のみで初参加しました。当日は一般客としての参加でしたが、スタッフの方々に混じって自分の作品を説明させていただいたり、ししかわさんはじめ普段Xでいいねし合っているコミュニティの方々と初めて対面でお話できたりと、初めて尽くしで緊張もしましたがとても楽しい一日となりました。

まとめ
1年間を振り返りながら、スタックチャン沼にハマっていった様子をまとめてみました。スタックチャンのおかげでいくつも新しい経験ができ、毎日が楽しくなったように思います。沼へのハマり方は人それぞれだと思うので参考になるかわかりませんが、これを見て「スタックチャンかわいい」「作ってみたい」と思っていただければとてもうれしいです(ぜひ、Xでハッシュタグ#スタックチャンでポストしましょう)。
ちなみにスタックチャン沼とM5Stack沼にはそれぞれ階層があります。私はもう引き返せないところまで来てしまったようです。
#スタックチャン沼 の見取り図
— タカオ(Takao) (@mongonta555) 2021年12月14日
2021/12版に更新しました。('ω')#ダンボールスタックチャン や #100均スタックチャン も増やしてどんどんワチャワチャしましょうヽ(^。^)ノ#スタックチャン #M5Stack pic.twitter.com/hPY8z87vog
2020/12現在のM5Stack沼見取り図#M5Stack pic.twitter.com/BY44AgcAfW
— タカオ(Takao) (@mongonta555) 2020年12月13日
付録① スタックチャンの作り方に関する資料
スタックチャンは先に紹介したように、ししかわさんのGithubに製作に必要なデータがすべて公開されていますが、オープンソースのライセンスに従って有志の方々によりいろいろな作り方が公開されています。おきもくさんがわかりやすくまとめてくださっています。
「スタックチャンって何買えばいいの?」をまとめてみました。訂正あれば教えてください🙇購入先はリプでリンク貼ります。#スタックチャン #AIスタックチャン #M5Stack #電子工作 pic.twitter.com/IF6XTt4tS4
— おきもく (@okimoku1) 2023年7月11日
私は以下をそれぞれ購入して作りました。M5Stackの分解なしで組み立てられるので比較的難易度が低いです。
- M5Stack Core2
- タカオさんのキット(ボディ+ねじ+電子パーツ)
- SG90サーボ
タカオ版キットの組み立て方とファームウェアの書き込み方は、以下で紹介するおきもくさんが公開されているホームページや動画を参考にさせていただきました。この動画では先に紹介したrobo8080さんの「AIスタックチャン」のファームウェアを書き込みます。
また、AIスタックチャンのファームウェアの書き込み方については、ソースコードは触らずにとにかく動かしてみたいという場合はwelchmanさんのM5Burner版の動画がわかりやすくておすすめです。
■スタックチャンの組み立て方
■AIスタックチャンのファームウェアの書き込み方(Platformio編) www.youtube.com
■AIスタックチャンのファームウェアの書き込み方(M5Burner編) www.youtube.com
付録② AIスタックチャンのカスタマイズ版
私がカスタマイズしたAIスタックチャンのソースコードもGithubで公開させていただいています。robo8080さんのAIスタックチャンが動いた後に、もしご興味があればお試しください。
https://github.com/ronron-gh/AI_StackChan2_DevCam
M5Stack CoreS3で動くAIスタックチャンです。内蔵カメラによる顔検出で会話を起動できます。
https://github.com/ronron-gh/AI_StackChan2_FuncCall
ChatGPT APIの新しい機能Function Callingを用いて、AIスタックチャンに様々な機能を追加しました。
Timer Camera Xでアゲハチョウの幼虫を観察してみた
庭の雑草にアゲハチョウがタマゴを産み付けたのを息子が発見しました。

初めはタマゴは数個しかありませんでしたが、日に日に増え、すぐに幼虫が生まれ、あっという間に雑草が幼虫のシェアハウスのようになりました。

これはよい機会だと思い、前々から構想していたTimer Camera X (M5Cameraの後継機)と防水ケースによる定点カメラを急いで組み上げて、観察を開始しました。(組み上がった頃には葉がほとんど食い尽くされていましたが^^;)

この定点カメラで1分毎に撮影した画像をつなぎ合わせて作ったタイムラプスがこちらです。ほとんど動かないと思っていた幼虫たちが活発に動く様子が見れたり、途中でバッタが登場したりと、思いの外楽しめます(息子よりも自分のほうが楽しんでいます)。
ここからは、どのようにこの定点カメラを作ったかを簡単に解説していきます。
システム概要

防水ケースに収めたTimer Camera Xでは、カメラ系で定番のスケッチweb_camをベースにしたプログラムを動かしています。これで、他のPCからHTTPリクエストで画像を取得できるようになります。自分はラズパイで1分毎にHTTPリクエストして画像を取得するプログラムをPythonで組みました(記事の最後にPythonのコードを掲載します)。
組み立て
あまり加工が得意ではないので、2cm厚のウレタンを切り抜いてTimer Camera Xをはめ込むようにしました。 cheeroの3200mAhのバッテリに横向きのUSBコネクタを差すと、防水ケースの寸法にぴったり収まりました。


庭の柵にタイラップで固定できるよう、裏側は両面テープ式のタイラップ固定部を貼り付けました。

Timer Camera Xの低電力化
スケッチweb_camをそのまま動かすと常に100mA程度の消費電流となるため、cheeroの3200mAhバッテリーでは32時間しか動かせない計算です。これでは毎日バッテリーを交換せねばならず、定点カメラとしてはちょっと不便なので、次の3つの対策で低電力化しました。結果、3日間連続動作できるようになりました。
対策1:CPU周波数を低くする
デフォルトだと240MHzですが、80MHzまで落とすことで電流を10mA程度下げることができました(80MHzより落とすとWifiが使えなくなる仕様のようです)。次の関数でCPU周波数を設定できます。
setCpuFrequencyMhz(80);
対策2:ディープスリープを使う
1分毎に画像を取得するので、「50秒間ディープスリープ」→「10秒間カメラサーバ動作」を繰り返すようにしました。ディープスリープへの移行は次の関数を使います。
M5.Power.deepSleep(SLEEP_SEC(50));
対策3:カメラデバイスOV3660のスタンバイモードを使う
消費電流を計測してみると、ディープスリープにしても40mAくらい消費しており、期待したより消費電流が下がりませんでした。調べるとこちらの記事にたどり着き、Timer Camera Xに搭載されているカメラデバイスOV3660をスタンバイモードにすると消費電流を数μAまで下げられることがわかりました。次のようにカメラデバイスのレジスタ番地0x3008の値を「0x02」から「0x42」に書き換えることでスタンバイモードに移行できます。ディープスリープに移行する直前にこれを実施します。
sensor_t *s = esp_camera_sensor_get(); s->set_reg(s, 0x3008 , 0xff, 0x42);
ラズパイ側のPythonプログラム
1分毎にHTTPリクエストして画像を取得するプログラムを参考として掲載します。
# -*- coding: utf-8 -*- import os import urllib.request if __name__ == '__main__': i = 0 while True: try: response = urllib.request.urlopen('http://xxx.xxx.xxx.xxx/capture',timeout=10) image_b = response.read() #ファイル名を通番にして保存 fname = '{:04d}'.format(i) f = open('YOUR_PICTURES_FOLDER/'+ fname + '.jpg', 'wb') f.write(image_b) f.close() i = i+1 time.sleep(60) except Exception as e: print(e)
まとめ
Timer Camera Xを利用した定点カメラでアゲハチョウの幼虫を観察してみた様子と、定点カメラの作り方について簡単ですがご紹介しました。ウレタンやタイラップを利用することで、難しい加工を一切せずに組み立てることができました。得られた画像でタイムラプスを作成したら思いの外楽しめるものになりました。省電力化にも取り組み、バッテリーで3日間連続動作できるようになりましたが、理想はバッテリー交換を週一回にしたいので、もう少し工夫したいと思います。
参考サイト
Timer Camera(USB給電時)を低電力化する - MSR合同会社
防水ケースとTimer Camera Xを使った定点カメラや、Timer Cameraの低電力化について、多くを参考にさせていただきました。
M5Stack CoreS3でディープラーニング推論を実装してみた

以前、M5StackシリーズのTimer Camera X(ESP32マイコンを搭載)でディープラーニングの推論を試してみた記事を投稿しましたが、新しく発売されたM5Stack CoreS3にカメラが搭載されたため、移植して記事も刷新しました。また、以前は開発環境としてArduinoIDEを使用していたため、ライブラリを取り込むところでやや余計な手順が発生していましたが、今回はPlatformIOを使用して開発効率も上がりました。
本記事ではM5Stack CoreS3のカメラに映った手の指がさしている方向(中央、上、下、右、左)を、デバイス側のプログラムだけで推論できるようにするまでの手順を解説します。学習はGoogle Colaboratory上で行います。自分で用意した画像を用いて学習させることができます。
次の動画は、M5Stack CoreS3で実行した様子です。動画では完璧に指差した方向を認識していますが、背景の色などが変わると認識率がとても悪くなります。実用的なものを作るにはもっと勉強が必要のようです^^;
GitHubにPlatformIOの最終的なプロジェクトも入っていますので、ビルドしてM5Stack CoreS3に書き込めばすぐに試すことができます。
- 開発環境
- 開発手順の概要
- 手順① データセットのリストを作成する
- 手順② MNISTサンプルプログラムを改造する
- 手順③~④ Colab上で学習し、モデルファイルを生成する
- 手順⑤ 変換結果ファイルとnnablaランタイムをPlatformIOのプロジェクトに取り込む
- 手順⑥ カメラ画像から推論するコードを作成する
- まとめ
- 参考書籍・サイト
開発環境
| 項目 | 名称 | バージョン |
|---|---|---|
| M5Stack実機 | M5Stack CoreS3 | |
| 開発用PC | Windows 11 Pro | 21H2 |
| IDE (実機プログラム開発用) |
PlatformIO | Core 6.1.7 Home 3.4.4 |
| AI開発環境 (学習モデル生成用) |
Google Colaboratory ライブラリ : Neural Network Library (nnabla) |
1.33.1 |
PlatformIOについて
PlatformIOはVisual Studio Codeの拡張機能としてインストールします。インストール手順の説明は割愛しますが、こちらの記事などが参考になります。
Google Colaboratoryについて
学習は自前のPC上のPython環境で行ってもよいのですが、今回はGoogle Colaboratory (以下Colab)を利用しました。Colabなら環境構築に手間をかけることなく、GPUも簡単に使うことができます(ここではColabの使い方は解説しませんが、Googleのアカウントさえ持っていれば簡単に使い始めることができます)。
機械学習フレームワーク Neural Network Library (nnabla) について
マイコンでディープラーニングの推論を動かす方法はいくつかあるようですが、今回はSonyのフレームワーク Neural Network Library (nnabla)を使う方法を選びました。nnablaは学習済みモデルをマイコンで実行できるCソースコードに変換する機能を備えています。
nnablaのライブラリやサンプルプログラムはGithubで公開されています。
開発手順の概要
大まかな手順は次の通りです。以降、詳しく解説していきます。
| No. | 作業内容 | 作業環境 |
|---|---|---|
| ① | CSVファイルでデータセットのリストを作成する(nnablaでデータセットを読み込むときに必要)。 | Python (Colab) |
| ② | nnablaのMNISTサンプルプログラムを、MNISTデータセットではなく自分のデータセットを読み込めるように改造する。 | - |
| ③ | 改造したサンプルプログラムを実行し学習済みモデルのファイル(.nnp)を出力する。 | Python (Colab) |
| ④ | nnabla_cliコマンドでnnpファイルをCソースコードに変換する。 | Python (Colab) |
| ⑤ | 変換結果ファイルとnnablaランタイムをPlatformIOのプロジェクトに取り込む。 | PlatformIO |
| ⑥ | カメラ画像から推論するコードを作成する。 | PlatformIO |
なお、①~④のColabでの作業については、解説のコメントを付けたColabノートブックをGitHubで公開しますので、このノートブックのコードを順番に実行すれば④までの作業が完了します。
[補足]
ColabでGPUを有効にしていないと、上記ノートブックを実行できません。もし有効になっていなければ、Colabのメニューの「ランタイムのタイプを変更」から設定してください。

手順① データセットのリストを作成する
nnablaにデータセットを読み込ませるためには、データセットのリストをCSVファイルで渡す必要があります。 CSVファイルは次のようなフォーマットで、学習用とテスト用に分けて作成します。
x:image,y 画像データのファイルパス, 分類(0,1,...,n) 画像データのファイルパス, 分類(0,1,...,n) 画像データのファイルパス, 分類(0,1,...,n) ・ ・ ・
今回、分類は次のようにしました。
0: 何も写っていない画像
1: 中央を指している画像
2: 上を指している画像
3: 下を指している画像
4: 右を指している画像
5: 左を指している画像
データセットはGitHubのmy_datasetフォルダに、このような感じで分類毎のフォルダに分けて入っています。

今回、このようにフォルダ分けしたデータセットから、自動的にCSVファイルを作成するPythonスクリプトも作ってGitHubに入れました(make_dataset_csv.py)。データセットを8:2の割合で分けて、train.csvとtest.csvを作成してくれます。さらに、データセットの画像を28x28のグレースケールに変換してくれます(変換後の画像データはconverted_datasetsフォルダに保存されます)。
Colabノートブックでは、このデータセットとスクリプトを利用してCSVファイルを作成しています。
手順② MNISTサンプルプログラムを改造する
nnablaのMNISTサンプルプログラム(classification.py)を、MNISTデータセットの代わりにCSVファイル(train.csv,、test.csv)を読み込むように改造します。
改造の仕方は次の記事がとても参考になりますのでここでの解説は割愛しますが、改造済みのプログラム(classification_mydata.py)をGitHubに置いています。Colabノートブックでもこのプログラムをダウンロードして使用しています。
手順③~④ Colab上で学習し、モデルファイルを生成する
Python環境でnnablaのMNISTサンプルプログラムを実行し、学習済みモデルのファイル(.nnp)を出力します。その後、nnabla_cliコマンドでnnpファイルをCソースコードに変換します。ここまではColabノートブックで実行できます。
変換結果として以下のCソースコードが得られ、以降の手順で使用します。
- Validation_inference.c
- Validation_inference.h
- Validation_parameters.c
- Validation_parameters.h
手順⑤ 変換結果ファイルとnnablaランタイムをPlatformIOのプロジェクトに取り込む
ここからはPlatformIOでの作業になります。変換で得られたCソースコード、及びnnablaのランタイムを、下図のようにPlatformIOのプロジェクトフォルダに配置します。
nnablaのランタイムはgit cloneで入手します。
> git clone https://github.com/sony/nnabla-c-runtime.git
図中のstb_image_resize.hは、カメラ画像を前処理としてリサイズするときに使うライブラリで、こちらのGitHubリポジトリで公開されているものを使用させていただきました。

また、Validation_inference.cとValidation_parameters.cは次のように修正が必要です。
■Validation_inference.c 修正内容
130行目付近の関数宣言をコメントアウト(削除)します(そうしないと、ビルド時に二重定義だと言われる)。
//void *(*rt_variable_malloc_func)(size_t size) = malloc; //void (*rt_variable_free_func)(void *ptr) = free; //void *(*rt_malloc_func)(size_t size) = malloc; //void (*rt_free_func)(void *ptr) = free;
■Validation_parameters.c 修正内容
全てのfloat型配列にconstを付けます。ビルド時にRAMがオーバーフローしたというエラーが出たため、配置先をFlashに変更するためにconstを付けました。
const float Validation_parameter11[] = { /* その他全てのfloat型配列にconstを付ける */
手順⑥ カメラ画像から推論するコードを作成する
カメラ画像から推論するコードを作成します。この部分に関しては、ほとんどこちらの記事を参考にさせていただきました。
ソースコードのプロジェクト一式はGitHubのPlatformioフォルダに置いてあります。手順①~⑤を実施済みのプロジェクトなので、ビルドしてM5Stack CoreS3に書き込めば動かすことができます。
■カメラ画像から推論するコード(抜粋)
uint8_t resized_img[NNABLART_VALIDATION_INPUT0_SIZE];
_context = nnablart_validation_allocate_context(Validation_parameters);
float *nn_input_buffer = nnablart_validation_input_buffer(_context, 0);
while(true){
fb = esp_camera_fb_get();
if (!fb) {
Serial.println("Camera capture failed");
res = ESP_FAIL;
} else {
// 28x28にリサイズ
stbir_resize_uint8(fb->buf, 160, 120, 0, resized_img, 28, 28, 0, 1);
// 推論
int64_t infer_time = esp_timer_get_time();
nnablart_validation_inference(_context);
// 推論結果をフェッチ
float *probs = nnablart_validation_output_buffer(_context, 0);
int top_class = 0;
float top_probability = 0.0f;
for (int classNo = 0; classNo < NNABLART_VALIDATION_OUTPUT0_SIZE; classNo++) {
if (top_probability < probs[classNo]) {
top_probability = probs[classNo];
top_class = classNo;
}
}
Serial.printf("Result %d ", top_class);
}
}
まとめ
新しく発売されたM5Stack CoreS3はカメラが搭載されたため、以前Timer Camera Xでやっていたディープラーニング推論を移植してみました。また、以前はArduinoIDEで開発していましたが、今回はPlatformIOで開発することで開発効率も上がっています。冒頭の動画を見るとかなり精度が高いように見えますが、実際は背景に映り込むものによってかなり精度が悪くなります。そこらへんはこれから勉強していきたいと思います。ちなみに、指差した方向を推論させた理由は、スタックチャンとあっち向いてほいをしてみたいと思ったからですw(スタックチャンって何?という方はぜひTwitter等で検索してみてください)
参考書籍・サイト
文中で紹介したものもありますが、参考書籍・サイトを記載します。
・人気ブロガーからあげ先生のとにかく楽しいAI自作教室 (Amazon)
M5Stackは扱われていませんが、ディープラーニングを学び直したり今回の挑戦(エッジAI)をしたりするきっかけになった本です。Google Colaboratoryを使っているのもこの本の影響を強く受けています。
・マイコンでディープラーニングした話 on ESP32 - Qiita
M5StackでNeural Network Library (nnabla)のMNISTのサンプルを動かす方法について参考にさせていただきました。
・SONY Neural Network Libraries データセットの読ませ方 | cedro-blog
nnablaに独自のデータセットを読み込ませる方法について参考にさせていただきました。
プログラミングでChatGPTが欠かせなくなるかもしれないと思わされた体験談
ChatGPTにプログラミングを手伝ってもらったという記事はすでにネット上にあふれていますが、実際に自分で体験してみるまでわからなかったすごさを共有できたらと思います。
きっかけ
仕事で、Linuxでリアルタイム性が求められる組込みシステムのマルチタスク制御をする必要が出てきました。学生のとき(1●年前!!!)にLinuxのマルチスレッド(pthread)でロボット制御をしたことはありますが、最近はというと、ラズパイで遊ぶくらいしかLinuxには触れていません^^; Linuxでリアルタイム性を損なわずにマルチタスク制御できるのかどうか、真面目に調べる必要がありました。
まずは最近のトレンドについて、ChatGPTに聞いてみた
最近ようやくアカウントをつくったChatGPTに、あまり期待はせずに聞いてみました。

コルーチンって何??? ネット検索してみると、確かに最近のトレンドであることが分かります。組込みシステムについてそれなりに知っている気になっていた自分が恥ずかしくなってきました。同時に、いきなりトップクラスの技術者の友達が出来たような、不思議な感覚にとらわれました。(コルーチンなんて常識じゃんと言われてしまうとゴメンナサイですが…)
結局、仕事のチーム内でコルーチンについてプレゼンするのは面倒なので、まずは伝統的なpthreadで調査を進めることにしましたが、ChatGPTは今後無視できなくなると初めて考えさせられた体験でした。
サンプルコードも正確
さらに感動は続きます。
よくよく調べると、Linuxのマルチスレッドでリアルタイム処理をするために、スレッドのスケジューリングポリシーをデフォルトのSCHED_OTHERからSCHED_FIFOに変更する必要があることがわかりました(そうすることでリアルタイムOSと同じように優先度ベースの並列処理ができる)。
※まだ自分のネット検索力にも自信はあったので、これは自分で調べてしまいましたが、後に、ChatGPTに聞いたほうが近道だったことが分かります。
自分で調べた結果、どうやらスケジューリングポリシーを確認、変更するには sched_getscheduler() / sched_setscheduler() を使えば良いことがわかりましたが、いくら検索してもサンプルコードが出てきません。出てくるのはManページを翻訳したようなサイトばかりです(Manページの情報が不十分と言うわけではありませんが、効率を求めるとやはりサンプルコードは欲しい…)。
そこで、ようやくChatGPTに聞いてみました。

…完璧です。わかりやすい解説が付くうえ、とても読みやすいサンプルコードが出てきました。しかも、そのままコンパイルして実行することができました。
なぜ、ネット検索しても出てこないようなサンプルコードをChatGPTさんは書けるのでしょうか… もしかすると、海外サイトも含めて検索するとサンプルコードも出てくるのかもしれませんが、それを日本語の質問で出してくれるChatGPT、便利すぎます。
後で、この関数は親プロセスのスケジューリングポリシーを変更するものであって、子スレッドに対しては別の関数を使う必要があることがわかりました。ChatGPTに質問したら、初めから正しい関数を教えてくれました。そのやり取りがこちら。…ネット検索力、完敗です(汗)

まとめ
初めてChatGPTと一緒にプログラミングをして、そのすごさを目の当たりにしたという話でした。ChatGPTに聞いた内容があまり一般ウケする内容ではなかったので、記事にするかは少し悩みましたが、このような組込み技術者の中でもさらに一握りの人しか調べないような知識までChatGPTが完璧にカバーしているのが本当にすごいと思い、あえて記事にしました。
ChatGPTがプログラミングできると聞いても、結局人が色々手を加えないと使い物にならないでしょと今まであまり気にしていませんでしたが、サンプルコードを生成してくれるツールだと思うと急に身近に感じられ、ネット検索するより早いという評判も、確かに...と思えるようになりました。
ちなみに、自分が使っているのはGPT3.5です。GPT4だとさらに性能が上がってしまうなんて... GPT3.5をもう少し使いこなしたら、GPT4も使ってみたいと思います。
使わなくなったタブレットとラズパイでデジタルフォトフレーム(共有ストレージ対応)を作ってみた
きっと自分だけではないと思いますが…
- 電子書籍を何冊か読んだ後忘れ去られていたiPad mini (2012年モデル)
- 外付けHDDを共有ストレージ化することくらいにしか活用できていないRaspberry Pi 3B+
といったもったいない使い方をしているデバイスたちを使って、デジタルフォトフレーム(共有ストレージ対応)を作ってみました。(今回は構想メインで、ソースコード等細かいことは記載しませんが、今後追記するかもしれません...)
きっかけ
以前からRaspberry Piと使い古しの外付けHDDで共有ストレージを構成して、デジカメやスマホで撮った写真を保存していたのですが、どんどん溜まっていくだけで見る機会がほとんどなく、簡単に家族みんなで見れたら楽しいのになと思っていました。また、iPadも10年落ちとなると、新しいアプリは対応していないし、電子書籍もスマホで十分読めるし…という状況で、ハード的にはまだまだ動くのに使い道がなくもったいないなと感じていました。
コンセプト
共有ストレージに溜まった写真データを、タブレットにランダムで表示して家族みんなで楽しめる。表示する写真は1分毎に自動更新する。
共有ストレージには家族みんながアクセスでき、スマホなどで撮った写真を簡単に保存できる。
フォトフレームはWEBアプリとして実装することで、WEBブラウザが動くデバイス(タブレット、スマホ、fireTVなど)なら何でもフォトフレーム化できる。
実現方法(かなりざっくりとした解説)

Raspberry Pi
- SambaでUSB外付けHDDを共有ストレージ化した。
- WEBサーバはNode.jsで開発した。WEBサーバにリクエストしてきたデバイスに対して、ランダムに選んだ写真を埋め込んだHTMLを返信する。
- HTMLにはJavaScriptを埋め込み、1分毎に自動的にリクエスト(ページ更新)するようにした。
- Node.jsのWebサーバを開始するときに、共有ストレージ内の特定フォルダ内の写真データをすべて探索してリストアップするようにした。(この処理はNode.jsで実装できればスマートだが、自分は慣れているPythonで作成してNode.jsから呼ぶようにした。)
iPad mini
- Webブラウザがあればよいので、アプリ開発は不要。
- デフォルトだと時間が経つと自動で画面オフしてしまうので、設定を「自動ロックなし」に変更した。
- キオスクモードで、管理者以外は余計な操作(ブラウザを閉じて他のアプリを起動するなど)をできないようにした。(ここらへんはお好みで)
PC、スマホなど
アプリ開発は不要。Sambaで共有されたHDDには、標準のファイルエクスプローラでアクセスして写真データを保存できる。(スマホの場合はSambaに対応した適当なアプリを探してインストールする必要がある。)
最後に
市販のデジタルフォトフレームで共有ストレージに対応したものはほとんどないと思いますし、何より既に家にある物だけで作れたので自分的にはとても満足しています。ラズパイのWEBサーバを開発するところは、WEBプログラミング初心者の自分にはちょっと難易度が高かったですが、次の本で勉強しながら作りました。
作りながら学ぶWebプログラミング実践入門 ~一冊で理解するHTML、CSS、JavaScript、Node.js~(Amazonリンク)
お好みで、写真と一緒に日時や天気やラズパイで測った温湿度などを表示することもできると思います。このように、アイデア次第でカスタマイズできるのも自作の良いところではないでしょうか。