Elixir/NervesでPLC(多機能リレー)を作ってみた

この記事は、[#NervesJP Advent Calendar 2020](https://qiita.com/advent-calendar/2020/nervesjp)の７日目です。
６日目は、@takasehideki 先生の「[Docker(とVS Code)だけ！でNerves開発環境を整備する](https://qiita.com/takasehideki/items/ecf9bd4a43f66b2d6273)」でした。Docker＋Windowsユーザにとっては有り難い記事ですね～

---

#1.はじめに

NervesJPという[コミュニティ](https://nerves-jp.connpass.com/)では、いろいろな勉強会やハンズオンに取り組んでいます。

**Nervesとは？** - [Nervesが開拓する「ElixirでIoT」の新世界](https://www2.slideshare.net/takasehideki/nerveselixiriot)

ハンズオンしたら、やはり身近なところで実装してみたくなるところ･･･そういう用途を想定して、身近な測定や制御に活用するための機材を作ってみました。

**補足：PLCという単語に馴染みのない方へ･･･**

 1. [プログラマブルロジックコントローラ](https://ja.wikipedia.org/wiki/%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9E%E3%83%96%E3%83%AB%E3%83%AD%E3%82%B8%E3%83%83%E3%82%AF%E3%82%B3%E3%83%B3%E3%83%88%E3%83%AD%E3%83%BC%E3%83%A9)
 1. [PLCとは？](https://www.robot-befriend.com/blog/plc/)

つまり、工場やプラントのなかの生産設備、エレベータ、ビル空調・照明･･･など、産業機器の制御に特化したコンピュータです。

##なぜPLCにElixirを使いたいの？

PLCの多くは[ラダーなどの言語](https://ja.wikipedia.org/wiki/%E3%83%A9%E3%83%80%E3%83%BC%E3%83%BB%E3%83%AD%E3%82%B8%E3%83%83%E3%82%AF)で書かれています。
FA系では非常に馴染みのある言語ですが、C#やPythonなどの言語とは大分概念が違うので、IT系の方が触るとなると取っ掛かりに戸惑いがあります。

比較的新しいPLCでは、LinuxやリアルタイムOS等が自由に動かせる環境が整ってきて、多くの高級言語も容易に扱う事ができるようになりました。

それらの言語の中で、長期に渡る安定動作や分散処理、RUN中書き込み[^run]など、PLCならではの機能を要求する場合に対応出来そうなのが、Elixirかなと考えています。

 - Elixirの特徴（分かり易い記事です）
   - [最速で知る！ ElixirプログラミングとErlang/OTPの始め方](https://eh-career.com/engineerhub/entry/2017/06/12/110000)
 - 組込み向けElixirの可能性について
   - [Nervesが開拓する「ElixirでIoT」の新世界](https://www.slideshare.net/takasehideki/nerveselixiriot)
   - [ElixirでIoT](https://qiita.com/takasehideki/items/94820516ec95b85bae32)

まだまだ作例が少ないのですが、上手くいけばラダーに変わる高級言語になり得るかと期待しているので、個人的に色々模索しています。

[^run]: [RUN中書き込みとは、PLCが動作中でもプログラム変更できる機能](https://www.niwakafa.com/entry/2017/10/11/%E3%80%90%E5%88%9D%E7%B4%9A%E7%B7%A8%E3%80%91PLC%28%E3%82%B7%E3%83%BC%E3%82%B1%E3%83%B3%E3%82%B5%29%E3%81%AE%E3%83%A2%E3%83%8B%E3%82%BF%E3%83%A2%E3%83%BC%E3%83%89%E3%80%81RUN%E4%B8%AD%E6%9B%B8%E3%81%8D#:~:text=RUN%E4%B8%AD%E6%9B%B8%E3%81%8D%E8%BE%BC%E3%81%BF%E3%81%A8%E3%81%AF,%E3%81%99%E3%82%8B%E3%81%93%E3%81%A8%E3%81%A7%E3%81%8D%E3%82%8B%E6%A9%9F%E8%83%BD%E3%81%A7%E3%81%99%E3%80%82)


#2.考え方

いわゆる多機能リレーをモデルにしています。
>**市販品の一例**
スマートリレー、多機能リレー：[IDEC](https://jp.idec.com/idec-jp/ja/JPY/PLC/%E3%82%B9%E3%83%9E%E3%83%BC%E3%83%88%E3%83%AA%E3%83%AC%E3%83%BC/c/Smart_Relay)、[OMRON](https://www.fa.omron.co.jp/products/category/control-components/programmable-relays/)
ローコストPLC：[キーエンス](https://www.keyence.co.jp/products/controls/plc-package/kv_nano/)、[三菱電機](https://www.mitsubishielectric.co.jp/fa/products/cnt/plc_fx/items/index.html)

表題は（イメージしやすいかと思って）PLCとしていますが、PLCほどガリガリと制御する程でもなく、やや高機能なリレーの制御、ついでにアナログ入力や[SeeedのGROVE](https://wiki.seeedstudio.com/Grove_System/)との接続までを、組み合わせたデバイスとして、簡単に活用出来るイメージで開発してみました。

**[Raspberry Pi Zero WH](https://raspberry-pi.ksyic.com/main/index/pdp.category/15/pdp.names/Pi%20Zero%20WH/)をそのまま載せて**いるので、Nerves/Elixir以外でも、**PythonやGo、RustなどRaspberryPiで動く言語は何でもOK**です。

##(1)外観

タカチの[「DINモジュールボックス H53シリーズ」](https://www.takachi-el.co.jp/products/H53)にぴったり収まるようにしています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145581/b5019fed-1792-aa77-9e2b-8d4d30605da7.png)

中の基板はこんな感じです。
Raspberry Pi Zero WH を垂直に取り付けます。
こうすることで、Raspberry Pi Zeroの側面に設置のコネクタに対し、DINモジュールボックスの正面からアクセスできるようになっています。（用事が無ければ、フタをして構いません）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145581/eff8551e-583c-13f7-60d2-ce6e6ca7f258.png)

**DINレールに設置してみた**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145581/f4474a94-4fa8-55c9-74f4-077af655a11f.png)

##(2)仕様

今までRaspberryPiを活用してきて、最低限必要な機能を盛り込んでみました。

また、NervesのOTA機能、[Nerves HUB](https://www.nerves-hub.org/)などを活用する際に必要な、[Nerves Key](https://docs.nerves-hub.org/nerves-key/getting-started)も設置できるようにしています。

|機能|仕様|補足|
|:--|:--|:--|
|出力|4ch（フォトリレー絶縁）|シンク（NPN）・ソース（PNP）駆動切り替え可能。各chの動作確認LEDあり。|
|入力|4ch（フォトカプラ絶縁）|〃|
|AD変換|10bit 2ch|非絶縁・入力保護のダイオード付き|
|時刻保持|リアルタイムクロックDS1307|ボタン電池でバックアップ|
|GROVEコネクタ|あり、I2C x 1|5V電源タイプ|
|外部UART端子|あり x 1|RaspberryPiのUARTに直結|
|電源|5V系/24V系は個別に供給|それぞれポリスイッチ（過電流防止）あり|

#3.ハードウェアのはなし

基板のデータはKiCAD形式で、Githubに公開しています。
ライセンスはクリエイティブコモンズです。

 - [RasPi_NervesBOX - Github](https://github.com/trihome/RasPi_NervesBOX)

gerberディレクトリに、ガーバデータも一式入れてありますので、PCB業者さんにそのまま発注すれば基板を作る事ができます。

基板の発注の仕方については、こちらを参考にしてください。

 - [Fusion PCBでの注文手順](https://github.com/trihome/RasPi_PiFA/blob/master/doc/README_pcb.jp.md#fusion-pcb%E3%81%A7%E3%81%AE%E6%B3%A8%E6%96%87%E6%89%8B%E9%A0%86)

##(1)全体構成

各入出力は、下記の様に接続しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145581/9463d59c-2c77-3132-f1b3-fe590635afa1.png)

##(2)入力/出力回路

（抜粋）
入出力共に、フォトカプラで絶縁しています。
74HC541を経由して、RaspberryPiのGPIOに接続しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145581/87389bb2-545a-b77e-324b-eb94cba4b6b2.png)

**J5, J7の接続**

|対応表|GPIO(BCM表記)|本機の端子|
|:--|:--|:--|:--|
|入力|12|X0|
|〃|16|X1|
|〃|20|X2|
|〃|21|X3|
|出力|6|Y0|
|〃|13|Y1|
|〃|19|Y2|
|〃|26|Y3|

**J2の接続**

24V系の電源と、24V系の入出力端子の回路です。
`J6`コネクタへの電源供給の仕方で、シンク・ソース駆動を切り替えられます。
供給方法に合わせて、LEDの点灯対象や、X・Y側のCOM端子への給電も変わります。

|駆動したい方法|Pow24+In|Pow24-In||D16|D13||X側COM端子|Y側COM端子|
|:--|:--|:--|:--|:--|:--|:--|:--|:--|
|シンク|+24V|GND|→|点灯|消灯||GND|+24V|
|ソース|GND|+24V|→|消灯|点灯||+24V|GND|

ソース駆動にしたいときには、24V端子の接続を逆にするだけです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145581/bc356f71-a405-3708-61f7-a6488f35aa44.png)

入力(X)、出力(Y)とも、コモン端子を隣りに設置しているので、
接続対象の配線を隣り合わせでターミナルに差し込んでください。

<!--
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145581/7d77dbc8-8923-e9ac-b536-6f0bda3eacf7.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145581/646c1dc2-c4a4-32de-92a9-a81276553d1e.png)
-->

##(4)I2C回路

（抜粋）

RaspberryPiのI2C端子から、3.3V→5Vレベルコンバータを経由して、RTCとNervesKey、GROVEコネクタに接続します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145581/7d0d8517-2877-9026-fc02-cce748614e00.png)

#4.ソフトウェア

本記事では詳細は触れませんが、Qiita他でハードウェア制御の例がありますので、そちらのコードで試してみてください。

 - [Nerves - Qiita](https://qiita.com/tags/nerves)
   - https://qiita.com/takasehideki/items/94820516ec95b85bae32
   - https://qiita.com/torifukukaiou/items/bf0354db8cd0628f161e
   - https://qiita.com/nishiuchikazuma/items/cce6152430467cffba56
   - https://qiita.com/kikuyuta/items/6c8debcfe7741ef48dd3
   - https://qiita.com/kikuyuta/items/904acd2ce4117168d22a
   - https://qiita.com/kikuyuta/items/a5a0dd72ef926299be7e

#5.おわりに

`ハードは作った。さぁこれからだ！`
今後、いろいろな社会実装に向けて、活用していけたら良いなぁ･･･
（どうやって展開していこう^^;）