複数LEDをパッケージ化した部品を使う:NeoPixel LED Stick, Strip and Ring
ここでは、NeoPixelというLEDが複数個並んでいる部品の使い方を説明します。NeoPixelではないLEDは対象外です。手持ちの部品に付いているLEDがNeoPixelかどうか分からない場合には、商品名や部品の説明に以下のどれかが含まれているかチェックしてください。以下のどれかが含まれていれば、その部品はNeoPixel(あるいはその準拠品、互換品)だと考えて問題ありません。
- WS2812
- WS2812B
- WS2811
- WS2813
- SK6812
NeoPixel(というLEDが複数個並んでいる部品)には様々な形状があり、形状ごとに呼び方が異なります。例えば、細長い板の上にLEDが並んでいるものは「NeoPixel Stick」や「LED Stick」と呼ばれます。有名な商品には以下のようなものがあります。
細長いテープ状(ヒモのような形状)にLEDが並んでいるものは「NeoPixel Strip」や「LED Strip」と呼ばれます。やわらかくて透明なシリコン素材のカバーが付いている場合もあります。有名な商品には以下のようなものがあります。
- Adafruit NeoPixel LED Strip
- AdafruitはあまりにたくさんのLED Stripを販売しているので、「これ」というリンクを選ぶのが難しいです。AdafruitのWebサイトで検索してみてください。
- Seeed Studio Grove LED Strip
ドーナツ状のリングの上にLEDが並んでいるものは「NeoPixel Ring」や「LED Ring」と呼ばれます。有名な商品には以下のようなものがあります。
ラズパイとの接続
NeoPixelというのはLEDの名前で(正確にはLEDの発色を制御するチップ(極小コンピュータ)の名前)、これを使ってさまざまなメーカーがさまざまな商品を製造、販売しています。NeoPixelを使ってさえいれば、どの商品を使っていても、プログラムの書き方は同じです。
が、LEDの種類が同じでも、商品ごとに異なるワイヤーやコネクターを使っていることがあります。その場合、ラズパイとの接続方法が、商品ごとに少しずつ異なります。また、使うLEDの個数に応じて電源供給の方法が異なります。ですので、まだ未購入であれば、どの商品を買うのがいいかお問合せください。お問い合わせ時点でのおすすめ商品をお知らせします。あわせてラズパイとの接続方法もお知らせします。
既に手元にLED商品(スティックやストリップ、リングなど)がある場合は、その商品がNeoPixelを使っていることを確認してください。そして、その商品とラズパイとの接続方法をお問合せください。このページでは、LED商品とラズパイを物理的に接続する方法は省略します。
準備
ラズパイとの接続が終わったら、プログラミングをするための準備をします。まずはラズパイを最新の状態にします。Terminalで、以下のコマンドをひとつづつ実行してください。
sudo apt update -y
sudo apt full-upgrade -y
続いて、以下のコマンドを実行します。
sudo pip3 install rpi_ws281x
ラズパイZeroをお使いの場合、準備作業はこれで終わりです。次の「プログラミング」のセクションへ移ってください。
もし、ラズパイ3かラズパイ4をお使いの場合は、追加の準備作業が必要です。以下のコマンドをTerminalで実行してください。
sudo mousepad /etc/modprobe.d/snd-blacklist.conf
「Mousepad」というラズパイのテキストエディタ(Windowsのメモパッドのようなもの)が「snd-blacklist.conf」という設定ファイルを開きます。おそらくこのファイルには何も書かれていないと思います。最初の行に、以下の設定項目を追加します(コピー・アンド・ペーストする)。
blacklist snd_bcm2835
そして、ファイルを保存して、Mousepadを閉じます。もし、「snd-blacklist.conf」という設定ファイルが空でなく何か書かれていたら、最後の行まで移動して上記設定項目をコピー・アンド・ペーストしてください。
Terminalに戻り、以下のコマンドを実行してください。
sudo mousepad /boot/config.txt
今度は、Mousepadが「config.txt」という設定ファイルを開きます。このファイルには数多くの設定項目が書かれています。ファイルの1行目から順に見ていって、
という行を探してください(だいたい50行目あたりにあります)。そしてその行の先頭に「#」を書き込みます。以下のようにします。
```#dtparam=audio=on```
そして、ファイルを保存して、Mousepadを閉じます。
これで準備作業は終わりです。ラズパイをリブートして、次の「プログラミング」のセクションへ移ってください。
<!--
ラズパイとの接続が終わったら、プログラミングをするための準備をします。まずは「[CircuitPythonをインストールする](../../circuit-python)」を読んで、CircultPythonをインストールしてください。
続いて、ラズパイのTerminalで以下のコマンドを実行してください。
sudo pip3 install adafruit-circuitpython-neopixel
-->
### プログラミング
最初のサンプル・プログラムが[all-red.py](/IoT-Kids/projects/p/led/neopixel/all-red.py)です。ラズパイへコピーして下さい。そして、[iotutils_neopixel.py](/IoT-Kids/projects/p/led/neopixel/iotutils_neopixel.py)を同じフォルダにコピーしてください。NeoPixelを使ってLEDを点滅させるプログラを書くとき、そのプログラムは常に[iotutils_neopixel.py](/IoT-Kids/projects/p/led/neopixel/iotutils_neopixel.py)を必要とします。自分のプログラムと[iotutils_neopixel.py](/IoT-Kids/projects/p/led/neopixel/iotutils_neopixel.py)が同じフォルダにフォルダに置いてあることを確認してください。
次に、Thonnyで[all-red.py](/IoT-Kids/projects/p/led/neopixel/all-red.py)を開いて、以下の行を探して下さい。
```python
ledCount = 10
ここで変数ledCountは、LEDの総数(お手持ちのNeoPixelにLEDが全部で何個付いているか)を表しています。ここでは例としてLEDが10個ある想定になっています。自分のNeoPixelに何個LEDが付いているかを数えて、その数字に変更してください。
Neopixelを使うプログラムを実行するにはTerminalから実行してください。他のプログラムのように、Thonnyの緑の再生ボタンのようなものをクリックしても、エラーが出てプログラムは実行できません(”Permission denied”というようなエラーがでます)。プログラムを「iot-python」というフォルダに保存している場合には、Terminalで以下のコマンドを実行してください。
cd iot-python
そして、以下のコマンドでプログラムを実行します。
sudo python3 all-red.py
このプログラムが正常に動くと、すべてのLEDが赤く3秒間光ります。
さてプログラムの説明に移ります。NeoPixelを使ってLEDを点滅させるプログラを書くには、プログラムの先頭行を以下のようにします。
from iotutils_neopixel import Neopixel
そして、以下のようにNeoPixel()という関数を使って、LEDを点灯させる準備をします。
ledCount = 10
ledPin = 18
neop = Neopixel(ledCount, ledPin)
変数ledCountはLEDの総数を表しています。変数ledPinは、ラズパイのどのGPIOピンを使ってNeoPixelと接続しているかを表しています。このGPIOピンのことをSIG(シグナル)ピン、DI(データIN)ピンなどと呼びます。ここではGPIOの18番を使う想定になっています。この数字を変更する必要はありません。
関数NeoPixel()は、NeoPixelを点灯させる準備を終えると、NeoPixelと通信をする「通信口」を返します。上記例では、これを変数neopに入れています。以後は、この「通信口」を使って点灯、色の指定、消灯などを行います。
NeoPixelに付いているLEDすべてに同じ色を指定するには、fillRGB()という関数を使います。そして、その色で実際に点灯させるにはshow()という関数を使います。fillRGB()だけ呼んでshow()を呼ばないと、LEDは点灯しないので注意が必要です。
neop.fillRGB((255, 0, 0))
neop.show()
time.sleep(3)
関数fillRGB()を呼ぶ時には、LEDを何色で点灯させるかを指定します。この色指定には、RGB値を使います。Rの値、Gの値、Bの値の順です。上の例では、Rの値が255で、GとBの値は0になっています。つまり赤色を指定しています。
色の指定に使うRGB値について少し補足します。色には(厳密にいうと「光」には)3つの根本的な色があります。赤(Red)、緑(Green)、青(Blue)です。光の三原色とよばれます。この3つを混ぜあわせると(人間が認識できるほぼ)すべての色を表現できます。このページを使って、三原色を混ぜあわせた結果がどんな色になるかを調べてみてください。
赤(Red)、緑(Green)、青(Blue)のそれぞれには、0から255までの256レベルを指定できます。この値は所定の色の「含有量」を表します。例えば、R値は「赤っぽさ」がどの程度かを表しており、最大値の255は「真っ赤」を意味します。R値が小さくなると、「赤っぽさ」が減ってだんだん暗い色になります。R値が0になると黒色になります。R、G、Bすべてが0だと黒色、R、G、Bすべてが255だと白色になります。
さてプログラムの説明に戻ります。上記の例では、LEDすべてを赤色に設定し、点灯させ、プログラムの実行を3秒間止めています。結果として、すべてのLEDが3秒間赤く光ります。
点灯しているLEDを消す(消灯する)には、以下のように、すべてのLEDを黒色にします。「黒い色でLEDを光らせる」のと「消灯」は同じ意味です。
neop.fillRGB((0, 0, 0))
neop.show()
プログラムの一番最後にこの2行を入れておいてください。こうしないと、プログラム終了後もLEDが光ったままになります。
次のプログラムがall-rgb.pyです。このプログラムは、すべてのLEDを赤(255, 0, 0)、緑(0, 255, 0)、青(0, 0, 255)と3秒づつ点灯させます。このプログラムを実行するには、Terminalで
sudo python3 all-rgb.py
とします。Neopixelを使うプログラムを実行するにはTerminalから実行してください。Thonnyの緑の再生ボタンのようなものをクリックしても、エラーが出てプログラムは実行できません(”Permission denied”というようなエラーがでます)。
次がin-sequence.pyです。このプログラムでは、すべてのLEDを一度に点灯させるのではなく、個々のLEDを順番に点灯させます。それぞれのLEDは自分のID番号を持っています。LEDが全部で10個ある場合には、先頭のLEDが0番のID、次のLEDが1番のID・・・というふうに続き、最後のLEDは9番のIDを持ちます。
個々のLEDを点灯させるには、このID番号を使って関数setRGB()を呼びます。例えば、0番のIDを持つLEDを赤色に設定するには、以下のようにします。
ledCount = 10
ledPin = 18
neop = Neopixel(ledCount, ledPin)
neop.setRGB(0, (255, 0, 0))
pixels.show()
このように、関数setRGB()には、LEDのID番号と色(RGB値)を渡します。
ちなみに「先頭の」(IDが0番の)LEDは、たいてい電源供給されている部分から一番近いLEDです。お使いのNeopixelで、どれが先頭(IDが0番)のLEDか分からなかったら、in-sequence.pyを動かしてみて、最初に光るLEDが「先頭」だと理解してください。
さてin-sequence.pyでは、以下のようにして、
for led in range(ledCount):
neop.setRGB(led, (255, 0, 0))
neop.show()
time.sleep(interval)
IDが0番のLEDを点灯させ、次にIDが1番のLEDを点灯させ、その次にIDが2番のLEDを点灯させ・・・というふうに、順々にLEDを点灯します。forから始まるこの部分は「forループ」とよばれ、インデントされている部分を繰り返し実行します。ここでは、インデントされている3行を繰り返し実行します。
range(10)というのは「0以上10未満の整数の並び」を意味します。つまり、0、1、2、3、・・・、8、9のことです。この数が、先頭から順番にひとつづつ変数ledに入りながら繰り返し作業をします。つまり、最初は0が変数ledに入り、その上でsetRGB()を呼びます。いま変数ledには0が入っているので、
neop.setRGB(0, (255, 0, 0))
が実行されます。このループを2回目に実行するときは、変数ledに1が入り、その上でsetRGB()を呼びます。つまり、
neop.setRGB(1, (255, 0, 0))
が実行されます。同様に、変数ledに2、3、・・・、8、9が順番に入って繰り返しsetRGB()を呼びます。変数ledに9を入れてsetRGB()を呼んだら繰り返しをやめます。
in-sequence.pyには、もうひとつforループがあります:
for led in reversed(range(ledCount)):
neop.setColor(led, Color("yellow"))
neop.show()
time.sleep(interval)
range(10)は「0以上10未満の整数の並び」、つまり0、1、2、3、・・・、8、9を意味します。この数字の並びを関数reversed()に渡すと、並び方が逆になって返されます。つまり、9、8、…、1、0になります。上記のforループでは、最初に変数ledに9が入るので、
neop.setColor(9, Color("yellow"))
が実行されます。このループを2回目に実行するときには、変数ledに8が入って、
neop.setColor(8, Color("yellow"))
が実行されます。同様に、変数ledに7、6、・・・、1、0が順番に入って繰り返しsetColor()を呼びます。変数ledに0を入れてsetColor()を呼んだら繰り返しをやめます。
なお関数setColor()は、setRGB()と同じようにLEDに色を設定しますが、色の設定方法が少し違います。setRGB()にはLEDのID番号とRGB値を渡します。一方、setColor()を呼ぶときには、関数Colorを使います。上記のように、
Color("yellow")
というふうにします。”yellow”の部分を他の色の名前に変えると、LEDの色が変わります。光の三原色(red、green、blue)、色の三原色(cyan、magenta、yellow)、黒(black)、白(white)に加え、数多くの色(の名前)を指定できます。他にどの色の名前を使えるかは、こちらを参照して下さい。