Adafruitの8×8ミニLEDマトリックスをRaspberry Piで使う

電子工作

Adafuitの8x8のLEDマトリックスをRaspberry Piで使う方法を紹介します。
この製品はLEDと制御基盤のセットで、I2C経由で制御できます。また複数の8×8のモノクロ画像を連続再生したり縦横スクロールをしたりといったAPIも提供されているので、LEDオン・オフをすべてコードで書く必要はありません。
LEDのカラーバリエーションは赤、白、青、緑、黄色の5色。
制御基盤とLEDの横幅は同じなので、横に並べて16x8とか32x8とかのマトリックス相当にもできるような気がします(試していません)。

私はスイッチサイエンスでみつけて赤を買いました。キットになっていて、LEDとピンヘッダは自分で基板に取り付ける必要があります。ピン間隔は普通の2.54mmなので半田付けは難しくありません。

Adafruit 8x8 LED matrix(赤)

Adafruit 8x8 LED matrix(赤)

ブレッドボードに刺したところ

ブレッドボードに刺したところ

公式チュートリアルはArduinoを前提に書かれていて、Raspberry Pi向けはあまり詳しく書かれていません。そこでこの記事ではRaspberry Piに特化して、ライブラリのインストールと使い方を記していきます。

インストール

  1. 前提となるパッケージをインストールします。
    sudo apt-get update
    sudo apt-get install build-essential python-dev
  2. I2C通信用のパッケージとイメージ処理用のパッケージをインストールします。
    sudo apt-get install python-smbus python-imaging
  3. GitHub内からライブラリの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. - GitHub...
    にアクセスし、右上の緑のボタンをクリック→Download ZIPボタンをクリックするとmaster.zipファイルのダウンロードが始まるので、適当なフォルダに保存してください。

    LEDライブラリのzipファイルダウンロード

    LEDライブラリのzipファイルダウンロード

  4. master.zipをRaspberry Pi上で解凍します。
    unzip master.zip
  5. 解凍してできたフォルダに移り、インストールを実行します。
    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とサンプルコードを紹介します。

コメント

タイトルとURLをコピーしました