GAミント至上主義

Web Monomaniacal Developer.

Raspberry Pi Zero WHでLED8個をチカチカさせた(動画あり)

買ったあとすぐ入院したので放置していたRaspberry Pi Zero WHを活用すべく、LEDの点滅、通称Lチカさせる。8個でやった。


動画


Raspberry Pi Zero WHについて

名刺サイズのZeroにWifiとかBluetooth、ピンヘッダがついたやつという認識。
小さくて安いイメージのZeroだったけど、ネットワークの問題だとか、GPIOピンヘッダがついてないとか、映像端子がこれでしか見たことないminiHDMIだったり、不便そうなので、下記セットを買ってしまって安くはなかった。揃えるの面倒だったので後悔はしていない。

WH本体だけだと1814円で買える
Raspberry Pi Zero WH - スイッチサイエンス

無印は648円で買える。
Raspberry Pi Zero v1.3 - スイッチサイエンス

どちらも2019/06/23時点 

OSインストール&設定

3ヶ月前なのでうろ覚えだけどNOOBSを使った。
第56回「改めましてラズベリーパイの基本!(1)NOOBSインストール 2017年度版」 | Device Plus - デバプラ

最初フルRaspbianを入れたけど、インストールだけでかなり待たされ、起動後もGUIのせいか遅すぎ&フリーズでストレス半端ないため、Raspbian Liteを入れて、コンソールのみにした。
そもそもUSBが一個しかなく、マウスとキーボードを使うためにはUSBハブが必要なのも邪魔。

WifiSSHサーバーの有効化設定は

$ sudo raspi-config

コマンドで出来るので便利。

そのあとの作業は、PixelbookのLinuxターミナルから家庭LANを通してSSH + Vimで作業した。
Vimですらちょっとカクつくことがあるので、快適に開発したければ3がいいと思う。
今回ラズパイでPython書く用の.vimrcを新調したのであとでGitHubに載せたい。

LEDの接続

正直電子回路に関する偏差値は20ぐらいなので、書けることは少ないし自信がない。

以前買ったキットに入っていた4色のLED(詳細不明、おそらく20mA?)と、臭気センターを試すときに秋月電子で買った1K抵抗とジャンパワイヤーなどを使いまわした。

GPIOのケーブルは1-5が赤、足りなくて6-8が白。GND系は全部青。

LEDの色は赤、黄緑、黄、白。動画を見れば分かるけど、白色が明るめ。

接続はGPIOから1KΩ抵抗、LED、GNDにつなげる×8をしたのみ。

抵抗に関しては330Ωを使う情報が多いが、下記の記事などを参考にして、数が多いから1Kの方が流れる量が少なくて安心だろうということで決めた。具体的な計算はしていないが全部光らせても今のところ問題ない(ように見えている)
hombre-nuevo.com

8個にしたのは、たまたま手元に4色あったので、それを2セットにしたことと、3bitでキリがいいこと、それ以上接続するのが面倒になったことが一番大きい。

GPIOの位置は下記資料で確認した。GPIOしか使ってない自分には無駄に詳しい。
https://cdn.sparkfun.com/assets/learn_tutorials/6/7/6/PiZero_1.pdf

Pythonを書く

今回の目的はPythonでLチカさせて終わりだけではなく、将来的にはFirebaseやVue.jsなど最新のWEB技術を利用して、高度なWEBアプリでLチカさせるプロジェクトの第一弾という位置づけ。

そのため、デモでありながらLEDの点灯情報を外部から変更できる設計を意識した。

以前はRaspbianにもインストールされている標準のパッケージ(RPi.GPIO) を使ったが、検索しているうちにGpiozeroという便利なパッケージを見つけたので使用した。コードがかなり短くなるし、後始末も勝手にやってくれるので非常に楽。もう戻れない。インストール方法は割愛するので下記ドキュメントを参照。

14. API - Output Devices — Gpiozero 1.5.0 Documentation

実際のコードは下記。微妙にブログ上で変更したから動くとは限らない。

これを書いている時にドキュメントを読んで気づいたが、複数LEDを操作する用にLEDBoardというのもあり、場合によっては、こちらを使ってもいいかもしれない。

16. API - Boards and Accessories — Gpiozero 1.5.0 Documentation

import RPi.GPIO as GPIO
from time import sleep
from gpiozero import LED

# Key:GPIO番号
PIN_NUMS_DICT = {1:4, 2:17, 3:27, 4:22, 5:18, 6:23, 7:24, 8:25} 
INTERVAL_SEC = 0.2

def init_led():
    led = {}
    for key, val in PIN_NUMS_DICT.items():
        led[key] = LED(val)
    return led

def generate_demo_pattern():
    yield [1, 2, 3, 4, 5, 6, 7, 8]
    yield [1, 2, 3, 4, 5, 6, 7, 8]
    yield [1, 2, 3, 4, 5, 6, 7, 8]
    yield [1, 2, 3, 4, 5, 6, 7, 8]
    
    yield [1, 5]
    yield [2, 6]
    yield [3, 7]
    yield [4, 8]
    yield [3, 7]
    yield [2, 6]
    yield [1, 5]
    
    yield [1, 8]
    yield [2, 7]
    yield [3, 6]
    yield [4, 5]
    yield [6, 3]
    yield [7, 2]
    yield [8, 1]
    
    yield [1]
    yield [2]
    yield [3]
    yield [4]
    yield [5]
    yield [6]
    yield [7]
    yield [8]
    yield [7]
    yield [6]
    yield [5]
    yield [4]
    yield [3]
    yield [2]
    yield [1]
    
    yield [1, 2, 3, 4, 5, 6, 7, 8]
    yield []
    yield [1, 2, 3, 4, 5, 6, 7, 8]
    yield []
    yield [1, 2, 3, 4, 5, 6, 7, 8]
    yield []
    yield [1, 2, 3, 4, 5, 6, 7, 8]
    yield []
    yield [1, 2, 3, 4, 5, 6, 7, 8]
    yield []
    yield [1, 2, 3, 4, 5, 6, 7, 8]


def update_pattern(leds, on_keys):
    for key, val in leds.items():
        if key in on_keys:
            led[key].on()
        else:
            led[key].off()

pat_gen = generate_demo_pattern()
def get_pattern():
    return next(pat_gen)

if __name__ == '__main__':
    led = init_led()
    while True:
        try:
            pattern = get_pattern()
        except StopIteration:
            break
        print(pattern)
        update_pattern(led, pattern)
        sleep(INTERVAL_SEC)

GPIO番号はそのまま使うには辛いので、任意のKeyを使えるようにし、今回は右から1から8までの数字で順番に指定できるようにした。
色に意味のある場合は"RED01"とかにした方が良さげ。

あとは、点灯させるKeyの配列を渡せば、指定したKeyのLEDがINTERVAL_SECの間点灯し、また更新される。
空リストを渡せば、全部消せる。

実際の動きは動画で。

デモ用のパターン指定は無駄にジェネレータを使った。こんなyield見たことない。

趣味でたくさんyieldしてみたかっただけ感は否めないが、無理にメリットを説明すると、forを使わずに回せたことがある。

今見たらyieldで返してる値、変更しないからリストじゃなくてタプルでいいじゃんと今思ったけどまあいいや。セットは順序が変わるとデバッグ時に見づらいから良くなさそう。

今後はget_pattern()の部分を変更して、ファイルなり、APIなりで、点灯させるKeyの配列だけ渡すことができれば、LEDの点灯をコントロールすることが出来る。

あと秋葉原秋月電子の営業時間内に行くことがあれば、他の色のLEDも買いたい。

でもファイルは書き込みが多いとSDカードの寿命が心配なので、APIかメモリに載せる系がいいのかなぁと思った。