5×5 LEDでのアニメーション

 今回はマイクロビットのLEDでアニメーションを表示してみましょう。マイクロビットはJavaScriptとPython (micro Python) のどちらかでプログラミングすることができます。手軽なJavaScriptでプログラムを作成している人の方が多いでしょう。しかし、JavaScriptだけではマイクロビットのLED表示性能を発揮することはできません。そこで、今回はPythonも使ってマイクロビットのLED性能を発揮させてみます。
 まず、JavaScriptでアニメーションを作成し、その後にPythonでアニメーションを作成することにします。

・JavaScript用マイクロビット エディター
https://makecode.microbit.org/

アニメーションさせる

 最初に作成するアニメーションは、至ってシンプルな人が走るだけのプログラムです。人が走るパターンを2つ用意し、一定時間ごと切り替えるだけです。プログラムは以下のように組み合わせます。

  • JavaScript用マイクロビット ブロックエディタでの構造

    JavaScript用マイクロビット ブロックエディタでの構造

JavaScriptコードだと以下のようになります。

 basic.forever(() => {
     basic.showLeds(`
         . . # . .
         . . # # .
         . # # . .
         . . # # .
         . . # . .
         `)
     basic.pause(500)
     basic.showLeds(`
         . . # . .
         . # # . .
         . . # # .
         . . # . .
         . # . # .
         `)
     basic.pause(500)
 })

プログラムができたらマイクロビットに転送して動作を確認してみましょう。人が走るようなアニメーションが表示されます。

  • 人が走るようなイメージを表現したアニメーション
  • 人が走るようなイメージを表現したアニメーション
  • 人が走るようなイメージを表現したアニメーション

次にこの人を右から左に走らせてみましょう。ここは、頑張ってドットで人を走らせるように描きます。
プログラムは以下のように組み合わせます。

JavaScriptコードだと以下のようになります。

 basic.forever(() => {
     basic.showLeds(`
         . . . . .
         . . . . #
         . . . . .
         . . . . .
         . . . . .
         `)
     basic.pause(100)
     basic.showLeds(`
         . . . . #
         . . . . #
         . . . # #
         . . . . #
         . . . . #
         `)
     basic.pause(100)
     basic.showLeds(`
         . . . # .
         . . # # .
         . . . # #
         . . . # .
         . . # . #
         `)
     basic.pause(100)
     basic.showLeds(`
         . . # . .
         . . # # .
         . # # . .
         . . # # .
         . . # . .
         `)
     basic.pause(100)
     basic.showLeds(`
         . # . . .
         # # . . .
         . # # . .
         . # . . .
         # . # . .
         `)
     basic.pause(100)
     basic.showLeds(`
         # . . . .
         # # . . .
         # . . . .
         # # . . .
         # . . . .
         `)
     basic.pause(100)
     basic.showLeds(`
         . . . . .
         . . . . .
         # . . . .
         . . . . .
         # . . . .
         `)
     basic.pause(100)
     basic.showLeds(`
         . . . . .
         . . . . .
         . . . . .
         . . . . .
         . . . . .
         `)
     basic.pause(1000)
 })

プログラムができたらマイクロビットに転送して動作を確認してみましょう。人が右から走ってきて左に消えて行くアニメーションが表示されます。
アニメーションが遅いなと感じたらウェイトを少なくするか、ブロックを削除してください。マイクロビットのJavaScriptを使った場合、ウェイト無しでも思ったほど速くなりません。

プログラムを自動生成する

 手作業でアニメーションパターンを描いてくのは面白いのですが、とにかく手間と時間がかかります。そこで、今度はプログラムを使ってマイクロビットのプログラムを自動生成してみます。
 ここでは横45ドット×縦5行サイズの画像を右から左にスライドさせるようなアニメーションを自動生成することにします。なお、45ドットのうち行末の5ドットは先頭と同じパターンにしてください。これは繰り返し同じパターンを表示するためです。
 自動的に生成するプログラムはWebブラウザ(Google ChromeやSafari)で動くものを用意しました。テキストエリアに#か.を指定しconvertボタンをクリックするとページ上にマイクロビットのJavaScriptが生成させます。あとは、これをコピーし、JavaScriptエディタにペーストするだけです。ペーストした後にJavaScriptブロックエディタに戻します。再度JavaScriptエディタに切り替えるとプログラムは綺麗に整形されて表示されます。
 なお、テキストエリアの文字で.ならLED消灯、#ならLED点灯となります。

  • プログラム自動生成HTML。フォーム部に.(LED消灯)/#(LED点灯)を入力して「convert」ボタンを押すと、マイクロビット用のコードを生成する

    プログラム自動生成HTML。フォーム部に.(LED消灯)/#(LED点灯)を入力して「convert」ボタンを押すと、マイクロビット用のコードを生成する)

プログラム自動生成HTML(JavaScript版マイクロビットエディタ用)

 <!DOCTYPE html>
 <html>
 <head>
 <meta charset="utf-8">
 <title>mbit-conv</title>
 <style>*{font-family:courier;}</style>
 <script>
 function conv(){
    var w=45,wait=0;
    var data="basic.forever(() => {<br>";
    var t=document.getElementById("mbit").value;
    t=t.replace(/\n/g,"").replace(/\r/g,"");
    for(var i=0; i<w-5; i++){
        data+="basic.showLeds(`<br>";
        for(var y=0; y<5; y++){
            for(var x=0; x<5; x++){
                data+=t.charAt((y*w+x)+i);
            }
        }
        data+="`)<br>";
        data+="basic.pause("+wait+")<br>";
    }
    data+="})";
    document.getElementById("result").innerHTML=data;
 }
 </script>
 </head>
 <body>
 <textarea id="mbit" cols="45" rows="5">
 ..................................#.#........
 ............#.......#.............#.#........
 ...#.......###......#.........#...#.#......#.
 ..####...######....###..#...#.#.#.#.#.....###
 #################.########..#.###.###########
 </textarea>
 <input type="button" value="convert" onclick="conv()">
 <div id="result"></div>
 </body>
 </html>

生成されたプログラムをマイクロビットに転送して、期待通りにアニメーションするかどうか確認してみましょう。
なお、生成するアニメーションの横サイズを変更する場合は

 var w=45,wait=0;

のw=45の値を、ウェイトを調整する場合はwait=0の値を変更してください。

  • 生成されたデータをJavaScript用マイクロビットで動作させたところ
  • 生成されたデータをJavaScript用マイクロビットで動作させたところ
  • 生成されたデータをマイクロビットで動作させたところ

Pythonでアニメーション

 それでは次にPythonを使ってアニメーションさせてみます。まずは、人が2パターンで走るプログラムです。Pythonの場合、ブロックエディタがないので命令を入力していくことになります。
 実際のプログラムは以下のようになります。

Python用のマイクロビット エディター
http://python.microbit.org/v/1
 from microbit import *

 while True:
     display.show(Image(
              "00900:"
              "00990:"
              "09900:"
              "00990:"
              "00900"))
     sleep(500)
     display.show(Image(
              "00900:"
              "09900:"
              "00990:"
              "00900:"
              "09090"))
     sleep(500)

display.show()は指定されたイメージパターンをLEDに表示します。自作パターンの場合はImage()内にパターンを指定します。0〜9までの数値がLEDの輝度になります。0なら消灯で9なら最も明るく点灯することになります。1文字が1ドットに対応し行末区切りとして:(コロン)を指定します。なお、パターンは以下のように1行にまとめて書くこともできます。自動生成する場合は、このような形で生成することにします。
マイクロビットのPythonは高速なのでsleep()を使ってウェイトを入れます。ウェイトなしで動作させてみると、いかに処理が速いかがわかりますので、ぜひ試してみてください。

 from microbit import *

 while True:
     display.show(Image("00900:00990:09900:00990:00900"))
     sleep(500)
     display.show(Image("00900:09900:00990:00900:09090"))
     sleep(500)

それでは最後にブラウザのJavaScriptでマイクロビットのPythonプログラムを生成します。使い方はJavaScriptプログラムを自動生成するものと同じです。異なるのはテキストエリアに書く文字です。Pythonの場合は.と#ではなく0〜9までの数字を書きます。これが、そのままLEDの明るさになります。JavaScript版と比べてより豊かな(?)表現が可能になっています。

プログラム自動生成HTML(Python版マイクロビットエディタ用)

 <!DOCTYPE html>
 <html>
 <head>
 <meta charset="utf-8">
 <title>mbit-conv</title>
 <style>*{font-family:courier;}</style>
 <script>
 function conv(){
    var w=45,wait=100;
    var data="from microbit import *<br><br>while True:<br>";
    var t=document.getElementById("mbit").value;
    t=t.replace(/\n/g,"").replace(/\r/g,"");
    for(var i=0; i<w-5; i++){
        data+='  display.show(Image("';
        for(var y=0; y<5; y++){
            for(var x=0; x<5; x++){
                data+=t.charAt((y*w+x)+i);
            }
            if(y!=4){ data+=":"; }
        }
        data+='"))<br>';
        data+="  sleep("+wait+")<br>";
    }
    document.getElementById("result").innerHTML=data;
 }
 </script>
 </head>
 <body>
 <textarea id="mbit" cols="45" rows="5">
 000000000000000000000000000000000020100000000
 000000000000900000009000000000000040300000000
 000900000009920000008000000000500060500000090
 009792000877942000076900700070709080700000979
 97654213765999421.646543530090949094945697654
 </textarea>
 <input type="button" value="convert" onclick="conv()">
 <pre id="result"></pre>
 </body>
 </html>

生成されたプログラムをマイクロビットに転送して、期待通りにアニメーションするかどうか確認してみましょう。
なお、生成するアニメーションの横サイズを変更する場合は

 var w=45,wait=100;

のw=45の値を、ウェイトを調整する場合はwait=0の値を変更してください。ここらへんはJavaScript版と変わりません。
なお、Pythonの場合、ウェイトを入れないと速すぎてアニメーションに見えませんので注意してください。

 from microbit import *

 while True:
   display.show(Image("00000:00000:00090:00979:97654"))
   sleep(100)
   display.show(Image("00000:00000:00900:09792:76542"))
   sleep(100)
   display.show(Image("00000:00000:09000:97920:65421"))
   sleep(100)
   display.show(Image("00000:00000:90000:79200:54213"))
   sleep(100)
   display.show(Image("00000:00000:00000:92000:42137"))
   sleep(100)
   display.show(Image("00000:00000:00000:20008:21376"))
   sleep(100)
   display.show(Image("00000:00000:00000:00087:13765"))
   sleep(100)
   display.show(Image("00000:00000:00009:00877:37659"))
   sleep(100)
   display.show(Image("00000:00009:00099:08779:76599"))
   sleep(100)
   display.show(Image("00000:00090:00992:87794:65999"))
   sleep(100)
   display.show(Image("00000:00900:09920:77942:59994"))
   sleep(100)
   display.show(Image("00000:09000:99200:79420:99942"))
   sleep(100)
   display.show(Image("00000:90000:92000:94200:99421"))
   sleep(100)
   display.show(Image("00000:00000:20000:42000:9421."))
   sleep(100)
   display.show(Image("00000:00000:00000:20000:421.6"))
   sleep(100)
   display.show(Image("00000:00000:00000:00007:21.64"))
   sleep(100)
   display.show(Image("00000:00009:00008:00076:1.646"))
   sleep(100)
   display.show(Image("00000:00090:00080:00769:.6465"))
   sleep(100)
   display.show(Image("00000:00900:00800:07690:64654"))
   sleep(100)
   display.show(Image("00000:09000:08000:76900:46543"))
   sleep(100)
   display.show(Image("00000:90000:80000:69007:65435"))
   sleep(100)
   display.show(Image("00000:00000:00000:90070:54353"))
   sleep(100)
   display.show(Image("00000:00000:00000:00700:43530"))
   sleep(100)
   display.show(Image("00000:00000:00000:07000:35300"))
   sleep(100)
   display.show(Image("00000:00000:00000:70007:53009"))
   sleep(100)
   display.show(Image("00000:00000:00000:00070:30090"))
   sleep(100)
   display.show(Image("00000:00000:00005:00707:00909"))
   sleep(100)
   display.show(Image("00000:00000:00050:07070:09094"))
   sleep(100)
   display.show(Image("00000:00000:00500:70709:90949"))
   sleep(100)
   display.show(Image("00000:00000:05000:07090:09490"))
   sleep(100)
   display.show(Image("00002:00004:50006:70908:94909"))
   sleep(100)
   display.show(Image("00020:00040:00060:09080:49094"))
   sleep(100)
   display.show(Image("00201:00403:00605:90807:90949"))
   sleep(100)
   display.show(Image("02010:04030:06050:08070:09494"))
   sleep(100)
   display.show(Image("20100:40300:60500:80700:94945"))
   sleep(100)
   display.show(Image("01000:03000:05000:07000:49456"))
   sleep(100)
   display.show(Image("10000:30000:50000:70000:94569"))
   sleep(100)
   display.show(Image("00000:00000:00000:00000:45697"))
   sleep(100)
   display.show(Image("00000:00000:00000:00009:56976"))
   sleep(100)
   display.show(Image("00000:00000:00009:00097:69765"))
   sleep(100)
  • Pythonで作成したコードをマイクロビットに転送して動作させたところ
  • Pythonで作成したコードをマイクロビットに転送して動作させたところ
  • Pythonで作成したコードをマイクロビットに転送して動作させたところ

  • LEDの濃度の表現と速度が高速に
  • LEDの濃度の表現と速度が高速に
  • LEDの濃度の表現と速度が高速に

今回はプログラムでプログラムを自動生成しました。このような手法は古くからあります。アニメーションに限らず手作業では面倒なことをプログラムを使って解決してみると、よい勉強になるでしょう。

著者 古籏一浩
プログラミングをベースにして面白そうなものはとりあえずやってみるというスタンス。複雑なものよりシンプルで楽しめるものが好み。最近は30年前に移植したゲーム(mz-700版 SPACE HARRIER)の話などを書いたりしています。
著者サイト:http://www.openspc2.org/