概要
Nervesは、Elixirで組み込みシステムを開発するためのフレームワークです。Raspberry Piなどのデバイス上でElixirコードを直接動作させることができ、ファームウェアの作成やデプロイもmixを使って行えます。
本記事では、学習の一環としてNervesを使い、Lチカ(LEDの点滅) を試してみます。
Lチカの方法として、以下の2種類があります。
-
NervesLiveBookを使用する方法
- ファームウェアを作成せず、LiveBook上で手軽に試せる
-
Nervesでファームウェアを作成する方法
- microSDカードにファームウェアを書き込み、ラズパイを起動時に実行する
まずは、セットアップが簡単な NervesLiveBook を使った方法から試してみます。
また記事中の内容は下記のリポジトリで公開しています
環境
本記事の内容はMac環境で検証しています。Debian等のLinuxでも同様に実行できると思いますが、Windows環境については未検証です。
使用しているElixirやErlangのバージョンは以下の通りです。
Name Version Source Installed
elixir 1.18.2-otp-27 /Users/tanuki/.tool-versions true
erlang 27.2.2 /Users/tanuki/.tool-versions true
必要なもの
Nervesは 複数のRaspberry Piモデル に対応していますが、本記事では Raspberry Pi 4Bを使用します。
- Raspberry Pi 4B
- microSDカード
- Raspberry Pi Imager(https://www.raspberrypi.com/software/)
- LED
- 抵抗(本記事では220Ωを使用)
- ブレッドボード
- ジャンパーワイヤ(オス-メス )
配線
(GPIO17) ─── LED(+) ─── [220Ω] ─── (GND)
手順
ファームウェアを作成しないNervesLiveBookを使用する方法と、
ファームウェアを作成してNervesを動作させる方法では、手順が異なります。
NervesLiveBookの手順
- NervesLiveBookのダウンロード
- microSDカードへの書き込み
- LiveBookへの接続
- Lチカの実行
Nervesの手順
- Nervesのインストール
- Nervesプロジェクトの作成
- Lチカの処理を実装
- 環境変数の設定
- ファームウェアの作成と書き込み
- Nervesの起動
NervesLiveBookの手順
NervesLiveBookのダウンロード
NervesLiveBookでは、使用するRaspberry Piのモデルごとに異なるファイルが必要です。
以下のリンクから、自分のデバイスに対応するファイルをダウンロードしてください。
本記事ではRaspberry Pi 4Bを使用するため、以下のファイルをダウンロードします。
nerves_livebook_rpi4.zip
microSDカードへの書き込み
ダウンロードしたファイルを、マイクロSDカードに書き込みましょう。
Raspberry Pi Imagerを起動し、以下のように設定します。
Raspberry Piデバイス | OS | ストレージ |
---|---|---|
RASPBERRY PI 4 | Use custom(ダウンロードしたファイルを指定) | 書き込みたいマイクロSDカード |
この画像は、すべての項目を選択し終わった直後のRaspberry Pi Imagerの画面です。

「次へ」を押した後、カスタム設定は使用せず、そのまま書き込みを開始してください。
書き込みが完了したら、マイクロSDカードをRaspberry Piに挿入し、有線LANでルーターと接続してください。
LiveBookへの接続
PCのブラウザで以下のURLにアクセスし、パスワード nerves
を入力してLiveBookに接続します。
複数台で起動している場合は、ルーター等でIPアドレスを調べて接続してください
Lチカの実行
新しいNotebookを作成し、以下のコードを 改行ごとにセルに分けて入力しながら 実行してください。
Mix.install([:circuits_gpio])
# GPIOを開く
{:ok, gpio } = Circuits.GPIO.open(17, :output)
# 出力をHIGH(1)にして電流を流す
Circuits.GPIO.write(gpio, 1)
# 出力をLOW(0)にして電流を止める
Circuits.GPIO.write(gpio, 0)
# 5回チカチカする
for _count <- 1..5 do
Circuits.GPIO.write(gpio, 1)
Process.sleep(1000)
Circuits.GPIO.write(gpio, 0)
Process.sleep(1000)
end
# GPIOを閉じる
Circuits.GPIO.close(gpio)
最後のセルを実行すると、LEDを5回点滅することができます。
Nervesの手順
Nervesのインストール
Nervesの公式ドキュメントを参考に、Nervesをインストールしてください。
Nervesプロジェクトの作成
Nervesのセットアップが完了したら、プロジェクトを作成します。
次のコマンドを実行して、新しいNervesプロジェクトを作成しましょう。
mix nerves.new tutorial_nerves
Lチカの処理を実装
Lチカの処理をGenServerで実装し、起動時に自動的にLEDが点滅するようにします。
次のコードを lib/tutorial_nerves/led_chika.ex
に記述してください。
defmodule TutorialNerves.LedChika do
@moduledoc """
起動時に led_on と led_off を交互に送信して、点滅を行う
"""
use GenServer
def start_link(gpio_pin) do
GenServer.start_link(__MODULE__, gpio_pin, name: __MODULE__)
end
@impl true
def init(gpio_pin) do
{:ok, gpio} = Circuits.GPIO.open(gpio_pin, :output)
Process.send_after(self(), :led_on, 0)
{:ok, %{gpio: gpio}}
end
@impl true
def handle_info(:led_on, %{gpio: gpio} = state) do
Circuits.GPIO.write(gpio, 1)
Process.send_after(self(), :led_off, 1000)
{:noreply, state}
end
def handle_info(:led_off, %{gpio: gpio} = state) do
Circuits.GPIO.write(gpio, 0)
Process.send_after(self(), :led_on, 1000)
{:noreply, state}
end
end
次に、作成したTutorialNerves.LedChika
モジュールをApplicationのSupervisorツリーに追加します。
これにより、Nervesが起動すると自動的にLEDの点滅が開始されます。
lib/tutorial_nerves/application.ex
のSupervisorの子プロセスのリストに以下を追加してください。
children =
[
{TutorialNerves.LedChika, 17}
] ++ target_children()
これにより、Nervesが起動する際にLチカが行われるようになります。
環境変数の設定
作業を進める前に、環境変数を設定します。
本記事では Raspberry Pi 4Bを使用するため、以下のように設定してください。
# export MIX_TARGET=<Tag>
export MIX_TARGET=rpi4
他のRaspberry Piモデルを使用する場合は、以下のリストから対応するターゲットを確認してください。
環境変数を設定したら、依存関係を取得します。
mix deps.get
ファームウェアの作成と書き込み
まず、次のコマンドを実行してファームウェアを作成します。
mix firmware
作成が完了したら、microSDカードをPCに接続し、以下のコマンドで書き込みを行います。
mix burn
書き込みが完了したら、microSDカードを取り出し、Raspberry Pi に挿入してください。
Nervesを起動する
microSDカードを挿入したら、電源を入れて起動してください。
Nervesが起動すると、自動的にLチカが開始されます。

リモートでファームウェアを更新する
Raspberry PiでNervesを一度起動すると、microSDカードを抜き取らずにファームウェアを更新できるようになります。
コードを修正した後、以下のコマンドを実行すると、リモートでファームウェアを適用できます。
mix upload nerves.local
まとめ
初めて Lチカ に触れたので、最初は配線の知識がなく不安でしたが、実際に試すことである程度理解できました。
今後は、その他の周辺機器も活用し、IoT デバイスの開発に応用してみたいと思います。
また、記事中で触れたようにGenServerを使用することで、プロセスを独立して動作させる仕組みを改めて学ぶことができました。
この知識は、Nervesでの実装だけでなく、Elixirでの並行処理全般にも活かせそうです。
本記事で作成したNervesのコードはGitHubリポジトリで公開しています。
記事の内容をそのまま試せるように、記述済みのプロジェクトを用意しているので、ぜひ参考にしてください。