先週、ESP32を標準JavaScript(以下、ECMAScriptと呼びます)でプログラミングできる環境”Moddable SDK”があると知りました。
さっそく”Moddable SDK”を導入してみました。→「ESP32をJavaScriptで動かすModdable SDK

SDK付属のサンプルプログラムを眺めたり動かしたりしてESP32+ECMAScriptでのプログラミングのし方を学びました。
自前で「Lチカ」プログラムを書いて動かすことができました。ECMAScriptの特性を使うと興味深い「Lチカ」ができるので、ここに掲載したいと思います。

  1. 基本のLチカ
    1. 回路図
      IO5でLEDを制御。
    2. プログラム1
      import Timer from 'timer'            // タイマーモジュールを使う
      import Digital from 'pins/digital'   // デジタルピン制御のモジュールを使う
      
      let led = 5          // IO5を指す値を変数ledに代入
      let sts = 0          // 変数stsはLEDのON-OFF状態を格納。0:OFF, ~0:ON
      
      // Blink LED
      Timer.repeat(() => {          // repeatメソッドで{}範囲を無限ループ
        Digital.write(led, sts)     // ledが指すピンをstsの状態にする
        sts = ~sts                  // stsの論理を反転する。not処理
      }, 300)                       // ループ1回毎に300ミリ秒待つ

      バイナリコードのビルドにはプログラムが要求するモジュールを組み込むためのmanifest.jsonが必要です

      {
      	"include": [
      		"$(MODDABLE)/examples/manifest_base.json",
      		"$(MODULES)/pins/digital/manifest.json",
      	],
      	"modules": {
      		"*": "./main",
      	},
      }
    3. プログラム2
      繰り返し処理部分を関数化してみました

      import Timer from 'timer'
      import Digital from 'pins/digital'
      
      // Blink LED                        // blink関数宣言
      function blink (led, interval) {    // 引数 led:制御ピン  interval:待ち時間
        let sts = 0
        Timer.repeat(() => {
          sts = ~sts
          Digital.write(led, sts)
        }, interval)
      }
      
      let ledA = 5       // IO5
      blink(ledA, 300)   // blink関数呼び出し LED A を300ミリ秒間隔で点滅
  2. 2個Lチカ
    1. 回路図
      IO5でLED-Aを,IO4でLED-Bを制御
    2. プログラム1
      import Timer from 'timer'
      import Digital from 'pins/digital'
      
      // Blink LED
      function blink (led, interval) {
        let sts = 0
        Timer.repeat(() => {
          sts = ~sts
          Digital.write(led, sts)
        }, interval)
      }
      
      let ledA = 5 // IO5
      let ledB = 4 // IO4
      
      blink(ledA, 300) // blink関数呼び出し LED A を300ミリ秒間隔で点滅
      blink(ledB, 300) // blink関数呼び出し LED B を300ミリ秒間隔で点滅
      1. C/C++な人だと「このプログラムは blink(ledA, 300) で無限ループに入り、blink(ledB, 300)は実行されないじゃん」と思われることでしょう。
      2. しかし、ECMAScriptでは、この2つの関数呼び出しは同時に実行され、それそれが無限ループに入ってLED A, LED BをLチカします….つまり並列処理が行われる訳です。
      3. このプログラムでは LED A と LED B は同時点滅します。
    3. プログラム2
      LED A と LED B の点滅間隔を異なる値にしてみます。

      import Timer from 'timer'
      import Digital from 'pins/digital'
      
      // Blink LED
      function blink (led, interval) {
        let sts = 0
        Timer.repeat(() => {
          sts = ~sts
          Digital.write(led, sts)
        }, interval)
      }
      
      let ledA = 5 // IO5
      let ledB = 4 // IO4
      
      blink(ledA, 300)
      blink(ledB, 500)
      1. LED A は300ミリ秒間隔で、LED B は500ミリ秒間隔で独立して点滅をします。
      2. この動作をarduinoのC/C++で実現しようとするとメンドクサイです。
        arduinoではタイマー割り込みとカウンターを使って300ミリ秒、500ミリ秒インターバルを検知するような方法がよく用いられます。
      3. ECMAScriptでは何も考えずに処理・関数を並べるだけで並列処理が実行されます。
        この特徴をうまく使えば、センサーの値を読み取りつつ複数のLED表示を変化させつつホストと通信をするようなプログラムが楽々と書けることでしょう。

Moddable SDKはM5Stackにも対応してしています –> M5StackをJavaScriptでプログラミング

Follow me!