QuickJSでお手軽ESP32＋Javascript実行環境（その2）：使ってみよう

前回の投稿「 [QuickJSでお手軽ESP32＋Javascript実行環境]( https://qiita.com/poruruba/items/e159464305e5bab6e06e) 」で、ESP32(M5StickC)上でJavascriptを動かしてみましたが、今回は、細かいことは置いておいて、とりあえず動かしてみるまでを説明します。

GitHubはこちら。

poruruba/Esp32quickJS_sample
　https://github.com/poruruba/Esp32QuickJS_sample


#前提条件

Microsoft Visual Studio Codeがインストールされ、PlatformIOがセットアップされている状態にします。

Visual Studio Code
https://azure.microsoft.com/ja-jp/products/visual-studio-code/

PlatformIO
Visual Studio Codeの左側の拡張機能から、PlatformIOと入れると出てくる「PlatfomIO IDE」をインストール。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261826/129f45d4-b6c2-79de-9202-7fd52e4a1556.png)

※私の環境ではいろいろセットアップ済みの状態で実施したため、新規の場合足りない作業があるかもしれません。

# Wifiアクセスポイントの書き換え

ソース一式はGitHubに上げているのですが、各環境に合わせて変更する箇所があります。
・WiFiアクセスポイントの変更
・M5StickCのCOMポート番号の変更

まずは、以下のURLからZIPをダウンロードします。

https://github.com/poruruba/Esp32QuickJS_sample

ダウンロードして展開し、以下のフォルダでVisual Studio Codeを開きます。

```
unzip Esp32QuickJS_sample-main.zip
cd Esp32QuickJS_sample-main\Esp32QuickJS_sample-main\Esp32QuickJS
```

src/main.cppの以下の部分を環境に合わせて書き換えます。

```c:src/main.cpp
const char *wifi_ssid = "【WiFiアクセスポイントのSSID】";
const char *wifi_password = "【WiFiアクセスポイントのパスワード】";
```

platformio.iniの以下の部分を環境に合わせて書き換えます。

```ini:platformio.ini
upload_port = COM6
monitor_port = COM6
```

私の環境では、M5StickCのCOMポート番号が6でした。

あとは、左下の「→」のところをクリックします。ツールチップで「PlatfomIO: Upload」と表示されている部分です。

そうすると、必要なファイルのダウンロードとコンパイルし、問題なければ、M5StickCに書き込みます。

成功すると以下のように表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261826/c9bf3271-cd93-5881-c3d5-67e10e0720e1.png)

ここで、```Ctrl+Shift+P```を押すと、拡張コマンドの入力ができるようになるため、以下を選択してEnterを押下します。
PlatformIO: Serial Monitor

そうすると、M5StickCのCOMポートに接続されたターミナルが表示されます。
すでにJavascriptは動いていて、main.jsの内容の通りにconsole.logの内容が出力されているのがわかります。

```
> Executing task: C:\Users\XXXX\.platformio\penv\Scripts\pio.exe device monitor <

--- Available filters and text transformations: colorize, debug, default, direct, esp32_exception_decoder, hexlify, log2file, nocontrol, printable, send_on_enter, time
--- More details at http://bit.ly/pio-monitor-filters
--- Miniterm on COM6  9600,8,N,1 ---
--- Quit: Ctrl+C | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---

Connected : XXX.XXX.XXX.XXX
https://raw.githubusercontent.com/poruruba/Esp32QuickJS_sample/main/public_html/modules.json
[HTTP] GET begin...
[HTTP] GET...
[HTTP] GET... code: 200
[HTTP] Content-Length=265
https://raw.githubusercontent.com/poruruba/Esp32QuickJS_sample/main/public_html/fib.js
[HTTP] GET begin...
[HTTP] GET...
[HTTP] GET... code: 200
[HTTP] Content-Length=176
fib.js
https://raw.githubusercontent.com/poruruba/Esp32QuickJS_sample/main/public_html/math.js
[HTTP] GET begin...
[HTTP] GET...
[HTTP] GET... code: 200
[HTTP] Content-Length=98
math.js
https://raw.githubusercontent.com/poruruba/Esp32QuickJS_sample/main/public_html/main_modules.js
[HTTP] GET begin...
[HTTP] GET...
[HTTP] GET... code: 200
[HTTP] Content-Length=309
Hello World
fib(10)=
55
add(1, 2)=
3
sub(3, 4)=
-1
Hello World
fib(10)=
55
・・・・
```

COMポートを開いたタイミングによっては、HTTP Getしている様の出力の表示はないかもしれません。
何も変更していなければ、以下の部分に指定したmain.jsが動いています。(GitHubにあげているやつです)

```c:src/main.cpp
const char *jscode_main_url = "https://raw.githubusercontent.com/poruruba/Esp32QuickJS_sample/main/public_html/main_modules.js";
```

内容は以下の通りです。

```js:main_modules.js
/* example of JS module importing a C module */

import { fib } from "fib.js";
import * as math from "math.js";

setInterval(() =>{
  console.log("Hello World");
  console.log("fib(10)=", fib(10));
  console.log("add(1, 2)=", math.add(1, 2));
  console.log("sub(3, 4)=", math.sub(3, 4));
}, 1000);
```

フィボナッチの計算をしたり、mathというモジュールを呼んだ結果をconsole.logしています。
では、これらモジュールはどこからとってきているかというと、以下の部分で指定しています。

```c:src/main.cpp
const char *jscode_modules_url = "https://raw.githubusercontent.com/poruruba/Esp32QuickJS_sample/main/public_html/modules.json";
```

内容は以下の通りです。

```json:modules.json
[
	{
		"name": "fib.js",
		"url": "https://raw.githubusercontent.com/poruruba/Esp32QuickJS_sample/main/public_html/fib.js"
	},
	{
		"name": "math.js",
		"url": "https://raw.githubusercontent.com/poruruba/Esp32QuickJS_sample/main/public_html/math.js"
	}
]
```

JSONファイルになっていて、そこに示されたJavascriptをさらに取得してロードしています。たとえば、math.jsは以下の内容になっています。

```js:math.js
export function add(a, b){
  return a + b;
}

export function sub(a, b){
  return a - b;
}
```

modules.jsonで示されている通りmath.jsという名前でモジュールが登録され、それをmain_modules.jsから以下のように指定しています。

```js:main_module.js
import * as math from "math.js";
```

#カスタマイズ

あとはサーバに配置するmodules.jsonやJavascriptを編集したのち、M5StickCを再起動すればよいです。
再起動は、M5StickCのBボタン(横側面のボタン)を押下することで再起動するようにしています。

#オフライン実行

オフラインで実行する場合は、JavascriptをM5StickCのROMに埋め込む必要があります。

まずは、main.cppにある以下の部分のコメントアウトを外します。

```c:src/main.cpp
#define LOCAL_JAVASCRIPT
```

srcフォルダ等に、Javascriptファイルを置きます。
※Cソースとごっちゃになるので、別のフォルダ(jsとか)に置けばよかった。後で直そう。

platformio.iniにそのJavascriptファイルを指定して埋め込みます。
(参考) https://docs.platformio.org/en/latest/platforms/espressif32.html#embedding-binary-data

```ini:platformio.ini
board_build.embed_txtfiles = 
;	src/default.js
	src/fib.js
	src/math.js
	src/main_modules.js
```

main.cppで埋め込んだJavascriptを参照できるようにします。

```c:src/main.cpp
extern const char jscode_main[] asm("_binary_src_main_modules_js_start");
extern const char jscode_fib[] asm("_binary_src_fib_js_start");
extern const char jscode_math[] asm("_binary_src_math_js_start");
```

後は以下のようにしてロードし実行します。

```c:src/main.cpp
  qjs.begin();

  qjs.load_module(jscode_fib, strlen(jscode_fib), "fib.js");
  qjs.load_module(jscode_math, strlen(jscode_math), "math.js");

  qjs.exec(jscode_main);
```

以上