はじめに
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 を点滅させる
- Nerves Livebook から RGB LED を制御する(ソフトPWMもやってみる)
この記事では、工作キットに付いている LED 棒グラフを制御します
実装したノートブックはこちら
LED 棒グラフ
白いところが LED になっていて、それぞれ光らせることができます
回路の組み立て
工作キットのオンライン説明書に従って回路を組みます
かなり線が多くなってきましたが、家族でわちゃわちゃしながら組み立てました
子どもでも簡単に組めるのが本当に良いです
抵抗を多数横並びにするため、足が長いのが邪魔になってきました
対処として正しいのか分かりませんが、ニッパーで短く切りました
Nerves Livebook の場合 SPICE0 のピンがすでに使われています(詳細までは追えていません)
そのため、 GPIO5 のピンを代わりに使いました
ピンのステータス確認
以下のコードで GPIO のラベル一覧が取得できます
Circuits.GPIO.enumerate()
|> Kino.DataTable.new()
この情報を元に SPICE0 = label: SPI_CE0_N のピンを開いてみます
Circuits.GPIO.open("SPI_CE0_N", :output)
すると、実行結果には {:error, :already_open}
が返ってきます
当然、この状態では書き込むことができません
以下のコードでピンの状態が確認できます
Circuits.GPIO.status("SPI_CE0_N")
すでに使われている場合、実行結果は以下のようになります
{:ok, %{pull_mode: :none, direction: :output, consumer: "spi0 CS0"}}
他のピンの状態を確認し、使われていないものを代用しましょう
使われていない場合は以下のように consumer: ""
となります
{:ok, %{pull_mode: :none, direction: :input, consumer: ""}}
LED の点灯
以下のコードで各ピンを開きます
led_list =
[
"GPIO17",
"GPIO18",
"GPIO27",
"GPIO22",
"GPIO23",
"GPIO24",
"GPIO25",
"SDA1",
"SCL1",
"GPIO5"
]
|> Enum.map(fn label ->
label
|> Circuits.GPIO.open(:output)
|> elem(1)
end)
実行結果は以下のような配列になります
[
%Circuits.GPIO.CDev{ref: #Reference<0.2085008915.2670067723.197044>},
%Circuits.GPIO.CDev{ref: #Reference<0.2085008915.2670067723.197045>},
%Circuits.GPIO.CDev{ref: #Reference<0.2085008915.2670067723.197046>},
%Circuits.GPIO.CDev{ref: #Reference<0.2085008915.2670067723.197047>},
%Circuits.GPIO.CDev{ref: #Reference<0.2085008915.2670067723.197048>},
%Circuits.GPIO.CDev{ref: #Reference<0.2085008915.2670067723.197049>},
%Circuits.GPIO.CDev{ref: #Reference<0.2085008915.2670067723.197050>},
%Circuits.GPIO.CDev{ref: #Reference<0.2085008915.2670067723.197051>},
%Circuits.GPIO.CDev{ref: #Reference<0.2085008915.2670067723.197052>},
%Circuits.GPIO.CDev{ref: #Reference<0.2085008915.2670067723.197053>}
]
オンライン説明書の回路の場合、各 LED は 0 でオン、 1 でオフになります
そのため、この時点で LED は全て点灯します
しかし、やはり直観に反しているのが気持ち悪いので 3V3 の線を GND に差し替え、 LED を反転させましょう
電源を入れ直して最初からやり直すと、以下のように全て消灯した状態になります
以下のコードを実行すると、上から4番目までが光ります
Circuits.GPIO.write(led_list |> Enum.at(0), 1)
Circuits.GPIO.write(led_list |> Enum.at(1), 1)
Circuits.GPIO.write(led_list |> Enum.at(2), 1)
Circuits.GPIO.write(led_list |> Enum.at(3), 1)
Circuits.GPIO.write(led_list |> Enum.at(4), 0)
Circuits.GPIO.write(led_list |> Enum.at(5), 0)
Circuits.GPIO.write(led_list |> Enum.at(6), 0)
Circuits.GPIO.write(led_list |> Enum.at(7), 0)
Circuits.GPIO.write(led_list |> Enum.at(8), 0)
Circuits.GPIO.write(led_list |> Enum.at(9), 0)
下から指定番目までを光らせるモジュールを作ってみましょう
defmodule LEDBar do
def set(led_list, value) do
led_list
|> Enum.with_index()
|> Enum.map(fn {led, index} ->
Circuits.GPIO.write(led, (if (10-index) <= value, do: 1, else: 0))
end)
end
end
モジュールを使って LED 棒グラフを光らせます
LEDBar.set(led_list, 6)
LED 棒グラフの上昇
だんだん棒グラフが伸びるようにしてみましょう
defmodule LEDElevator do
def set(led_list, interval) do
led_list
|> Enum.map(fn led ->
Circuits.GPIO.write(led, 0)
end)
Process.sleep(interval)
led_list
|> Enum.reverse()
|> Enum.map(fn led ->
Circuits.GPIO.write(led, 1)
Process.sleep(interval)
end)
end
end
500 msec 間隔で上昇させてみます
LEDElevator.set(led_list, 500)
うまくいきました
ピンを閉じる
最後にピンを閉じておきます
led_list
|> Enum.map(fn led ->
Circuits.GPIO.close(led)
end)
まとめ
LED の数が増えても同じように制御できました
LED 棒グラフは割合を示すときに使えそうですね