Adafuitの8x8のLEDマトリックスをRaspberry Piで使う方法を紹介します。
この製品はLEDと制御基盤のセットで、I2C経由で制御できます。また複数の8×8のモノクロ画像を連続再生したり縦横スクロールをしたりといったAPIも提供されているので、LEDオン・オフをすべてコードで書く必要はありません。
LEDのカラーバリエーションは赤、白、青、緑、黄色の5色。
制御基盤とLEDの横幅は同じなので、横に並べて16x8とか32x8とかのマトリックス相当にもできるような気がします(試していません)。
私はスイッチサイエンスでみつけて赤を買いました。キットになっていて、LEDとピンヘッダは自分で基板に取り付ける必要があります。ピン間隔は普通の2.54mmなので半田付けは難しくありません。
公式チュートリアルはArduinoを前提に書かれていて、Raspberry Pi向けはあまり詳しく書かれていません。そこでこの記事ではRaspberry Piに特化して、ライブラリのインストールと使い方を記していきます。
インストール
- 前提となるパッケージをインストールします。
sudo apt-get update sudo apt-get install build-essential python-dev
- I2C通信用のパッケージとイメージ処理用のパッケージをインストールします。
sudo apt-get install python-smbus python-imaging
- GitHub内からライブラリのzipファイルをダウンロードします。
にアクセスし、右上の緑のボタンをクリック→Download ZIPボタンをクリックするとGitHub - adafruit/Adafruit_Python_LED_Backpack: Python library for controlling LED backpack displays such as 8x8 matrices, bar graphs, and 7/14-segment displays on a Raspberry Pi or BeagleBone Black.Python library for controlling LED backpack displays such as 8x8 matrices, bar graphs, and 7/14-segment displays on a Raspberry Pi or BeagleBone Black. - adafru...master.zip
ファイルのダウンロードが始まるので、適当なフォルダに保存してください。 master.zip
をRaspberry Pi上で解凍します。unzip master.zip
- 解凍してできたフォルダに移り、インストールを実行します。
cd Adafruit_Python_LED_Backpack sudo python setup.py install
テスト
サンプルの実行
最小限の構成で動作テストをします(クリックで大きな図になります)。下図のように配線してみましょう。次に回路を増設するので電源直結ではなくラインを分離しています。
- LEDのC端子(Clock)にGPIO3/SCL1 I2C(ピン番号5)を接続
- LEDのD端子(Data)にGPIO2/SDA1 I2C(ピン番号3)を接続
- LEDの+端子と-端子をそれぞれ++3.3V(ピン番号17)とGND(ピン番号39)に接続
先ほどのmaster.zip
を解凍してできたフォルダ内にサンプルプログラムがあるので実行してみます。
cd Adafruit_Python_LED_Backpack/examples python matrix8x8_test.py
64個のLEDを一つずつ順番に点灯させ、最後に四角枠にバツ印が表示されれば正常です。
サンプルはLEDが点灯しっぱなしで終了してしまいます。まぶしいので全面をクリアするプログラムを実行しておきます。
# -*- coding: utf-8 -*- from Adafruit_LED_Backpack import Matrix8x8 display = Matrix8x8.Matrix8x8() display.begin() display.clear() display.write_display()
これをclear_matrix.py
という名前で保存し実行します。
python clear_matrix.py
これで最低限のテストはできました。
ゲームを作ってみた
ライブラリの使い方は次回にゆずるとして、テストを兼ねて昔懐かしい雰囲気のゲームを作ってみました。
必要な部品
# | 部品 | 備考 |
---|---|---|
U1 | Raspberry Pi Zero | |
LED1 | Adafruit Mini 8x8 LED Matrix w/I2C Backpack - Red | |
R1 | 抵抗 1kΩ | |
R2 | 抵抗 1kΩ | |
SW1 | タクトスイッチ | |
SW2 | タクトスイッチ | |
- | ブレッドボード | |
- | 配線材 |
配線図
まずは配線図。先ほどのテスト配線にタクトスイッチを増設します(クリックで大きな図になります)。
先ほどの配線に加え以下を接続します。
- GPIO25(ピン番号22)からプルダウン抵抗(1kΩ)を介してGND(ピン番号39)とタクトスイッチに接続
- GPIO24(ピン番号18)からプルダウン抵抗(1kΩ)を介してGND(ピン番号39)とタクトスイッチに接続
- 両タクトスイッチの反対側を+3.3V(ピン番号17)に接続
プログラム
左のタクトスイッチを押すとGPIO25がHIGHになり、右のタクトスイッチを押すとGPIO24がHIGHになります。これを使って、パドルの位置を左右に動かし、あとはボールの動きとミス判定とゲームオーバー処理をすれば出来上がりです。
# -*- coding: utf-8 -*- import RPi.GPIO as GPIO from Adafruit_LED_Backpack import Matrix8x8 from time import sleep import signal import sys import math import random def handler(signum, frame): GPIO.cleanup() sys.exit(0) signal.signal(signal.SIGINT, handler) def gameover(): for i in range(100): m.set_pixel(random.randint(0, 7), random.randint(0, 7), 1) m.write_display() sleep(0.01) # initialize LED matrix m = Matrix8x8.Matrix8x8() m.begin() # initialize GPIO pins for tact switches GPIO.setmode(GPIO.BCM) GPIO.setup(24, GPIO.IN) GPIO.setup(25, GPIO.IN) # initialize game variables field_width = 8 field_height = 8 paddle_pos = 2 paddle_length = 3 ball_pos_x = 3 ball_pos_y = 1 ball_vector_x = 0.3 ball_vector_y = 1 sleep(1) while True: m.clear() for i in range(paddle_length): m.set_pixel(paddle_pos + i, 7, 1) m.set_pixel(int(ball_pos_x), int(ball_pos_y), 1) m.write_display() # process switch input if GPIO.input(24) == GPIO.HIGH: if paddle_pos + paddle_length < field_width: paddle_pos += 1 if GPIO.input(25) == GPIO.HIGH: if paddle_pos > 0: paddle_pos -= 1 # process ball position new_x = ball_pos_x + ball_vector_x if new_x < 0 or new_x > field_width - 1: ball_vector_x *= -1 ball_pos_x += ball_vector_x else: ball_pos_x = new_x new_y = ball_pos_y + ball_vector_y if new_y == field_height - 1: if ball_pos_x < paddle_pos or ball_pos_x > paddle_pos + paddle_length: gameover() break else: ball_vector_y *= -1 ball_pos_y += ball_vector_y elif new_y < 0: ball_vector_y *= -1 ball_pos_y += ball_vector_y else: ball_pos_y = new_y sleep(0.1)
実行
実行してみます。ミス判定がいまいちです。
python game_test.py
ゲームオーバーになったらプログラムが終了します。リプレイする場合はもう一度実行してください。
次回は各APIとサンプルコードを紹介します。
コメント