Pythonロボティクスコース レッスン 12
テーマ.3-3 LEDディスプレイの高度な制御
LED ディスプレイを高度に制御するメソッドを学ぼう
チャプター1
このレッスンで学ぶこと
このレッスンでは、StuduinoBitImageクラスに用意されているメソッドや特殊な演算処理について学び、LEDディスプレイを利用した高度な表現を作ります。
チャプター2
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 】
1. from pystubit.board import display
2.
3 RED = (31, 0, 0)
4. display.set_pixel(1, 1, RED)
5. display.set_pixel(3, 1, RED)
6. display.set_pixel(0, 3, RED)
7. display.set_pixel(4, 3, RED)
8. display.set_pixel(1, 4, RED)
9. display.set_pixel(2, 4, RED)
10. display.set_pixel(3, 4, RED)
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. from pystubit.board import display,Image
2.
3. image = Image('00000:01010:00000:10001:01110:', color=(31, 0, 0))
4. display.show(image)
※1行目で取り込んでいるImage
は、StuduinoBitImageクラスの省略したクラス名です。これにより、image = StuduinoBitImage(...)
の代わりに、image = Image(...)
でインスタンスが作成できます。
点灯パターンをイメージとして保存しておくことで、繰り返し利用できるだけでなく、次に紹介する方法を使って、そのイメージをベースとした新たな別のイメージを作成することもできます。
チャプター3
イメージを合成する
下のキリンのイメージは、黄色と茶色の2色を使ったパターンで表現されています。上で説明したStuduinoBitDisplayクラスのset_pixel()
メソッドを使って1つ1つのLEDを個別に制御し、このパターンで点灯させることもできますが、コードの行数が多くなるため少し大変です。
一方で、このイメージは分解して2つのイメージを重ね合わせたものと考えることもできます。「+演算子」はこれまで数値計算を行ったり、文字列を連結したりするために使ってきましたが、StuduinoBitImageクラスでは、+演算子で2つのインスタンスのもつイメージを合成した新たなイメージのインスタンスを作成することができます。
3. 1 +演算子を利用したイメージの重ね合わせ
実際に+演算子を使い、上のキリンのイメージをもつインスタンスを作成してみましょう。まず、StuduinoBitImageクラスで黄色img_yellow
と茶色img_brown
の2つのイメージを用意します。
※変数名が長くなるため、image
ではなく、省略してimg
としています。
1. from pystubit.board import display,Image
2.
3. YELLOW = (31, 31, 0)
4. BROWN = (4, 1, 1)
5. img_yellow = Image("10000:01000:00000:01010:00000",color=YELLOW)
6. img_brown = Image("01000:00000:01000:00100:01010",color=BROWN)
この2のイメージを+演算子で足し合わせ、新たなイメージimg_giraffe
を作成します。作成したイメージをStuduinoBitImageクラスのshow()
メソッドで表示します。
※キリンは英語で「giraffe」と表します。
【 サンプルコード 3-1-1 】
追加【7行目、8行目】
1. from pystubit.board import display, Image
2.
3. YELLOW = (31, 31, 0)
4. BROWN = (4, 1, 1)
5. img_yellow = Image("10000:01000:00000:01010:00000", color=YELLOW)
6. img_brown = Image("01000:00000:01000:00100:01010", color=BROWN)
7. img_giraffe = img_yellow + img_brown
8. display.show(img_giraffe)
これでプログラムの完成です。実行して結果を確認しましょう。
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色のイメージを用意してみましょう。
1. from pystubit.board import display,Image
2.
3. img_red = Image("11111:11111:11111:11111:11111", color=(31, 0, 0))
4. img_green = Image("11111:11111:11111:11111:11111", color=(0, 31, 0))
5. img_blue = Image("11111:11111:11111:11111:11111", color=(0, 0 ,31))
6.
7. img_yellow = img_red + img_green
8. img_cyan = img_green + img_blue
9. img_magenta = img_red + img_blue
10. img_white = img_red + img_green + img_blue
作成したイメージをタプルにまとめ、for文で順番に取り出して、LEDディスプレイに表示させてみます。これをさらにwhile文で囲むと、繰り返し色が変化するイルミネーションライトになります。
【 サンプルコード 3-2-1 】
追加【12行目、14行目~16行目】
1. from pystubit.board import display,Image
2.
3. img_red = Image("11111:11111:11111:11111:11111", color=(31, 0, 0))
4. img_green = Image("11111:11111:11111:11111:11111", color=(0, 31, 0))
5. img_blue = Image("11111:11111:11111:11111:11111", color=(0, 0 ,31))
6.
7. img_yellow = img_red + img_green
8. img_cyan = img_green + img_blue
9. img_magenta = img_red + img_blue
10. img_white = img_red + img_green + img_blue
11.
12. imgs = (img_red, img_green, img_blue, img_yellow, img_cyan, img_magenta, img_white)
13.
14. while True:
15. for img in imgs:
16. display.show(img)
※for a in A:
でA
にタプルやリストを指定すると、その要素を順番に取り出して変数a
に格納して内部のコードを実行する反復処理になります。このループは要素を全て取り出すと終了します。
完成したプログラムを実行して、動作を確認しましょう。
3. 3 2色を使ったイメージによるアニメーション
ここまでで、+演算子を利用すると、複数の色をもつイメージをイメージどうしを合成することで簡単に作成できることを確認してきました。そこでこれを応用して、2つのイメージを交互に表示してカメが泳いでいるように見えるアニメーションを作成してみましょう。
■ プログラムの作成
上の2つのイメージには共通している部分があります。それは緑色の甲羅の部分です。そこで、この共通している甲羅のイメージとそれぞれの手足の部分の合計3つのイメージを作成し、それらを合成して2つの亀のイメージを作成する以下のコードを書きます。
※亀は英語で「turtle」、甲羅は英語で「shell」と表します。
1. from pystubit.board import display,Image
2.
3. YELLOW = (31, 31, 0)
4. GREEN = (0, 31, 0)
5.
6. img_shell = Image("00000:01110:01110:01110:00000:", color=GREEN) #甲羅
7. img_hands_and_legs1 = Image("00100:10001:00000:00000:10001:", color=YELLOW) #左のイメージの亀の手足
8. img_hands_and_legs2 = Image("00100:00000:10001:00000:01010:", color=YELLOW) #右のイメージの亀の手足
9.
10. img_turtle1 = img_shell + img_hands_and_legs1 # 左のイメージ
11. img_turtle2 = img_shell + img_hands_and_legs2 # 右のイメージ
これら2つのイメージ「img_turtle1
」と「img_turtle2
」を交互に表示することでアニメーションが完成します。
【 サンプルコード 3-3-1 】
追加【13行目~15行目】
1. from pystubit.board import display,Image
2.
3. YELLOW = (31, 31, 0)
4. GREEN = (0, 31, 0)
5.
6. img_shell = Image("00000:01110:01110:01110:00000:", color=GREEN)
7. img_hands_and_legs1 = Image("00100:10001:00000:00000:10001:", color=YELLOW)
8. img_hands_and_legs2 = Image("00100:00000:10001:00000:01010:", color=YELLOW)
9.
10. img_turtle1 = img_shell + img_hands_and_legs1
11. img_turtle2 = img_shell + img_hands_and_legs2
12.
13. while True:
14. display.show(img_turtle1)
15. display.show(img_turtle2)
完成したプログラムを実行して、動作を確認しましょう。
チャプター4
イメージのシフト
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()
メソッドで表示しましょう。
1. from pystubit.board import display, Image
2.
3. img_line = Image("00100:00100:00100:00100:00100:", color=(31, 0, 0))
4.
5. display.show(img_line)
次に、shift_left()
メソッドとshift_right()
メソッドを使い、img_line
の表示前と後に左右へ1ピクセルシフトさせたイメージを表示します。
【 サンプルコード 4-1-1 】
追加【5行目、7行目】
1. from pystubit.board import display, Image
2.
3. img_line = Image("00100:00100:00100:00100:00100:", color=(31, 0, 0))
4.
5. display.show(img_line.shift_left(1)) #左へ1ピクセル分シフトしたイメージ
6. display.show(img_line)
7. display.show(img_line.shift_right(1)) #右へ1ピクセル分シフトしたイメージ
これで左から右へ垂直な線が移動するアニメーションになります。プログラムを実行して動作を確認しましょう。
shitf_left()
メソッドやshift_right()
メソッドは、負の数を引数に指定することもできます。その場合は、反対方向へシフトするため、結果としてshift_left(-1)
とshift_right(1)
は同じイメージを返すことになります。実際に上の【 サンプルコード 4-1-1 】を下のように書き換えて実行し、同じ動作となることを確認しましょう。
【 サンプルコード 4-1-2 】
変更【5行目、7行目】
1. from pystubit.board import display, Image
2.
3. img_line = Image("00100:00100:00100:00100:00100:", color=(31, 0, 0))
4. display.show(img_line.shift_right(-1)) #img_line.shift_left(1)と同じ結果
5. display.show(img_line)
6. display.show(img_line.shift_left(-1)) #img_line.shift_right(1)と同じ結果
4. 2 上下方向のシフト
上下方向にイメージをシフトさせるときは、shift_up()
メソッドとshift_down()
メソッドを使います。
StuduinoBitImage.shift_up(n) ・・・イメージをnピクセル分上にシフトした新たなイメージを返します。
StuduinoBitImage.shift_down(n) ・・・イメージをnピクセル分下にシフトした新たなイメージを返します。
実際に、上の図のように水平な線が上下に1ピクセル分シフトしたイメージを作り、上から下へ水平な線が移動するアニメーションを作成してみましょう。
■ プログラムの作成
はじめに、LEDディスプレイの中央に水平な線を表示するためのイメージimg_line
を作成し、作成したイメージをStuduinoBitDisplayクラスのshow()
メソッドで表示しましょう。
1. from pystubit.board import display,Image
2. import time
3.
4. img_line = Image("00000:00000:11111:00000:00000:", color=(31, 0, 0))
5.
6. display.show(img_line)
次に、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行目】
1. from pystubit.board import display,Image
2. import time
3.
4. img_line = Image("00000:00000:11111:00000:00000:", color=(31, 0, 0))
5.
6. display.show(img_line.shift_dwon(-1))
7. display.show(img_line)
8. display.show(img_line.shift_up(-1))
4. 3 シフトメソッドを利用したディスプレイ上を流れるアニメーションの作成
学習したシフトメソッドを利用すると、StuduinoBitDisplayクラスのscroll()
メソッドと同じく、文字が横切って流れていく表現が作成できます。ここでは例として、下のコードと同じく、アルファベットの「A」が繰り返し流れるアニメーションを作成してみましょう。
1. from pystubit.board import display
2.
3. while True:
4. display.scroll('A')
■ プログラムの作成
はじめに、流す文字「A」のイメージを作成します。
1. from pystubit.board import display, Image
2.
3. img_A = Image("01100:10010:11110:10010:10010:", color=(31, 0, 0))
次に、作成したイメージをディスプレイの右端から左端へ流すとき、両端にあたるイメージが元のイメージを何ピクセル分シフトさせたものになるのかを考えます。左端は4ピクセル分、右端は5ピクセル分になります。また、ここではプログラムを簡単にするため、shift_left(-n)
とshift_right(n)
で作成されるイメ―ジが同じだったことから、shift_left()
メソッドだけですべてのイメージを作成します。
※shift_left(0)は元のイメージと同じイメージを返します。
for文と標準関数のrange()
で、右端から左端へ向かって順番にシフトしたイメージを作成し、StuduinoBitDisplayクラスのshow()
メソッドでLEDディスプレイに表示します。また、下のコードでは、range()
関数には負の数を引数として渡すことで、「-5~4」のように負の値から順番に並んだ数字を得ています。
変更【5行目~7行目】
1. from pystubit.board import display, Image
2.
3. img_A = Image("01100:10010:11110:10010:10010:", color=(31, 0, 0))
4.
5. while True:
6. for n in range(-5, 5):
7. display.show(img_A.shift_left(n))
※range(-5, 5)
と指定した場合、作成される数字のリストには5が含まれないことに注意しましょう。
完成したプログラムを実行して、scroll()
メソッドを使ったときと同じ表現ができていることを確認しましょう。こ
チャプター5
課題:+演算子とシフトメソッドを組み合わせたイルミネーションライトの作成
ここまでで学習した内容を踏まえて、次のように2色の線がシフトするアニメーションを合成したイルミネーションライト作成しましょう。
5. 1 プログラムの作成
水平な線と垂直な線のイメージをそれぞれ作成し、shift_right()
メソッドとshift_down()
メソッドでシフトしたイメージを作ります。その2つを+演算子で合成すると、上のアニメーションのイメ―ジが得られます。
はじめに、水平な赤色の線と垂直な青色の線のイメージを作成し、合成してディスプレイに表示します。
※「horizontal」は英語で「水平な」の意味を、「vertical」は英語で「垂直な」の意味を表します。
1. from pystubit.board import display, Image
2.
3. img_horizontal_line = Image("11111:00000:00000:00000:00000:", color=(31, 0, 0))
4. img_vertical_line = Image("10000:10000:10000:10000:10000:", color=(0, 0, 31))
5.
6. img = img_vertical_line + img_horizontal_line
7. display.show(img)
次に、for文を使って、水平な線を下へ、垂直な線を右へ向かって1ピクセルずつ順番にシフトさせ、それらを合成したイメージを表示するようにします。できたら、ここまでのプログラムを実行して、動作を確認しましょう。
追加・変更【6行目~8行目】
1. from pystubit.board import display, Image
2.
3. img_horizontal_line = Image("11111:00000:00000:00000:00000:", color=(31, 0, 0))
4. img_vertical_line = Image("10000:10000:10000:10000:10000:", color=(0, 0, 31))
5.
6. for n in range(5):
7. img = img_vertical_line.shift_right(n) + img_horizontal_line.shift_down(n)
8. display.show(img)
今度はそれぞれの線を反対向きに1ピクセルずつ順番にシフトさせます。range(4, -1, -1)
のように、第3引数に負の数「-1」と指定すると、順番に1ずつ小さくなる数字の並び「4, 3, 2, 1, 0」が得られます。これを引数に指定してイメージを作成します。
追加【9行目~11行目】
1. from pystubit.board import display, Image
2.
3. img_horizontal_line = Image("11111:00000:00000:00000:00000:", color=(31, 0, 0))
4. img_vertical_line = Image("10000:10000:10000:10000:10000:", color=(0, 0, 31))
5.
6. for n in range(5):
7. img = img_vertical_line.shift_right(n) + img_horizontal_line.shift_down(n)
8. display.show(img)
9. for n in range(4, -1, -1):
10. img = img_vertical_line.shift_right(n) + img_horizontal_line.shift_down(n)
11. display.show(img)
最後に、while文を使った永久ループでアニメーションを繰り返すようにして、プログラムの完成です。実行して動作を確認しましょう。
【 サンプルコード 5-1-1 】
追加・変更【6行目~12行目】
1. from pystubit.board import display, Image
2.
3. img_horizontal_line = Image("11111:00000:00000:00000:00000:", color=(31, 0, 0))
4. img_vertical_line = Image("10000:10000:10000:10000:10000:", color=(0, 0, 31))
5.
6. while True:
7. for n in range(5):
8. img = img_vertical_line.shift_right(n) + img_horizontal_line.shift_down(n)
9. display.show(img)
10. for n in range(4, -1, -1):
11. img = img_vertical_line.shift_right(n)+img_horizontal_line.shift_down(n)
12. display.show(img)
チャプター6
おわりに
6. 1 このレッスンのまとめ
このレッスンでは、StuduinoBitDisplayクラスの+演算子やシフトメソッドを利用することで、LEDディスプレイの高度な制御ができることを確認しました。
6. 2 次回のレッスンについて
次のレッスンでは、関数やメソッドの引数の種類について学習し、StuduinoBitDisplayクラスのshow()
メソッドやscroll()
メソッドの引数と表示形式の関係を確認します。