Moddable SDK 5.2.0で追加されたカメラ機能を試してみた (※解決済)

# はじめに

2024年11月14日、Moddable SDK 5.2.0がリリースされて、カメラ機能が含まれていました。

![スクリーンショット 2024-11-23 11.03.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/65226291-9fb9-78b3-0615-5a02618a8957.png)

# 積みボードを崩すつもりが、積んでしまった件

カメラ機能を試すため、新しいボードを積んでしまいました。

### Seeed Studio XIAO ESP32S3 Sense

https://jp.seeedstudio.com/XIAO-ESP32S3-Sense-p-5639.html

### M5Stack AtomS3R Cam

https://docs.m5stack.com/en/core/AtomS3R%20Cam

### M5Stack AtomS3R M12

https://docs.m5stack.com/en/core/AtomS3R-M12

# 環境構築(再構築)

xs-devツールを使用して環境を構築します。
xs-devツールを更新します。(私の環境では、v0.30.4 -> V0.33.1 へ更新)

```bash
npm update xs-dev
```

最初、SDKを更新(update)しようとしましたが、エラーが出たので環境を再構築しました。
環境を破棄します。

```bash
xs-dev teardown
```

Moddable SDKをインストールします。

```bash
xs-dev setup
```

環境変数(IDF_PYTHON_ENV_PATH)の問題でエラーが出たので、ターミナルを開き直します。
ESP-IDFをインストールします。

```bash
xs-dev setup --device esp32
```

ターミナルを開き直します。
エラーが発生しました。
インストールされているPythonのバージョンが3.9と異なると、エラーが発生します。

```bash
Last login: Sat Nov 23 12:51:54 on ttys000
Detecting the Python interpreter
Checking "python3" ...
Python 3.13.0
"python3" has been detected
Checking Python compatibility
Checking other ESP-IDF version.
Not using an unsupported version of tool openocd-esp32 found in PATH: 0.12.0. To use it, run '/opt/homebrew/opt/python@3.13/bin/python3.13 /Users/kitazaki/.local/share/esp32/esp-idf/tools/idf_tools.py export --prefer-system'
WARNING: Error while accessing the ESP-IDF version file in the Python environment: [Errno 2] No such file or directory: '/Users/kitazaki/.espressif/python_env/idf5.3_py3.13_env/idf_version.txt'
Adding ESP-IDF tools to PATH...
WARNING: Error while accessing the ESP-IDF version file in the Python environment: [Errno 2] No such file or directory: '/Users/kitazaki/.espressif/python_env/idf5.3_py3.13_env/idf_version.txt'
Checking if Python packages are up to date...
ERROR: /Users/kitazaki/.espressif/python_env/idf5.3_py3.13_env/bin/python doesn't exist! Please run the install script or "idf_tools.py install-python-env" in order to create it
```

ESP-IDFを再インストールします。

```bash
cd $IDF_PATH
./install.sh esp32
```

.zprofileに環境変数(MODDABLE、IDF_PATH)が設定されていることを確認します。

```bash
export MODDABLE="/Users/ユーザ名/.local/share/moddable"
export PATH="${MODDABLE}/build/bin/mac/release:$PATH"
export IDF_PATH="/Users/ユーザ名/.local/share/esp32/esp-idf"
source $IDF_PATH/export.sh
```

# サンプルプログラムの実行

$MODDABLE/examples/io/imagein/camera ディレクトリにサンプルプログラムがあります。

camera-balls
camera-server
camera-server-jpeg
camera-server-motion-jpeg
camera-test

結論から言うと、AtomS3R CamやXIAO ESP32S3 Senseのように、デバイスにディスプレイが存在しないと動かないサンプルがありました。(ビルドでエラーが出ます)

camera-balls
camera-server
camera-test

## 動いたサンプル

### camera-server-jpeg

ブラウザでデバイス(HTTPサーバ)へアクセスすると、デバイスのカメラで撮影したJPEG画像を表示します。
XIAO ESP32S3 Sense と M5Stack AtomS3R M12 で動作しました。
AtomS3R Camに搭載されているカメラ(<A HREF="https://m5stack.oss-cn-shenzhen.aliyuncs.com/resource/docs/datasheet/core/K128%20CoreS3/GC0308.PDF">GC0308</A>)はJPEGを出力できないため、ビルド後の実行時にエラー("camera init failed")が発生します。
<A HREF="https://github.com/Moddable-OpenSource/moddable/tree/public/examples/io/imagein">README</A>にも記載されています。

```bash
cd $MODDABLE/examples/io/imagein/camera/camera-server-jpeg
UPLOAD_PORT=/dev/cu.usbmodem11101 mcconfig -d -m -p esp32/xiao_esp32s3_sense ssid="SSID" password="PASSWORD"
```

デバッガ(xsbug)のログに表示されるURLへブラウザでアクセスします。

![1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/29a55b8c-cf28-faea-68f4-4c7c3f366f2f.jpeg)

![2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/1089d702-92df-3f6f-8b40-fc490483342c.jpeg)

### camera-server-motion-jpeg

ブラウザでデバイス(HTTPサーバ)へアクセスすると、デバイスのカメラで撮影した動画(Motion JPEG)を表示します。
XIAO ESP32S3 Sense と M5Stack AtomS3R M12 で動作しました。
AtomS3R Camは動作しませんでした。(JPEG出力に対応していないため)

XIAO ESP32S3 Sense は連続で動作させるとデバイスが高温になるので、注意してください。(<A HREF="https://www.seeedstudio.com/Aluminum-Heat-Sink-For-XIAO-2pcs-p-5972.html">ヒートシンク</A>が発売されています)

![3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/e9cb5813-d440-5cd4-2c2e-2ad6e47cbf04.jpeg)

![4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/696b4b66-7828-8e40-11f0-c39c62cb3c23.jpeg)

M5Stack AtomS3R M12 は連続で動作させると画像が乱れ始めました。
カメラデバイス、または、画像データの処理速度が追いついていないかもしれません。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/34ed1aee-5431-4e0f-4d26-d643d5be98b6.jpeg" width="50%">


### 追記(解決済):デバイスの不良ではありませんでした(2025年1月3日時点)

初期ファームウェアに戻したところ問題ありませんでした。

https://qiita.com/kitazaki/items/8db9db07e0ef08d55378

原因がわかりました。(2025年1月3日)

https://x.com/Zakkiea/status/1875135086057902388

PR(プルリク)を出しました。(2025年1月4日)

https://x.com/Zakkiea/status/1875399037496782922


### 追記(解決済):Moddable SDK 5.3.3でmotion-jpegが動作しなくなりました(2025年1月4日)

Issueを出しました。

|Moddable SDK Version | XIAO ESP32S3 Sense | M5Atom S3R M12
| --- | --- | --- |
|5.2.0 | OK | OK |
|5.3.0 | OK | OK |
|5.3.3 | NG | NG |

https://x.com/Zakkiea/status/1875399190869897218

原因が判明しました。HTTP Serverの変更が影響していました。(2025年1月5日)

https://github.com/Moddable-OpenSource/moddable/issues/1448


# AtomS3R Camで動かす方法(調査完了)(2024年11月24日時点)

AtomS3R Camで動かす方法を探っていきます。
Cam と M12 は同じピン配列なので、同じデバイス定義ファイルで問題なさそうです。

### デバイス定義ファイル(m5atom_s3r)

![スクリーンショット 2024-11-23 19.45.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/1fe1936b-f027-3307-7b43-4c516a166a89.png)

### ピン配列

![Cam.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/30db75d2-4d49-cf67-0fb9-3162f035026b.jpeg)

![M12.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/df9a9f01-ec73-7914-e956-f9589ea0cfac.jpeg)

## サンプルプログラム

AtomS3R Camにディスプレイを追加することでサンプルプログラムを動かすことができました。
以下のサンプルプログラムを使用します。

camera-server

## ディスプレイが必要な理由

GC0308はJPEG出力に対応していないためRGB565で出力させますが、BMPを処理するのにCommodettoライブラリを使用するためscreen定義が必要です。

$MODDABLE/examples/manifest_commodetto.json を include している
　↓

$MODDABLE/build/devices/esp32/setup/commodetto.js を preload している
　↓
screen定義がないとエラー("no screen configured")を出力

最初、I2C接続のOLEDディスプレイ(SSD1306)を使用しましたが、エラー("unsupported pixel format")で動きませんでした。
SPI接続のIPSディスプレイ(ST7789)を使用してサンプルプログラムを動かすことができました。

ディスプレイのないデバイスにディスプレイを追加する方法(メモ)はこちらです。

https://qiita.com/kitazaki/private/eb62c0d68bbd68b6a24d


### 追記:次回のリリースで改善される見込み(2025年1月3日時点)

GitHub Discussionsで議論されています。

https://github.com/Moddable-OpenSource/moddable/discussions/1445


### プログラムの変更点

ディスプレイを使用するため、manifest.jsonに定義を追加します。

- include
  - ST7789ドライバー
- config
  - screen定義
- defines
  - spi
  - ili9341 (ST7789ドライバーはili9341ドライバーを使用しています)

```json:manifest.json
{
        "include": [
                "$(MODDABLE)/examples/manifest_base.json",
                "$(MODDABLE)/examples/manifest_net.json",
                "$(MODDABLE)/examples/manifest_commodetto.json",
                "$(MODULES)/network/http/manifest.json",
                "$(MODDABLE)/modules/io/imagein/camera/manifest.json",
                "$(MODULES)/drivers/st7789/manifest.json"
        ],
        "modules": {
                "commodetto/Bitmap": "$(COMMODETTO)/commodettoBitmap",
                "commodetto/Poco": "$(COMMODETTO)/commodettoPoco",
                "commodetto/*": "$(COMMODETTO)/commodettoPocoBlit",
                "commodetto/PixelsOut": "$(COMMODETTO)/commodettoPixelsOut",
                "*": [
                        "./main",
                        "./bmpSpooler"
                ]
        },
        "preload": [
                "commodetto/*",
                "bmpSpooler"
        ],
        "config": {
                "screen": "st7789",
                "touch": ""
        },
        "defines": {
                "spi": {
                        "mosi_pin": 6,
                        "miso_pin": -1,
                        "sck_pin": 7
                },
                "ili9341": {
                        "cs_pin": -1,
                        "dc_pin": 5,
                        "rst_pin": 8,
                        "spi_port": "SPI3_HOST",
                        "hz": 20000000,
                        "width": 240,
                        "height": 240
                }
        }
}
```

画像サイズが大きいとエラー(RangeError)が出るため、画像サイズを小さくします。

![0.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/dd4104f3-ffed-dce3-e2b2-2b8abb9d248b.jpeg)

```javascript:main.js
let width = 176, height = 144;
↓
let width = 96, height = 96;
```

### 動作結果

デバッガ(xsbug)のログに出力されるURLへブラウザ(Firefoxはエラーが出ます。Chrome、または、Safariを使用します)からアクセスして、無事に画像(BMP)を表示できました。

![2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/b20c61c0-e0e8-e03d-b168-6e25882cb1af.jpeg)