この記事は「fukuoka.ex(その2) Elixir Advent Calendar 2017」の25日目,および
「Raspberry Pi Advent Calendar 2017」の20日目です.
昨日は,@twinbeeさんの
「Google DatalabコンテナにElixirを入れてTensorflexを動かそう」でした.
本記事では,ラズパイのGrovePi+に接続した各種Groveを関数型言語Elixirから扱えるGrovePiライブラリを紹介します.
お知らせ!新たなElixir Advent Calendar、来週6/18(月)から始まります
fukuoka.exアドバイザーズのざっきーさん率いる山崎研究室、通称「ザキ研」の有志と、fukuoka.exアドバイザーズ/キャスト数名が、合同で新たな季節外れのElixir Advent Calendarを始めます
来週6/18(月)からスタートで、「季節外れのfukuoka.ex(その2) Elixir Advent Calender」で連載途中だったシリーズも、「fukuoka.ex x ザキ研 Advent Calendar」で、続きが見れます
どうぞ、来週6/18(月)以降の新たなカレンダーをお楽しみに!
はじめに
どうもこんにちは.
fukuoka.exという福岡のElixir/PhoenixコミュニティにてIoT芸を披露している者です.
巷を賑わせている新しめの関数型言語である**ElixirでIoTできるんじゃね!?**と喧伝しております.
これまでの連載記事はこちら.
|> ElixirでIoT#1.0:IoTボードへのLinux環境の準備
|> ElixirでIoT#1.1:IoTボードへのElixir環境の構築とEEloTツールキットの紹介
|> ElixirでIoT#1.2:いろいろ分かるベンチマークを整備してみる
|> ElixirでIoT#1.3:IoTボードで動いた!Phoenixが立った!性能評価と考察
|> ElixirでIoT#2.1:Nervesって何者?ラズパイでLチカできんの!?
Elixirユーザの皆さまにはいろいろそこそこ反響をいただいて感謝の限りです.
ラズパイユーザな皆さまにも,**ラズパイでElixir使えるよ!?**ということを知っていただきたく,やはり季節外れですが「Raspberry Pi Advent Calendar 2017」の空き日に投下しております.
なお,ラズパイカレンダーに前回投下した記事はこちらです.
|> ElixirでIoT#1.1.1:ラズパイへのErlang/Elixir環境の構築
今回は,Elixirから各種Groveを扱えるGrovePiライブラリを紹介します.
Elixirとは?
RaspberryPi
タグで来た方への説明です.
Elixirは2012年に登場した新しい関数型言語です.ErlangのVM上で走ります.次に来る大物Web言語と言われています.
Elixirには以下の特徴があります.
- 読み書きしやすく,生産性が高い.
- 並行処理(並列処理)のプログラミングが簡単に実現できる.
- 分散システム対応/スケールしやすい.
- 軽量で耐障害性が高い.
あれっ?これってIoTでも使えるんじゃね!??
Groveとは?
Elixir
やErlang
のタグで来た方への説明です.
Groveは,各種センサなどのIoTデバイスを画一パッケージ化したモジュール群です.中国深センにある気鋭のスタートアップであるSeeed社が開発・販売しています.
入出力ピンが4ピンのGroveコネクタで統一されており,簡単に付け替えできるのが特徴です.また,Arduinoやラズパイに96Boardsなどの主要なIoTボードに適合する各種シールドも提供されています.このため,様々なIoTシステムの開発をラピッドに試すことができます
Elixirのラズパイ/Groveへの対応状況
Elixir界隈では,前回の記事でも紹介したとおり,Nervesというプロジェクトにてラズパイへの対応が進んでいます.
Grove対応は,Nerves.Groveというライブラリが提供されており,GitHubでもソースが公開されています.最初はこれを使おうかと思ったのですが,ドキュメントやサンプルアプリが乏しく,扱い方がよく分かりませんでした.開発が2016年8月で止まっているのも気がかりです.
今回は,上記のNerves.Groveを発展させてGrovePiに対応した下記のライブラリを使いました.
GrovePi+とGrovePi Zeroに対応していて,examples/
以下に幾つかサンプルも提供されていて分かりやすいです.Groveモジュールの対応状況はHexDocsをご参照ください.
GrovePiライブラリでは,Erlang VMのNIF経由でラズパイのGPIO,I2C,SPIの各種デバドラにアクセスできるelixir_aleが使われています.
用意した環境
筆者が試してみた環境をまとめてみます.
- ボード:Raspberry Pi 3 Model B
- カーネル:Raspbian Stretch with Desktop 4.9とUbuntu MATE 16.04
- Groveシールド:GrovePi+
- Elixirバージョン:Elixir 1.6.5 (compiled with OTP 20)
- Erlang/OTP 20 [erts-9.3] [source] [smp:4:4] [ds:4:4:10] [async-threads:10] [hipe] [kernel-poll:false]
今回の記事では,以下のGroveモジュールを使いました.
GrovePi+の環境構築
まずはこちらを参考にして,GrovePi+を使えるように環境をインストールします.
インストール後は再起動が必要です.
$ sudo curl -kL dexterindustries.com/update_grovepi | bash
$ sudo reboot
再起動後にGrovePi+をラズパイに刺して,i2cdetect
コマンドで正常にシールド接続が検出できることを確認してください.
sudo i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- 04 -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
GrovePiライブラリの使用方法
それではGrovePiライブラリを使っていきましょう.
まずはmixプロジェクトの作成ですが,この辺りはいつものElixirと同じです.
$ mix new grovepi_test
* creating README.md
* creating .formatter.exs
* creating .gitignore
* creating mix.exs
* creating config
* creating config/config.exs
* creating lib
* creating lib/grovepi_test.ex
* creating test
* creating test/test_helper.exs
* creating test/grovepi_test_test.exs
Your Mix project was created successfully.
You can use "mix" to compile it, test it, and more:
cd grovepi_test
mix test
Run "mix help" for more commands.
$ cd grovepi_test/
mix.exs
にGrovePiライブラリを使うための依存関係を書いてやります.
releaseタグじゃなく最新のmaster
ブランチを明示的に指定してやらないと動かないサンプルがありました.
defp deps do
[{:grovepi, github: "adkron/grovepi", branch: "master"}]
end
あとは,lib/grovepi_test.ex
にプログラミングしていくだけです.
コンパイルと実行はこんな感じです.
elixir_aleの都合でMIX_ENV=prod
を明示指定する必要があるようです.
$ mix deps.get
$ MIX_ENV=prod mix compile
$ MIX_ENV=prod iex -S mix
examples/
の紹介
最後に,GitHubに挙がっているexamplesを使ってみたので紹介します.
とりまgit clone
して移動しましょう.
$ git clone https://github.com/adkron/grovepi
$ cd grovepi/examples
$ ls
alarm demo_pivotpi demo_rgblcd
home_weather_display led_fade
alarm
GrovePi+のA0にButtonを,D3にBuzzerを接続します.
ボタンを押したらAlert!!!!
と表示されて1秒間ブザーが鳴ります.Buzzer音がすっごく大きいので,周りの方々をビックリさせないようにご注意ください
(Buzzerに養生テープ等を貼り付けとくと音量が抑制できます)
$ cd alarm/
$ mix deps.get
$ MIX_ENV=prod mix compile
$ MIX_ENV=prod iex -S mix
Erlang/OTP 20 [erts-9.3] [source] [smp:4:4] [ds:4:4:10] [async-threads:10] [hipe] [kernel-poll:false]
Interactive Elixir (1.6.5) - press Ctrl+C to exit (type h() ENTER for help)
# ボタンを押したら,,,??
iex(1)> Alert!!!!
ちなみに,コネクタの配置はlib/alarm.ex
の6-7行目で変更できます.
# Pick ports that work on both the GrovePi+ and GrovePi Zero
@button_pin 14 # Port A0
@buzzer_pin 3 # Port D3
demo_pivotpi
シリアルモータを制御できるPivotPi用のサンプルです.
手元に持っていなかったんでカッツアイ.
demo_rbglcd
LCDモジュールを使ったサンプルです.今回のLCD RGB Backlightは,名前の通りRBGのバックライトが付いています.
GrovePi+のI2C-1に接続します.
$ cd demo_rgblcd/
$ mix deps.get
$ MIX_ENV=prod mix compile
$ MIX_ENV=prod iex -S mix
LCDの表示を制御するデモが幾つか用意されています.
無限ループで動きますので,その都度Erlangを終了させる必要があります.
iex(1)> DemoRGBLCD.autoscroll()
%GrovePi.RGBLCD.Config{display_control: 12, entry_mode: 6, function: 56}
0
1
2
3
4
5
6
7
8
9
%GrovePi.RGBLCD.Config{display_control: 12, entry_mode: 7, function: 56}
0
1
2
3
4
5
6
7
BREAK: (a)bort (c)ontinue (p)roc info (i)nfo (l)oaded
(v)ersion (k)ill (D)b-tables (d)istribution
実際に動いている様子です.0-9の数字が右から左へ受け流されます.
iex(4)> DemoRGBLCD.colors()
バックライトがRGBWで点灯します.
動画だともっと綺麗なんですが,GIFだとコレが限界ですかね.
その他のデモの解説はさらっといきますかね.
iex(3)> DemoRGBLCD.blink()
# Say "Hello World!" and toggles cursor blinking on and off every 3000ms
iex(4)> DemoRGBLCD.cursor()
# Say "Hello World!" and toggles the cursor on and off every 1500ms
iex(5)> DemoRGBLCD.display()
# Toggles the display on and off every 1500ms
iex(6)> DemoRGBLCD.text_direction()
# Demonstrates text direction both ways
iex(7)> DemoRGBLCD.set_cursor()
# Demonstrates moving the cursor to the second line
home_weather_display
温湿度センサ(Temperature&Humidity Sensor)の値をLCDに表示します.
ただこれはなぜかNerves環境下で動作するクロス開発のアプリになっています.使用されているNervesや他ツールのバージョンが古いようで,最新環境を構築している筆者の母艦Macではコンパイルすらできませんでした.
そのうちセルフ開発で扱えるように本サンプルを作り変えたいと思っています.
led_fade
GrovePi+のA2にRotary Angle Sensorを,D3にLED Socketを接続します.
ロータリの角度に応じてLEDの点灯量が変化します.
$ cd led_fade/
$ mix deps.get
$ MIX_ENV=prod mix compile
$ MIX_ENV=prod iex -S mix
実際の動作はこんな感じ.
細かくて分かりにくい上に汚い指ですみません,,,
ラズパイはデジタルピンしか出ていないのですが,Groveを使用することでアナログ制御も簡単に実現できるようになります.
まとめ
- ElixirでGrove使えるよ!IoTラピッドプロトタイピングできちゃうよ!!
- Groveモジュールを扱えるGrovePiライブラリとそのサンプルを紹介しました
お知らせ
満員御礼!Elixir MeetUpを6月末に開催します
※応募多数により、増枠しました
「fukuoka.ex#11:DB/データサイエンスにコネクトするElixir」を6/22(金) 19時に開催します.
私も**「ElixirでIoTやってみた」**芸を披露する予定です.
実は今回の記事は,このfukuoka.ex#11に向けたネタ仕込みの先出しだったりするのです.
温湿度センサをセルフで扱えるようにして,環境データをセンシングしてさくっとWeb表示できたらおもろいかな?と思っていたりしています.
そして,ネタ仕込みの開発状況は下記のGitHubで逐次公開していきます.
まだ今回のサンプルを移しただけなのですが,,,ちゃんと準備が進んでいるのかリポジトリをWatchしてたら面白いかもしれませんw
どうぞfukuoka.ex#11での発表にご期待ください!!