12
3

はじめに

Nerves Livebook で Raspberry Pi 用スターター電子工作キットを楽しんでいます

SunFounder Raspberry Pi 用のスターター電子工作キット

これまでの記事

この記事では、工作キットに付いている LED 棒グラフを制御します

実装したノートブックはこちら

LED 棒グラフ

白いところが LED になっていて、それぞれ光らせることができます

IMG_1551.JPG

回路の組み立て

工作キットのオンライン説明書に従って回路を組みます

かなり線が多くなってきましたが、家族でわちゃわちゃしながら組み立てました

子どもでも簡単に組めるのが本当に良いです

抵抗を多数横並びにするため、足が長いのが邪魔になってきました

対処として正しいのか分かりませんが、ニッパーで短く切りました

IMG_1552.JPG

Nerves Livebook の場合 SPICE0 のピンがすでに使われています(詳細までは追えていません)

そのため、 GPIO5 のピンを代わりに使いました

ピンのステータス確認

以下のコードで GPIO のラベル一覧が取得できます

Circuits.GPIO.enumerate()
|> Kino.DataTable.new()

スクリーンショット 2024-06-23 21.18.32.png

この情報を元に 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 は全て点灯します

IMG_1553.JPG

しかし、やはり直観に反しているのが気持ち悪いので 3V3 の線を GND に差し替え、 LED を反転させましょう

電源を入れ直して最初からやり直すと、以下のように全て消灯した状態になります

IMG_1554.JPG

以下のコードを実行すると、上から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)

IMG_1555.JPG

下から指定番目までを光らせるモジュールを作ってみましょう

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)

IMG_1556.JPG

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)

elevation.gif

うまくいきました

ピンを閉じる

最後にピンを閉じておきます

led_list
|> Enum.map(fn led ->
  Circuits.GPIO.close(led)
end)

まとめ

LED の数が増えても同じように制御できました

LED 棒グラフは割合を示すときに使えそうですね

12
3
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
3