ESP32をBlocklyで動かしてみた

以前、以下の投稿で、ESP32上でMakecodeを使ったノーコードプログラミングを動作させました。

・[MakeCode for M5Core2 を作った](https://qiita.com/poruruba/items/be4b86a65af91c8dca45)
・[MakeCode for micro:bitで作ったプロジェクトをM5Atomで動かす](https://qiita.com/poruruba/items/8feed48b7dccb218f29b)

これをベースに、いろいろ拡張しようと思ったのですが、いろいろ制限がきついので、いっそのこと、素のBlocklyをベースにノーコードプログラミング環境を作ろうかなあと思いました。
UIFlowもBlocklyをベースにしているようで、同様のことを、自分の好きなように作りこんでいこうと思います。

Blockly | Google Developers

https://developers.google.com/blockly

ESP32側は以下のファームウェアを使っています。Javascript実行環境をESP32上に構築したもので、手軽にIoTができるようにしています。

電子書籍：M5StackとJavascriptではじめるIoTデバイス制御

https://poruruba.booth.pm/items/3735175

# 全体の構成

全体構成は以下の通りです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261826/53c1cc39-6847-6516-6ba3-246f0aad24cc.png)

あらかじめJavascript実行環境のファームウェアを、ESP32に書き込んでいます。この書き込みは最初の一回のみです。

①Blockページの表示
　ESP32に書き込んでおいたファームウェアには、Webサーバ機能を搭載しており、BlocklyのWebページを提供しています。それをブラウザから表示します。
②ノーコードプログラミング
　ブラウザ上から、Blocklyページで、ブロックを組み合わせてノーコードプログラミングを行います。ScratchやMakeCodeなど、ブロック操作は一般的になっていますので、特に違和感なく操作できるかと思います。
③Javascript生成＋アップロード
　「Show & Upload Javascript」ボタンを押下することで、作成したブロックがJavascriptコードに変換され、ESP32にアップロードされます。ESP32では、受け取ったJavascriptコードをSPIFFSに保存します。
④Javascript実行
　自動的にJavascript実行環境がリスタートし、SPIFFSに保存したJavascriptコードを実行します。後程示す例では、LEDを1秒間隔で点滅させてます。

SPIFFSに書き込んだ内容は、不揮発メモリへの保存であるため、ESP32電源Off/On後も覚えています。

BlocklyのWebページは以下のような感じです。ESP32がWebサーバになっているので、別途Webサーバを立ち上げる必要はありません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261826/00978667-7a5a-9e82-ae5f-f2ef9828d24a.png)

以下のページを参照し、Blocklyタブを選択後、Create Workspaceボタンを押すことで直接触れられます。
※ただし、ESP32にアップロードする場合は、HTTPとHTTPSでMixed Contentsエラーとなるため、解除するかローカルにダウンロードして直接index.htmlファイルをブラウザから参照する必要があります。

https://poruruba.github.io/QuickJS_ESP32_IoT_Device/QuickJS_ESP32_Firmware/data/html/


# ブロック例（LED自動点滅）

以下例を示します。M5StickCを利用します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261826/f2c2c40a-29cf-03db-d691-c1d0ee54ef6f.png)

Javascript実行環境で用意してある関数名をそのままブロックにしているため、まだまだ、初めての方にはわかりにくいかと思いますが、Blocklyのカスタムブロックは結構簡単に作れるので、今後ブロックの追加やリバイスをしていこうと思います。

簡単に説明すると、

・以降でGpioライブラリを利用するので、Gpioライブラリをインポートしています。
・Arduinoでいうところの、pinMode()です。LEDは10番にある想定です。
・JavascriptのsetInverval()です。Arduinoでは一般的ではないですが、Javascriptでは超一般的です。1000秒間隔で実行するロジックを定義しています。
・ArduinoでいうところのdigitalWrite()でLEDをOnにしています。
・Arduinoでいうところのdelay()で、500msecのウェイトを入れています。
・ArduinoでいうところのdigitalWrite()でLEDをOffにしています。
・Arduinoでいうところのdelay()で、500msecのウェイトを入れています。
・これをsetIntervalで繰り返し。

これがJavascriptに変換されると以下になります。

```js
import * as gpio from 'Gpio';
gpio.pinMode(10, gpio.OUTPUT);
setInterval( () => {
  gpio.digitalWrite(10, gpio.LOW);
  delay(500);
  gpio.digitalWrite(10, gpio.HIGH);
  delay(500);
}, 1000);
```

Javascriptをご存じの方は説明はいらないですね。。。とはいっても、ブロックから勝手にJavascriptに変換されて、勝手にESP32にアップロードされて、勝手に実行されるので、内容は気にしなくてもよいでしょう。

# ブロック例（LED手動点滅）

ついでに、もう一つ例を示します。
M5Atom Matrixを利用します。ボタンを押すたびに、LED点灯の数が増えていきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261826/6336f38d-512f-4fc3-078d-4409a7979849.png)

2つのブロックの塊があります。1つ目は初期化処理、2つ目はボタンが押されたときの処理です。

初期化処理
・以降でInputとPixelsとUtilsライブラリを利用するので、それぞれのライブラリをインポートしています。
・5x5のRGBマトリクスLEDの初期化処理です。27番PINに接続されています。5x5の計25個のLEDがあります。
・いったん、すべてのLEDを消去します。

ボタンが押されたときの処理
・変数counterが示す番号のLEDを赤色で点灯させます。
・変数counterを１インクリメントします。
・もし変数counterが25以上になったら、それ以上LEDは搭載されていないので、以降で示す追加の処理をします。
・変数counterを0にします。
・すべてのLEDを消去します。

これがJavascriptに変換されると以下になります。

```js
var counter;


import * as input from 'Input';
import * as pixels from 'Pixels';
import * as utils from 'Utils';
pixels.begin(27, 25);
pixels.clear();

input.onButtonWasPressed(input.BUTTON_A, () => {
  pixels.setPixelColor(counter, (utils.rgb2Number('#ff0000')));
  counter = (typeof counter === 'number' ? counter : 0) + 1;
  if (counter >= 25) {
    counter = 0;
    pixels.clear();
  }
});
```

いかがでしょうか、簡単な操作でLチカできたのではないでしょうか。

# カスタムブロック(暫定)

ほかにも、ブロックを用意しています。
とりあえず、以下のカスタムブロックを用意しました。

まずは、基本的なブロックです。どちらかというと、今回のJavascript実行環境に依存したものかもしれません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261826/1ae414a5-fe1a-fee6-df33-f0bb1533863a.png)

次は、タイムアウト系のブロックです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261826/17b5c504-d31a-2c6d-a121-812c7a8e4a96.png)

次は、GPIOを操作のためのブロックです。arduinoっぽいI/Fです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261826/37c4c24f-9e5e-59ef-90bf-935002ea3eb8.png)

次が、ボタン系のブロックです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261826/18a2df27-70b2-cb41-d752-854d2a0780cd.png)

次が、RGBマトリクスLEDの操作用ブロックです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261826/0d13a716-0eb0-29f8-960d-e45bea3c425e.png)

最後がユーティリティで、#RRGGBBという文字列を0xRRGGBBという数値に変換するためのブロックです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261826/430599e8-3333-5437-3a3c-4495564ea950.png)

# 標準ブロック

すでにBlocklyに備わっていた標準ブロックも示しておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261826/adf3f6a2-9dda-208b-7fdd-15a29dbf259a.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261826/48ad1dbd-a05a-f32b-a410-0593c6b12bfa.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261826/f974b7f1-5d16-c8a8-c927-2a403c049a81.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261826/e776a639-c03e-804f-c548-8451bb9f645b.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261826/b5f81d23-be57-10f3-a5b0-0bede0078543.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261826/689523da-d813-bdba-d371-aa74753f095c.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261826/4a784306-d987-ba4b-21cb-7263b2256448.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261826/1c19d621-2ccb-2938-c93b-d8cd9b7acf78.png)

# 終わりに

Blocklyは、カスタマイズ性が強いので、今後いろいろな機能を追加できそうで楽しみです。

Javascript環境を有したESP32用のファームウェアは以下で紹介しています。

電子書籍：M5StackとJavascriptではじめるIoTデバイス制御

https://poruruba.booth.pm/items/3735175

サポート情報やファームウェアは以下にありますので、ぜひ電子書籍のご購入を！

poruruba/QuickJS_ESP32_IoT_Device

https://github.com/poruruba/QuickJS_ESP32_IoT_Device

以上