この記事は「#NervesJP Advent Calendar 2019」の9日目です。
昨日は @pojiro さんの「作って学ぶNerves、BBBでCO2計測」でした。
Nervesハンズオンを経験した結果、初心者には環境構築が厳しいと感じました。まずはElixir IoTの取っ掛かりとして、手軽なラズパイでElixirを使ってLEDをチカチカさせるまでをまとめようと思います。ひととおり手を動かした感想として、Nerves使った場合はRaspbianの設定が不要なのはいい点ではないかという印象を持ちました。
ざっくりまとめると
- Mac OSXでRaspbian OSインストールとかんたんな設定
- ラズパイにElixirインストール
- ラズパイのLEDをチカチカ
Mac OSXでRaspbian OSインストールとかんたんな設定
Raspbian OSのインストールはいろいろなやり方があると思いますが、今回はMac OSXを使ってRaspbian OSをインストール(実際にはSDカードにOSイメージ書き込み)して、Wi-Fi設定とSSHでログインできるまでをおこないます。
Raspbian OSインストール
Mac OSXを使ってRaspbian OSをインストール(実際にはSDカードにOSイメージ書き込み)します。
Raspbian OSダウンロード
今回はRaspbian Buster with desktopをインストールすることにします。
公式サイトからダウンロードしてもいいですが、時間がかかりすぎるのでミラーサイトから2019-09-26-raspbian-buster.zipをダウンロードして、unzipします。
unzipしたディレクトリに2019-09-26-raspbian-buster.imgファイルができあがります。
SDカードにイメージを焼く
フォーマットしたSDカードを準備[^sd-formatter]して、OSXがSDカードをマウントしているディレクトリを確認します。
以下の場合は/dev/disk4
ということが分かります。
% diskutil list
(いろいろ略)
/dev/disk4 (internal, physical):
#: TYPE NAME SIZE IDENTIFIER
0: FDisk_partition_scheme *32.2 GB disk4
1: Windows_FAT_32 NO NAME 32.2 GB disk4s1
Downloadsなどunzipしたファイルのあるディレクトリに移動します。
SDカードをアンマウントして、ダウンロードしたRaspbian OSイメージをSDカードに書き込みます。
% cd Downloads
% diskutil unmountDisk /dev/disk4
% sudo dd bs=1m if=2019-09-26-raspbian-buster.img of=/dev/disk4
かんたんな設定(Wi-Fi設定、SSHできるまで)
SDカードをRaspberryPiに挿して起動します。
この時、HDMIモニター・USBキーボード・USBマウスを準備しているとスムーズです。
今回は、RaspberryPiのインターネット接続はWi-Fi、メンテナンス用として有線LANを使うこととします。
インストール後、初期画面に基本設定をする画面が起動するので自分の環境にあわせた設定とWi-Fiでインターネットにつながるようにします。その後、以下のコマンドを実行してSSH・I2Cの有効化とパッケージの更新を実行します。
% sudo raspi-config
5 Interfacing Options
P2 SSH
Would you like the SSH server to be enabled? → <はい>
P5 I2C
Would you like the ARM I2C interface to be enabled? → <はい>
% sudo apt-get update
% sudo apt-get upgrade ※時間かかる
% sudo reboot
メンテナンス用として有線LANのIPアドレスを設定します。
基本はDHCPでIPアドレスを自動取得という設定にして、IPアドレス取得失敗した場合に192.168.5.55/24になる設定をおこないます。
/etc/dhcpcd.conf
を編集します。インターネット接続はWi-Fiを使いたいのでstatic routers
とstatic domain_name_servers
の行は削除かコメントアウトします。
% sudo vi /etc/dhcpcd.conf
profile static_eth0 ←そのまま
static ip_address=192.168.5.55/24 ←IPアドレスを修正
# static routers ←行を削除 or コメントアウト
# static domain_name_servers ←行を削除 or コメントアウト
inteface eth0 ←コメントアウトはずす
fallback static_eth0 ←コメントアウトはずす
補足
無線LANの設定は/etc/wpa_supplicant
ディレクトリにあるので必要に応じて設定します。
ラズパイにElixirインストール
注意
「aptでインストールしたElixir」と「asdfでインストールしたElixir」を共存させるととても面倒なことが起こると思うのでやめたほうがいいです。
aptでインストール(Elixir古いバージョンでていいから環境をお手軽に構築したい人向け)
Raspbianが提供しているパッケージ管理システムを使ってElixirをインストールします。
公式ドキュメントどおり実行します。
% echo "deb https://packages.erlang-solutions.com/debian buster contrib" | sudo tee /etc/apt/sources.list.d/erlang-solutions.list
% wget https://packages.erlang-solutions.com/debian/erlang_solutions.asc
% sudo apt-key add erlang_solutions.asc
% sudo apt update
% sudo apt install elixir
asdfでインストール(Elixirの最新バージョンを使いたい人向け)
Elixirのバージョンを切り替えて実行できるasdf
を使ってElixirをインストールします。
基本的には公式ドキュメントどおり実行します。
% git clone https://github.com/asdf-vm/asdf.git ~/.asdf --branch v0.7.5
<Bash on Linuxの場合>
% echo -e '\n. $HOME/.asdf/asdf.sh' >> ~/.bashrc
% echo -e '\n. $HOME/.asdf/completions/asdf.bash' >> ~/.bashrc
<Fishの場合>
% echo 'source ~/.asdf/asdf.fish' >> ~/.config/fish/config.fish
% mkdir -p ~/.config/fish/completions; and cp ~/.asdf/completions/asdf.fish ~/.config/fish/completions
% sudo apt-get install automake autoconf libreadline-dev libncurses-dev libssl-dev libyaml-dev libxslt-dev libffi-dev libtool unixodbc-dev unzip curl libncurses5-dev
% asdf install erlang 22.1.5 ※すごい時間かかる!
% asdf install elixir 1.9.4
% asdf global erlang 22.1.5
% asdf global elixir 1.9.4
% iex -v
Erlang/OTP 22 [erts-10.5.3] [source] [smp:4:4] [ds:4:4:10] [async-threads:1] [hipe]
IEx 1.9.4 (compiled with Erlang/OTP 20)
ラズパイのLEDをチカチカ
ラズパイのボードについている緑色のLEDをチカチカさせるプログラムをElixirで作ります。
緑色のLEDは/sys/class/leds/led0/brightness
を1
にすると光ります。root権限でなくても実行できるようにしたいので誰でも読み書き可能にしておきます。このパーミッションはラズパイを再起動すると元に戻ります。
% sudo chmod 666 /sys/class/leds/led0/brightness
iexを起動して以下の内容を入力します。
Led0chika.green(count, sleep_msec)
のように実行するとcount
回緑色のLEDをチカらせ、その間隔はsleep_msec
となります。
defmodule Led0chika do
@green "/sys/class/leds/led0/"
@brightness @green <> "brightness"
@bright "1"
@start 0
def green(count, sleep_msec) do
{:ok, file} = File.open(@brightness, [:write])
start = @start
finish = count
green(start, finish, sleep_msec, file)
end
def green(start, finish, sleep_msec, file) when start == finish do
chika(start, sleep_msec, file)
File.close(file)
IO.puts("finish!!!")
end
def green(start, finish, sleep_msec, file) when start != finish do
chika(start, sleep_msec, file)
green(start + 1, finish, sleep_msec, file)
end
defp chika(start, sleep_msec, file) do
IO.puts(start)
IO.binwrite(file, @bright)
:timer.sleep(sleep_msec)
end
end
入力が完了したら実行してみます。
以下の例では、1,000ミリ秒の間隔で10回緑のLEDをチカらせることとします。
iex(2)> Led0chika.green(10, 1_000)
0
1
2
3
4
5
6
7
8
9
10
finish!!!
:ok
緑色のLEDがチカチカしました!
動画がなくてスミマセン
明日は @torifukukaiou さんの「Nervesを使ってRaspberry Pi 2でLEDをチカチカさせる 〜クリスマスの飾り付けをしよう〜」です。