MacでStackChan物語 #2 StackChanをMacのOTAへ接続する 開発環境構築
Dockerを起動したところからの続きです。
今回はようやくスタックチャンとの接続の部分になります。
StackChanバックアップ
ファームウェアを書き換える前に、ESP32-S3のFlash全体(16MB)をバックアップしました。
公式ファームウェアはM5Burnerから取得できますが、「この個体の現在の状態」をそのまま保存しておくことで、万一の際にも完全に元へ戻せるようにしています。
まずこちらから、M5Burnerをダウンロードします。
M5Stack公式の「ファームウェアを書き込むソフト」らしいです。

MacOSのところからDLします。


起動したらスタックチャンのファームウエアをダウンロードしておきます。
いざというときに元に戻せるようにです。
保険保険
つぎにスタックチャンをType-CケーブルでMacに接続します。
ls /dev/cu.*これで何か出てくれば繋がっている証拠
satoshi@Satoshi-MacBook-Pro ~ % ls /dev/cu.*
/dev/cu.Bluetooth-Incoming-Port /dev/cu.debug-console /dev/cu.usbmodem1101
satoshi@Satoshi-MacBook-Pro ~ % esptool.py --port /dev/cu.usbmodem1101 flash_id
Warning: DEPRECATED: 'esptool.py' is deprecated. Please use 'esptool' instead. The '.py' suffix will be removed in a future major release.
Warning: Deprecated: Command 'flash_id' is deprecated. Use 'flash-id' instead.
esptool v5.3.1
Connected to ESP32-S3 on /dev/cu.usbmodem1101:
Chip type: ESP32-S3 (QFN56) (revision v0.2)
Features: Wi-Fi, BT 5 (LE), Dual Core + LP Core, 240MHz
Crystal frequency: 40MHz
USB mode: USB-Serial/JTAG
MAC: 1c:db:d4:ba:56:54
Stub flasher running.
Flash Memory Information:
=========================
Manufacturer: 46
Device: 4018
Detected flash size: 16MB
Flash type set in eFuse: quad (4 data lines)
Flash voltage set by a strapping pin: 3.3Vこれで
デバイス:ESP32-S3
Flash容量:16MB
ポート:/dev/cu.usbmodem1101
というのが確認できました。
スタックチャンのバックアップを取ります。
バックアップ用フォルダ作成
まずは保存場所を作ります。
mkdir -p ~/StackChanBackup
cd ~/StackChanBackupFlash全体をバックアップ
ESP32-S3の16MBなので、
esptool \
--chip esp32s3 \
--port /dev/cu.usbmodem1101 \
read-flash \
0x000000 \
0x1000000 \
factory_backup_v1.4.3.bin
まぁまぁ時間がかかりますねぇ。(放置)

バックアップがとれました!これで安心ですね。
Gemma4を使うためにやりたいことを一旦まとめ
案外道のりは遠いぞ
ESP-IDF 5.5.4をMacへ導入
fetch_repos.pyで依存関係を取得
公式状態のままビルド
OTA URLだけローカルMacへ変更
再ビルド
StackChanへ書き込み
xiaozhi-serverのログでWebSocket接続を確認
StackChan公式ファームウェアの開発環境構築
公式リポジトリを取得します
git clone https://github.com/m5stack/StackChan.git
cd StackChansatoshi@Satoshi-MacBook-Pro StackChan % ls
app firmware README.md remote server
なんかいろいろあるっすね。
ファームウェア側のバージョンとESP-IDF要件を確認
satoshi@Satoshi-MacBook-Pro StackChan % grep -n "PROJECT_VER" firmware/CMakeLists.txt
sed -n '1,220p' firmware/README.md
5:set(PROJECT_VER "1.4.3")
6:add_definitions(-DFIRMWARE_VERSION=\"${PROJECT_VER}\")
## Build
### Fetch Dependencies
```bash
python3 ./fetch_repos.py
```
### Tool Chains
[ESP-IDF v5.5.4](https://docs.espressif.com/projects/esp-idf/en/v5.5.4/esp32s3/index.html)
### Build
```bash
idf.py build
```
### Host-side tests
The motion coordinate helpers can be tested without ESP-IDF hardware:
```bash
cmake -S tests -B build-host-tests
cmake --build build-host-tests
ctest --test-dir build-host-tests --output-on-failure
```
### Flash
```bash
idf.py flash
```
satoshi@Satoshi-MacBook-Pro StackChan % grep -R -n \
"ota.*url\|OTA.*URL\|CONFIG_OTA\|xiaozhi/ota\|api.tenclass.net" \
firmware | head -100
firmware/CMakeLists.txt:13:# CONFIG_OTA_URL, etc. without touching committed defaults.
firmware/main/hal/hal_app_center.cpp:99: if (const char *url = get_json_string(item, {"firmwareUrl", "downloadUrl", "otaUrl", "url"})) {
firmware/main/hal/hal_app_center.cpp:125: start_ota_update(url.data(), ota_callback);
firmware/main/hal/utils/ota/ota.c:26:#define OTA_URL_SIZE 256
firmware/main/hal/utils/ota/ota.c:127:void start_ota_update(const char *url, void (*on_progress)(int progress))
firmware/main/hal/utils/ota/ota.c:161: char url_buf[OTA_URL_SIZE];
firmware/main/hal/utils/ota/ota.c:164: fgets(url_buf, OTA_URL_SIZE, stdin);
firmware/main/hal/utils/ota/ota.h:12:void start_ota_update(const char* url, void (*on_progress)(int progress));
firmware/main/Kconfig.projbuild:16:config OTA_URL
firmware/main/Kconfig.projbuild:17: string "Default OTA URL"
firmware/main/Kconfig.projbuild:18: default "https://api.tenclass.net/xiaozhi/ota/"
GitHub側も Firmware 1.4.3
本体も Firmware 1.4.3
指定ツールチェーンは ESP-IDF 5.5.4
OTA接続先は CONFIG_OTA_URL で設定可能
CONFIG_OTA_URL などを、コミット済みの初期設定に触れず変更できるらいいので、その辺を確認してみます。
sed -n '1,80p' firmware/CMakeLists.txtOTAの定義
sed -n '1,80p' firmware/main/Kconfig.projbuild依存取得スクリプト
sed -n '1,240p' firmware/fetch_repos.py公式ファイルを直接編集せず、sdkconfig.defaults.local でOTA URLを上書きできるのは間違いなさそう。
依存関係
satoshi@Satoshi-MacBook-Pro StackChan % git status --short
find . -maxdepth 2 -type d | sort
?? sdkconfig.defaults.local
.
./.git
./.git/hooks
./.git/info
./.git/logs
./.git/objects
./.git/refs
./app
./app/android
./app/assets
./app/ios
./app/lib
./app/test
./firmware
./firmware/main
./firmware/patches
./firmware/tests
./remote
./remote/code
./server
./server/api
./server/check_list
./server/file
./server/hack
./server/internal
./server/manifest
./server/resource
./server/utility
satoshi@Satoshi-MacBook-Pro StackChan %
ローカルOTA設定を作成
cat > sdkconfig.defaults.local <<'EOF'
CONFIG_OTA_URL="http://192.168.0.Macのip:8003/xiaozhi/ota/"
EOFESP-IDF 5.5.4 をダウンロードします。
ESP-IDFはESP32(StackChanの頭脳)用の公式開発環境です。
git clone --recursive --branch v5.5.4 https://github.com/espressif/esp-idf.gitダウンロードに結構時間がかかります。
ESP-IDFをインストールします。(まだなんかい!)
cd ~/git/esp-idf
./install.sh esp32s3これも結構時間がかかる。
みんなもしかしてこの辺の作業って、AIに自動でやらせてたりするんですかね。。結構面倒くさいですね。。
インストールが終わったら以下を確認します。
satoshi@Satoshi-MacBook-Pro esp-idf % . ./export.sh
Checking "python3" ...
Python 3.11.12
"python3" has been detected
Activating ESP-IDF 5.5
Setting IDF_PATH to '/Users/satoshi/git/esp-idf'.
* Checking python version ... 3.11.12
* Checking python dependencies ... OK
* Deactivating the current ESP-IDF environment (if any) ... OK
* Establishing a new ESP-IDF environment ... OK
* Identifying shell ... zsh
* Detecting outdated tools in system ... OK - no outdated tools found
* Shell completion ... Autocompletion code generated
Done! You can now compile ESP-IDF projects.
Go to the project directory and run:
idf.py build
satoshi@Satoshi-MacBook-Pro esp-idf % idf.py --version
ESP-IDF v5.5.4
satoshi@Satoshi-MacBook-Pro esp-idf % echo $IDF_PATH
/Users/satoshi/git/esp-idf
一歩一歩。
ESP-IDF 5.5.4が正常に起動しました。
試しにビルドしてみます。
idf.py build firmware % idf.py build
Executing action: all (aliases: build)
Running cmake in directory /Users/satoshi/git/StackChan/firmware/build
Executing "cmake -G Ninja -DPYTHON_DEPS_CHECKED=1 -DPYTHON=/Users/satoshi/.espressif/python_env/idf5.5_py3.11_env/bin/python -DESP_PLATFORM=1 -DCCACHE_ENABLE=0 /Users/satoshi/git/StackChan/firmware"...
-- StackChan: detected sdkconfig.defaults.local, applying overlay
-- IDF_TARGET is not set, guessed 'esp32s3' from sdkconfig '/Users/satoshi/git/StackChan/firmware/sdkconfig.defaults'
-- Found Git: /opt/homebrew/bin/git (found version "2.42.0")
省略
[2491/2491] cd /Users/satoshi/git/StackChan/firmware/build/esp-idf/esptool_py && /Users/satoshi/.espressif/python_env/...tackChan/firmware/build/partition_table/partition-table.bin /Users/satoshi/git/StackChan/firmware/build/stack-chan.bi
stack-chan.bin binary size 0x39c4e0 bytes. Smallest app partition is 0x4f0000 bytes. 0x153b20 bytes (27%) free.
Project build complete. To flash, run:
idf.py flash
or
idf.py -p PORT flash
or
python -m esptool --chip esp32s3 -b 460800 --before default_reset --after hard_reset write_flash --flash_mode dio --flash_size 16MB --flash_freq 80m 0x0 build/bootloader/bootloader.bin 0x8000 build/partition_table/partition-table.bin 0xd000 build/ota_data_initial.bin 0x20000 build/stack-chan.bin 0xa00000 build/generated_assets.bin
or from the "/Users/satoshi/git/StackChan/firmware/build" directory
python -m esptool --chip esp32s3 -b 460800 --before default_reset --after hard_reset write_flash "@flash_args"いけたかな??
これで、MacでStackChan公式ファームウェア v1.4.3を生成できたことになります。
🟩🟩🟩🟩🟩🟩⬜⬜⬜⬜
Mac環境 ✅
xiaozhi-server ✅
Gemma4 ✅
ESP-IDF ✅
StackChan Build ✅
OTA変更 ✅
書き込み ← 次はココ
ようやくStackChanへ書き込み
idf.py -p /dev/cu.usbmodem1101 flashここでスタックチャンが認識できていないとエラーになるので、
USBでちゃんと認識していることを確認してください。(僕失敗しました)
省略
Leaving...
Hard resetting via RTS pin...
Done
書き込み成功
StackChanがMacへアクセスしているかを確認します。
satoshi@Satoshi-MacBook-Pro firmware % docker logs -f xiaozhi-esp32-server
onnxruntime cpuid_info warning: Unknown CPU vendor. cpuinfo_vendor value: 0
260711 13:12:11[0.9.5_00000000000000][core.utils.gc_manager]-INFO-启动全局GC管理器,间隔300秒
260711 13:12:11[0.9.5_00000000000000][core.utils.modules_initialize]-INFO-初始化组件: llm成功 OllamaLLM
260711 13:12:11[0.9.5_00000000000000][core.utils.modules_initialize]-INFO-初始化组件: intent成功 function_call
260711 13:12:11[0.9.5_00000000000000][core.utils.modules_initialize]-INFO-初始化组件: memory成功 nomem
260711 13:12:11[0.9.5_00000000000000][core.providers.vad.silero]-INFO-SileroVAD
260711 13:12:11[0.9.5_00000000000000][core.utils.modules_initialize]-INFO-初始化组件: vad成功 SileroVAD
260711 13:12:15[0.9.5_00000000000000][core.providers.asr.fun_local]-INFO-funasr version: 1.2.7.
260711 13:12:15[0.9.5_00000000000000][core.utils.modules_initialize]-INFO-ASR模块初始化完成
260711 13:12:15[0.9.5_00000000000000][core.utils.modules_initialize]-INFO-初始化组件: asr成功 FunASR
260711 13:12:15[0.9.5_00000000000000][__main__]-INFO-OTA接口是 http://172.19.0.2:8003/xiaozhi/ota/
260711 13:12:15[0.9.5_00000000000000][__main__]-INFO-视觉分析接口是 http://172.19.0.2:8003/mcp/vision/explain
260711 13:12:15[0.9.5_00000000000000][__main__]-INFO-Websocket地址是 ws://172.19.0.2:8000/xiaozhi/v1/
260711 13:12:15[0.9.5_00000000000000][__main__]-INFO-=======上面的地址是websocket协议地址,请勿用浏览器访问=======
260711 13:12:15[0.9.5_00000000000000][__main__]-INFO-如想测试websocket请启动digital-human模块,打开浏览器交互测试
260711 13:12:15[0.9.5_00000000000000][__main__]-INFO-=============================================================
260712 01:28:09[0.9.5_00000000000000][core.api.ota_handler]-INFO-OTA请求设备ID: 1c:db:d4:ba:56:54
260712 01:28:09[0.9.5_00000000000000][core.api.ota_handler]-INFO-OTA请求ClientID: f9658e0b-3173-40f7-ac3f-9dc575974b94
260712 01:28:09[0.9.5_00000000000000][core.api.ota_handler]-INFO-未配置MQTT网关,为设备 1c:db:d4:ba:56:54 下发WebSocket配置
260712 01:28:09[0.9.5_00000000000000][core.api.ota_handler]-INFO-Firmware cache refreshed: 0 models
260712 01:28:09[0.9.5_00000000000000][core.api.ota_handler]-INFO-查找型号 m5stack-stack-chan 的固件,找到 0 个候选
260712 01:28:09[0.9.5_00000000000000][core.api.ota_handler]-INFO-设备 1c:db:d4:ba:56:54 固件已是最新: 1.4.3成功です!
StackChanがMac上のxiaozhi-serverへアクセスしていることがわかります。
これで公式サーバーを使わずに、Macに接続してスタックちゃんが動かすことができるようになりました。
マトリックスで電池の装置からサルベージしたような感覚!!

進捗
StackChan
│
▼
Mac OTA Server ✅
│
▼
xiaozhi-server ✅
│
▼
Ollama ✅
│
▼
Gemma4 👈 次はとうとうココ

【参考にしていただけましたら、よかったらフォローと、スキ❤️を、そしてX(Twitter)でシェアと感想を頂けると幸いです】
いいなと思ったら応援しよう!
お読みいただきありがとうございました。もし参考になったり面白かったと思っていただけましたらサポートよろしくお願いします。次の執筆のモチベになります。