Pythonロボティクスコース レッスン 12

テーマ.3-3 LEDディスプレイの高度な制御

LED ディスプレイを高度に制御するメソッドを学ぼう

このレッスンで学ぶこと

このレッスンでは、StuduinoBitImageクラスに用意されているメソッドや特殊な演算処理について学び、LEDディスプレイを利用した高度な表現を作ります。

LEDディスプレイの2つの制御方法

LEDディスプレイに絵や文字を表示させる方法は複数あります。例えば、下のパターンで点灯させるときの2つの方法を比べてみましょう。

2. 1 ① StuduinoBitDisplayクラスのメソッドで1つずつLEDを制御する

ひとつめは、StuduinoBitDisplayクラスのset_pixel()メソッドを使い、各LEDの位置を指定して制御する方法です。

StuduinoBitDisplay.set_pixel(x, y, color)
・・・LEDディスプレイの(x, y)の位置にあるLEDをcolorで指定した色で点灯させる。

Studuino:bitの各LEDの位置は次のx-y座標系で表されています。

そのため、上のパターンでLEDディスプレイを点灯させるためには、以下のプログラムを作ることになります。1行目で取り込んでいるdisplayはStuduinoBitDisplayクラスのインスタンスです。

【 サンプルコード 2-1-1 】

2. 2 ② StuduinoBitImageクラスで作成したイメージでLEDを制御する

もうひとつは、StuduinoBitImageクラスのインスタンスとしてイメージを作成し、それをStuduinoBitDisplayクラスのshow()メソッドで表示する方法です。

StuduinoBitImageクラスのインスタンス作成時に実行される__init__()メソッドでは、引数に座標ではなく、「 :(コロン)」区切りの文字列で点灯パターンを指定します。以下のように「 : 」までの5つの数字が横に並んだLEDの点灯と消灯のパターンを表しており、「1」で点灯し「0」で消灯します。

また、__init__()メソッドでは、点灯色も指定でき、以下のようにcolor=(R, G, B)の形式で渡します。

StuduinoBitImage('00000:01010:10001:01110', color=(31, 0, 0))

こうして作成したインスタンスをStuduinoBitDispayクラスのshow()メソッドの引数に渡すと、そのパターン通りにLEDディスプレイを点灯させることができます。

※1行目で取り込んでいるImageは、StuduinoBitImageクラスの省略したクラス名です。これにより、image = StuduinoBitImage(...)の代わりに、image = Image(...)でインスタンスが作成できます。

点灯パターンをイメージとして保存しておくことで、繰り返し利用できるだけでなく、次に紹介する方法を使って、そのイメージをベースとした新たな別のイメージを作成することもできます。

イメージを合成する

下のキリンのイメージは、黄色と茶色の2色を使ったパターンで表現されています。上で説明したStuduinoBitDisplayクラスのset_pixel()メソッドを使って1つ1つのLEDを個別に制御し、このパターンで点灯させることもできますが、コードの行数が多くなるため少し大変です。

一方で、このイメージは分解して2つのイメージを重ね合わせたものと考えることもできます。「+演算子」はこれまで数値計算を行ったり、文字列を連結したりするために使ってきましたが、StuduinoBitImageクラスでは、+演算子で2つのインスタンスのもつイメージを合成した新たなイメージのインスタンスを作成することができます。

3. 1 +演算子を利用したイメージの重ね合わせ

実際に+演算子を使い、上のキリンのイメージをもつインスタンスを作成してみましょう。まず、StuduinoBitImageクラスで黄色img_yellowと茶色img_brownの2つのイメージを用意します。

※変数名が長くなるため、imageではなく、省略してimgとしています。

この2のイメージを+演算子で足し合わせ、新たなイメージimg_giraffeを作成します。作成したイメージをStuduinoBitImageクラスのshow()メソッドで表示します。

※キリンは英語で「giraffe」と表します。
【 サンプルコード 3-1-1 】
追加【7行目、8行目】

これでプログラムの完成です。実行して結果を確認しましょう。

3. 2 色の重ね合わせ

さきほどのキリンのイメージは、LEDの点灯位置に重なりがない2つのイメージを合成して作りました。では、LEDの点灯位置に重なりがある場合はどうなるでしょうか。実は、2つの色を足し合わせてできる色で点灯するようになります。

  • 合成したイメージのR値 = イメージ1のR(赤)値 + イメージ1のR値
  • 合成したイメージのG値 = イメージ1のG(緑)値 + イメージ1のG値
  • 合成したイメージのB値 = イメージ1のB(青)値 + イメージ1のB値

そのため、光の3原色である赤、緑、青の3色のイメージから黄、シアン、マゼンタ、白の4色のイメージを作成することもできます。

では実際に、下のプログラムを書き、7色のイメージを用意してみましょう。

作成したイメージをタプルにまとめ、for文で順番に取り出して、LEDディスプレイに表示させてみます。これをさらにwhile文で囲むと、繰り返し色が変化するイルミネーションライトになります。

【 サンプルコード 3-2-1 】
追加【12行目、14行目~16行目】
for a in A: でAにタプルやリストを指定すると、その要素を順番に取り出して変数aに格納して内部のコードを実行する反復処理になります。このループは要素を全て取り出すと終了します。

完成したプログラムを実行して、動作を確認しましょう。

3. 3 2色を使ったイメージによるアニメーション

ここまでで、+演算子を利用すると、複数の色をもつイメージをイメージどうしを合成することで簡単に作成できることを確認してきました。そこでこれを応用して、2つのイメージを交互に表示してカメが泳いでいるように見えるアニメーションを作成してみましょう。

■ プログラムの作成

上の2つのイメージには共通している部分があります。それは緑色の甲羅の部分です。そこで、この共通している甲羅のイメージとそれぞれの手足の部分の合計3つのイメージを作成し、それらを合成して2つの亀のイメージを作成する以下のコードを書きます。

※亀は英語で「turtle」、甲羅は英語で「shell」と表します。

これら2つのイメージ「img_turtle1」と「img_turtle2」を交互に表示することでアニメーションが完成します。

【 サンプルコード 3-3-1 】
追加【13行目~15行目】

完成したプログラムを実行して、動作を確認しましょう。

イメージのシフト

StuduinoBitImageクラスには、イメージを上下左右に指定したピクセル分だけシフト(移動)し、新たなイメージを作成するメソッドが用意されています。そのメソッドとfor文を組み合わせると、簡単にイメージがLEDディスプレイ上を流れるようなアニメーションが作成できます。

4. 1 左右方向のシフト

イメージを左右方向にシフトさせるときは、shift_left()メソッドとshift_right()メソッドを使います。

StuduinoBitImage.shift_left(n)
・・・イメージをnピクセル分左にシフトした新たなイメージを返します。
StuduinoBitImage.shift_right(n)
・・・イメージをnピクセル分右にシフトした新たなイメージを返します。

実際に、上の図のように垂直な線が左右に1ピクセル分シフトしたイメージを作り、左から右へ垂直な線が移動するアニメーションを作成してみましょう。

■ プログラムの作成

はじめに、LEDディスプレイの中央に垂直な線を表示するためのイメージimg_lineを作成し、作成したイメージをStuduinoBitDisplayクラスのshow()メソッドで表示しましょう。

次に、shift_left()メソッドとshift_right()メソッドを使い、img_lineの表示前と後に左右へ1ピクセルシフトさせたイメージを表示します。

【 サンプルコード 4-1-1 】
追加【5行目、7行目】

これで左から右へ垂直な線が移動するアニメーションになります。プログラムを実行して動作を確認しましょう。

shitf_left()メソッドやshift_right()メソッドは、負の数を引数に指定することもできます。その場合は、反対方向へシフトするため、結果としてshift_left(-1)shift_right(1)は同じイメージを返すことになります。実際に上の【 サンプルコード 4-1-1 】を下のように書き換えて実行し、同じ動作となることを確認しましょう。

【 サンプルコード 4-1-2 】
変更【5行目、7行目】

4. 2 上下方向のシフト

上下方向にイメージをシフトさせるときは、shift_up()メソッドとshift_down()メソッドを使います。

StuduinoBitImage.shift_up(n)
・・・イメージをnピクセル分上にシフトした新たなイメージを返します。
StuduinoBitImage.shift_down(n)
・・・イメージをnピクセル分下にシフトした新たなイメージを返します。

実際に、上の図のように水平な線が上下に1ピクセル分シフトしたイメージを作り、上から下へ水平な線が移動するアニメーションを作成してみましょう。

■ プログラムの作成

はじめに、LEDディスプレイの中央に水平な線を表示するためのイメージimg_lineを作成し、作成したイメージをStuduinoBitDisplayクラスのshow()メソッドで表示しましょう。

次に、shift_up()メソッドとshift_down()メソッドを使い、img_lineの表示前と後に上下へ1ピクセルシフトさせたイメージを表示します。

【 サンプルコード 4-2-1 】
追加【5行目、7行目】
from pystubit.board import display,Imageimport time img_line = Image("00000:00000:11111:00000:00000:", color=(31, 0, 0)) display.show(img_line.shift_up(1))display.show(img_line)display.show(img_line.shift_down(1))

これで上から下へ水平な線が移動するアニメーションになります。プログラムを実行して動作を確認しましょう。

また、これらのメソッドも引数に負の数を指定できます。そのため、shift_up(-1)とshift_down(1)は同じイメージを返します。こちらも実際に上の【 サンプルコード 4-2-1 】を下のように書き換えて、同じ動作となることを確認しましょう。

【 サンプルコード 4-2-2 】
変更【5行目、7行目】

4. 3 シフトメソッドを利用したディスプレイ上を流れるアニメーションの作成

学習したシフトメソッドを利用すると、StuduinoBitDisplayクラスのscroll()メソッドと同じく、文字が横切って流れていく表現が作成できます。ここでは例として、下のコードと同じく、アルファベットの「A」が繰り返し流れるアニメーションを作成してみましょう。

■ プログラムの作成

はじめに、流す文字「A」のイメージを作成します。

次に、作成したイメージをディスプレイの右端から左端へ流すとき、両端にあたるイメージが元のイメージを何ピクセル分シフトさせたものになるのかを考えます。左端は4ピクセル分、右端は5ピクセル分になります。また、ここではプログラムを簡単にするため、shift_left(-n)shift_right(n)で作成されるイメ―ジが同じだったことから、shift_left()メソッドだけですべてのイメージを作成します。

※shift_left(0)は元のイメージと同じイメージを返します。

for文と標準関数のrange()で、右端から左端へ向かって順番にシフトしたイメージを作成し、StuduinoBitDisplayクラスのshow()メソッドでLEDディスプレイに表示します。また、下のコードでは、range()関数には負の数を引数として渡すことで、「-5~4」のように負の値から順番に並んだ数字を得ています。

変更【5行目~7行目】
range(-5, 5)と指定した場合、作成される数字のリストには5が含まれないことに注意しましょう。

完成したプログラムを実行して、scroll()メソッドを使ったときと同じ表現ができていることを確認しましょう。こ

課題:+演算子とシフトメソッドを組み合わせたイルミネーションライトの作成

ここまでで学習した内容を踏まえて、次のように2色の線がシフトするアニメーションを合成したイルミネーションライト作成しましょう。

5. 1 プログラムの作成

水平な線と垂直な線のイメージをそれぞれ作成し、shift_right()メソッドとshift_down()メソッドでシフトしたイメージを作ります。その2つを+演算子で合成すると、上のアニメーションのイメ―ジが得られます。

はじめに、水平な赤色の線と垂直な青色の線のイメージを作成し、合成してディスプレイに表示します。

※「horizontal」は英語で「水平な」の意味を、「vertical」は英語で「垂直な」の意味を表します。

次に、for文を使って、水平な線を下へ、垂直な線を右へ向かって1ピクセルずつ順番にシフトさせ、それらを合成したイメージを表示するようにします。できたら、ここまでのプログラムを実行して、動作を確認しましょう。

追加・変更【6行目~8行目】

今度はそれぞれの線を反対向きに1ピクセルずつ順番にシフトさせます。range(4, -1, -1)のように、第3引数に負の数「-1」と指定すると、順番に1ずつ小さくなる数字の並び「4, 3, 2, 1, 0」が得られます。これを引数に指定してイメージを作成します。

追加【9行目~11行目】

最後に、while文を使った永久ループでアニメーションを繰り返すようにして、プログラムの完成です。実行して動作を確認しましょう。

【 サンプルコード 5-1-1 】
追加・変更【6行目~12行目】

おわりに

6. 1 このレッスンのまとめ

このレッスンでは、StuduinoBitDisplayクラスの+演算子やシフトメソッドを利用することで、LEDディスプレイの高度な制御ができることを確認しました。

6. 2 次回のレッスンについて

次のレッスンでは、関数やメソッドの引数の種類について学習し、StuduinoBitDisplayクラスのshow()メソッドやscroll()メソッドの引数と表示形式の関係を確認します。

TOP