はじめに
Nerves Livebook で Raspberry Pi 用スターター電子工作キットを楽しんでいます
SunFounder Raspberry Pi 用のスターター電子工作キット
これまでの記事
- Nerves Livebook で Raspberry Pi 4 のLチカ
- Nerves Livebook + Delux で簡単Lチカ
- MacBook 上の Livebook から Raspberry Pi 上の Livebook に接続してLチカする
- Nerves Livebook から GPIO 拡張ボードの LED を点滅させる
この記事では、工作キットに付いている RGB LED を制御します
実装したノートブックはこちら
RGB LED
4本足が出ている LED です
赤、緑、青の 3 つの LED が中に入っています
回路の組み立て
公開されているオンライン説明書に従って回路を組み立てます
RGB LED は足の長さでどの線なのか見極める必要があります
ピンを開く
単純な LED のときと同様、まずは GPIO ピンを開いて使えるようにします
赤、緑、青にそれぞれ対応したピンを指定しています
{:ok, red} = Circuits.GPIO.open("GPIO17", :output)
{:ok, green} = Circuits.GPIO.open("GPIO18", :output)
{:ok, blue} = Circuits.GPIO.open("GPIO27", :output)
LED の点灯
どの色を光らせるかという組み合わせで色が決まります
# Red
Circuits.GPIO.write(red, 1)
Circuits.GPIO.write(green, 0)
Circuits.GPIO.write(blue, 0)
# Green
Circuits.GPIO.write(red, 0)
Circuits.GPIO.write(green, 1)
Circuits.GPIO.write(blue, 0)
# Blue
Circuits.GPIO.write(red, 0)
Circuits.GPIO.write(green, 0)
Circuits.GPIO.write(blue, 1)
# Yellow
Circuits.GPIO.write(red, 1)
Circuits.GPIO.write(green, 1)
Circuits.GPIO.write(blue, 0)
# Purple
Circuits.GPIO.write(red, 1)
Circuits.GPIO.write(green, 0)
Circuits.GPIO.write(blue, 1)
# White
Circuits.GPIO.write(red, 1)
Circuits.GPIO.write(green, 1)
Circuits.GPIO.write(blue, 1)
この辺りは子どもと一緒にやると「これとこれを一緒に光らせたら何色になるでしょうか」といった感じで盛り上がりました
PWM
Pulse Width Modulation = パルス幅変調を利用して LED の明るさを調整します
@mnishiguchi さんの記事で分かりやすく解説しています
今回の記事ではソフト PWM を実行してみました
Raspberry Pi 0 〜 3 の場合は Nerves Livebook のファームウェアが Pigpiox インストール済のものになっています
https://github.com/tokafish/pigpiox
Pigpiox があれば簡単に PWM を実行でき、サンプルコードも公開されています
https://github.com/nerves-livebook/nerves_livebook/blob/main/priv/samples/basics/pwm.livemd
残念ながら Raspberry Pi 4 では Pigpiox がインストールされていません
以下の箇所を参照
https://github.com/nerves-livebook/nerves_livebook/blob/main/mix.exs
...
# Libraries that use MMAL on the Raspberry Pi won't work with the Raspberry
# Pi 4. The Raspberry Pi 4 uses DRM and libcamera.
@rpi_mmal_targets [:rpi, :rpi0, :rpi2, :rpi3, :rpi3a]
...
{:pigpiox, "~> 0.1", targets: @rpi_mmal_targets},
...
まず、一旦すべての LED を消しておきます
Circuits.GPIO.write(red, 0)
Circuits.GPIO.write(green, 0)
Circuits.GPIO.write(blue, 0)
PWM 用のモジュールを定義します
defmodule PWM do
def set(led, duty, length) do
on_time = 10 * duty |> round()
off_time = 10 - on_time
full_time = length / 10 |> round()
1..full_time
|> Enum.map(fn _ ->
Circuits.GPIO.write(led, 0)
Process.sleep(off_time)
Circuits.GPIO.write(led, 1)
Process.sleep(on_time)
end)
end
end
10 msec のうち、第2引数(duty)に指定した割合の分だけ LED を ON にして、残りは OFF にします
例えば割合が 0.3 の場合、 3 msec OFF で 7 msec ON というのを繰り返します
これにより、ずっと ON の場合と比べて LED が暗くなります
次のように段階的に割合を上げることで明るさの変化を確認してみましょう
PWM.set(red, 0.3, 1000)
PWM.set(red, 0.6, 1000)
PWM.set(red, 1.0, 1000)
徐々に明るくなっています
これを利用して、緑 100% + 青 20% のシアンを作ってみます
まず、緑だけ光らせます
Circuits.GPIO.write(red, 0)
Circuits.GPIO.write(green, 1)
Circuits.GPIO.write(blue, 0)
この状態で青を 20% 光らせます
# Cyan
PWM.set(blue, 0.2, 5000)
上手くシアンが表現できました
ピンを閉じる
最後にピンを閉じておきます
led_list
|> Enum.map(fn led ->
Circuits.GPIO.close(led)
end)
まとめ
RGB LED を様々な色に光らせることができました
PWM は少し難しいところもありましたが、とりあえず実装できました