ESP32をJavascriptでLチカする

ESP32のプログラミングには、C言語の知識が必要なことに加えて、長い時間のコンパイルや、手間のかかるデバッグ作業が必要です。
そこで、Javascriptで記述できるようにし、Webサーバ上にJavascriptのソースコードを配置して実行するようにしてみました。

中身は、QuickJSを使っていますが、それに対して、ESP32で普段使っているsetup()やloop()で実装できるようにしたのと、ESP32の特有のデバイス操作をJavascriptから呼び出せるようにしています。

今回は、QuickJSや各種デバイス操作の実装の説明ではなく、JavascriptでのESP32の実装例やセットアップ手順を示します。

ソースコードは以下のGitHubにあります。

poruruba/QuickJS_ESP32

https://github.com/poruruba/QuickJS_ESP32

M5StickCとM5Core2の2種類に対応させておきましたが、他のESP32デバイスでも各種周辺デバイスの接続先ポート番号を変えれば動きます。

＜投稿一覧＞
・[ESP32をJavascriptでLチカする：I2Cデバイスを制御する](https://qiita.com/poruruba/items/4d7ba88408266d32d121)
・[ESP32をJavascriptでLチカする：LCDとRTCデバイスを制御する](https://qiita.com/poruruba/items/95671ce4bd84467112fa)
・[ESP32をJavascriptでLチカする：MQTTでPublish/Subscribeする](https://qiita.com/poruruba/items/acb57c59893331a7868d)
・[ESP32をJavascriptでLチカする：HTTP でJsonをPostする](https://qiita.com/poruruba/items/5dfa96ca9c182daf6c2e)
・[ESP32をJavascriptでLチカする：console.logをリモートで参照する](https://qiita.com/poruruba/items/aaff9a64b87fd220c826)
・[ESP32をJavascriptでLチカする：最終系](https://qiita.com/poruruba/items/311701e03a3de9e4f25c)

#Webサーバを用意する

Javascriptは、Webサーバ上に配置して、ESP32からHTTP Getで取得します。
ですので、まずは適当にWebサーバを立ち上げます。

以下のようにセットアップ・実行すれば、publicフォルダに配置したファイルをHTTP Getできるようになります。

```
$ npm install http-server -g
$ mkdir public
$ http-server ./public
```

ポート番号8080で立ち上がっているはずです。
publicフォルダに、実行したいJavascriptファイルを用意すればよいです。(後で作成します)

#ESP32に書き込む

GitHub「[poruruba/QuickJS_ESP32](https://github.com/poruruba/QuickJS_ESP32)」からダウンロードした中の、以下のフォルダに、Visual Studio Codeのプロジェクトファイル一式を用意しました。Visual Studio Codeからフォルダ読み込みしておきます。
事前に、PlatformIOのインストールが必要です。

 ``` Arduino/QuickJS_M5StickC ```

そして、以下の部分を環境に合わせて書き換えます。

```c:Arduino/QuickJS_M5StickC/src/main.cpp
const char *WIFI_SSID = "【WiFiアクセスポイントのSSID】";
const char *WIFI_PASSWORD = "【WiFiアクセスポイントのパスワード】";
const char *jscode_modules_url = "http://【WebサーバのURL】/ modules.json"; //【モジュールJsonの取得先URL】
const char *jscode_main_url = "http://【WebサーバのURL】/main.js";         //【Javascriptの取得先URL】
const char *MQTT_BROKER_URL = "【MQTTブローカーのURL】"; // MQTTブローカのURL
const unsigned short MQTT_BROKER_PORT = 1883; // MQTTブローカのポート番号(TCP接続)
```

まずは、最低限以下を指定します。
・WIFI_SSID
・WIFI_PASSWORD
・jscode_main_url

また、platformio.iniに、ESP32のCOMポート番号を指定していますので、環境に合わせて書き換えます。

```ini:Arduino/QuickJS_M5StickC/platformio.ini
upload_port = COM4
monitor_port = COM4
```

それでは、ESP32に書き込んでみましょう。
今回は、M5StickCに書き込みます。


#動かしてみる。

Javascriptはとりあえず、以下を用意しておきます。
publicフォルダにおいておけば、先ほど立ち上げたhttp-serverが公開してくれます。

```js:public/main.js
function setup(){
	var ipaddress = esp32.getIpAddress();
	console.log("ipaddress=" + ((ipaddress >> 24) & 0xff) + "." + ((ipaddress >> 16) & 0xff) + "." + ((ipaddress >> 8) & 0xff) + "." + (ipaddress & 0xff));
}

var counter = 0;

function loop(){
	console.log('hello ' + counter++);
	delay(1000);
}
```

コンソールに以下が表示されれば成功です。

```
WiFi Connenting...
Connected : XXX.XXX.XXX.XXX
http://【WebサーバのURL】/modules.json
[HTTP] GET begin...
[HTTP] GET...
[HTTP] GET... code: -1
[HTTP] GET... failed, error: connection refused
modules.json get error
http://XXX.XXX.XXX.XXX:8080/main.js
[HTTP] GET begin...
[HTTP] GET...
[HTTP] GET... code: 200
[HTTP] Content-Length=309
ipaddress=XXX.XXX.XXX.XXX
hello 0
hello 1
hello 2
hello 3
hello 4
hello 5
hello 6
```

#Lチカする

M5StickCには、LEDがついているので、1秒ごとに消灯・点灯を繰り返してみます。
LEDは、GPIO_10につながっていますね。
GPIOを制御するためのモジュールを用意してあります。import宣言します。
（ちなみに、先ほどのJavascriptで使ったesp32モジュールは、基本的なものなので、宣言なしで使えるようにしています。）

以下のJavascriptの記述に変えてみましょう

```js:public/main.js
import * as gpio from "gpio";

function setup(){
	var ipaddress = esp32.getIpAddress();
	console.log("ipaddress=" + ((ipaddress >> 24) & 0xff) + "." + ((ipaddress >> 16) & 0xff) + "." + ((ipaddress >> 8) & 0xff) + "." + (ipaddress & 0xff));
	
	gpio.pinMode(10, gpio.OUTPUT);
	gpio.digitalWrite(10, gpio.HIGH);
}

var led = false;

function loop(){
	led = !led;
	gpio.digitalWrite(10, led ? gpio.LOW : gpio.HIGH );
	delay(1000);
}
```

M5StickCを再起動しましょう。
LEDが点灯・消灯を繰り返すはずです。

#ボタンの押下でLEDのOn/Offを切り替える。

ボタン押下検出のために、inputというモジュールを用意しておきました。
起動が完了したら、LEDを点灯させるようにしましたので、以降、ボタンAが押されたことを検知したら、LEDの消灯・点灯を切り替えます。

esp32.update()は、M5のArduinoプログラミングで呼び出していたM5.update()に相当します。ボタン押下検出に必要な呼び出しです。

```js:public/main.js
import * as gpio from "gpio";
import * as input from "input";

function setup(){
	var ipaddress = esp32.getIpAddress();
	console.log("ipaddress=" + ((ipaddress >> 24) & 0xff) + "." + ((ipaddress >> 16) & 0xff) + "." + ((ipaddress >> 8) & 0xff) + "." + (ipaddress & 0xff));
	
	gpio.pinMode(10, gpio.OUTPUT);
	gpio.digitalWrite(10, gpio.LOW);
}

var led = true;

function loop(){
	esp32.update();
	
	if(input.wasPressed(input.BUTTON_A)){
		console.log('wasPressed');
		led = !led;
		gpio.digitalWrite(10, led ? gpio.LOW : gpio.HIGH );
	}
}
```

#終わりに

まだまだ機能はたくさん用意したので、次回説明します。
関数一覧を以下にまとめておきました。
　https://github.com/poruruba/QuickJS_ESP32/tree/main/doc

以下もご参考まで。
・[MakeCode for M5Core2 を作った](https://qiita.com/poruruba/items/be4b86a65af91c8dca45)
・[QuickJSでお手軽ESP32＋Javascript実行環境](https://qiita.com/poruruba/items/e159464305e5bab6e06e)

以上