BluemixでRaspberryPi2を制御する (3)アクチュエータを動かす　光編　外付けのLED

#<i class="fa fa-cubes" style="font-size:1em;"></i>概要
[BluemixのRaspberryPi登録レシピ](https://developer.ibm.com/recipes/tutorials/raspberry-pi-4/)に登場する[デバイス用のsampleプログラム](https://github.com/ibm-messaging/iot-raspberrypi/releases/tag/1.0.2)は、Bluemixからのデータの受信によってシステム停止(Linuxのshutdownコマンド)のみ行える作りになっている。

Raspberry Pi 2にアクチュエータを付け加えてBluemixからアクチュエータを制御するには、[sampleプログラムのソースコード](https://github.com/ibm-messaging/iot-raspberrypi/blob/master/samples/c/)を修正してビルドすれば良い。その方法を整理する。

※以下でやったことの反対方向(Bluemix→Raspberry Pi 2)をやってみる。
[BluemixでRaspberryPi2のセンサーデータを拾う (1)仕組みの理解](http://qiita.com/getapojim/items/b76ea2cfadaff6dfd159)
[BluemixでRaspberryPi2のセンサーデータを拾う (2)センサーを付けてデータを拾う　温度センサーデジタル編](http://qiita.com/getapojim/items/0f2b5178bfaddafcde9f)
[BluemixでRaspberryPi2のセンサーデータを拾う (3)センサーを付けてデータを拾う　温度センサーアナログ編](http://qiita.com/getapojim/items/12e5cb64a8046ab033e9)
[BluemixでRaspberryPi2のセンサーデータを拾う (4)センサーを付けてデータを拾う　温度センサーデジタル編（リベンジ）](http://qiita.com/getapojim/items/0ea4c7369d342d5b00d5)
[BluemixでRaspberryPi2のセンサーデータを拾う (5)センサーを付けてデータを拾う　温度・湿度・気圧まとめて採取編](http://qiita.com/getapojim/items/dfa526ece3af603b981e)
番外編 [『ムック「日経Linux ラズパイマガジン 2015年春号 」電子工作入門キット パーツセット』に入っていたもの](http://qiita.com/getapojim/items/c90edd38c0ad9d5eb379)


これから整理するにあたりきっとまた長い道のりになりそうなので、(1)Sampleプログラムの仕組みの整理と(2)どこをどのように変更すればよいのかを分けることにした。

[(1)　仕組みの理解](http://qiita.com/getapojim/items/8fffa73100292665eebc)
[(2)　アクチュエータを動かす　光編　RasPi2のオンボードLED](http://qiita.com/getapojim/items/b1f29ad5b9a8166ff887)
(3)　アクチュエータを動かす　光編　外付けのLED　　(これ)
[(4)　アクチュエータを動かす　音編](http://qiita.com/getapojim/items/9440de8ee37e6d8e7e63)

#<i class="fa fa-cube" style="font-size:1em;"></i>外付けのアクチュエータを動かす方法
外付けのアクチュエータを動かすにあたり、まずはLEDでやってみる。
オンボードLEDの場合は、`/sys/class/leds`配下に値を書き込むことで制御できたが、
外付けLEDの場合は`/sys/class/gpio`配下に値を書き込むことで制御できる（らしい）。

#<i class="fa fa-cube" style="font-size:1em;"></i>回路（ネタ）
ムック「日経Linux ラズパイマガジン 2015年春号 」第3部 はじめての電子工作ステップ50の内、「No.15 簡単なシェルスクリプトで制御する　LEDを点灯させよう」に記載されている回路でやってみる。

掲載されていた図（Excelで作図）
![No15_外付けLED点灯.png](https://qiita-image-store.s3.amazonaws.com/0/85506/4055afae-5601-e5e1-caad-ac9144b76169.png)

#<i class="fa fa-cube" style="font-size:1em;"></i>回路（設計）
元ネタの図の通りにFritzingで作ってみた。
![No15_外付けLED点灯_ブレッドボード.png](https://qiita-image-store.s3.amazonaws.com/0/85506/038d4e10-216c-8222-281d-a46709032115.png)

#<i class="fa fa-cube" style="font-size:1em;"></i>回路（実装）
Fritzingで作った絵の通りにつなげてみた。
![No15_外付けLED点灯.jpg](https://qiita-image-store.s3.amazonaws.com/0/85506/f633030c-13e6-874d-daea-dfd02e9e9313.jpeg)

##shellスクリプト準備
ムック読者限定サイトに用意されたプログラム「led.sh」を準備する。
以下は手直ししたものだが、変更せずにそのままでも良い。

```bash:/home/pi/bin/led.sh
#!/bin/bash
# 外付けLEDを5秒間点灯する

gpio_number=25                                                # GPIO25(22ピン)を使う
echo "${gpio_number}" > /sys/class/gpio/export                # GPIO25をオープン
echo "out" > /sys/class/gpio/gpio${gpio_number}/direction     # 出力モード(out)に設定
echo "1" > /sys/class/gpio/gpio${gpio_number}/value           # 電圧をHigh(1)にすることで点灯
sleep 5
echo "0" > /sys/class/gpio/gpio${gpio_number}/value           # 電圧をLow(0)にすることで消灯
echo "${gpio_number}" > /sys/class/gpio/unexport              # GPIO25をクローズ
```

##shellスクリプト実行
実行してみる。
LEDが5秒間光る。
root権限が必要

`$ cd ~/bin`
`$ ll led.sh`
`$ chmod 755 led.sh`
`$ sudo ./led.sh`

動画を撮ってみた。
<blockquote class="twitter-video" lang="ja"><p lang="und" dir="ltr"><a href="https://twitter.com/hashtag/RaspberryPi?src=hash">#RaspberryPi</a> <a href="https://twitter.com/hashtag/Bluemix?src=hash">#Bluemix</a> <a href="https://twitter.com/hashtag/IoT?src=hash">#IoT</a> <a href="https://twitter.com/hashtag/MQTT?src=hash">#MQTT</a> <a href="https://t.co/Q0HT8HI6Ox">pic.twitter.com/Q0HT8HI6Ox</a></p>&mdash; m (@getapojim) <a href="https://twitter.com/getapojim/status/658992350358716419">2015, 10月 27</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

#<i class="fa fa-cube" style="font-size:1em;"></i>プログラムの改修内容

[BluemixのRaspberryPi登録レシピに登場するデバイス用のsampleプログラム](https://github.com/ibm-messaging/iot-raspberrypi/releases/tag/1.0.2)を次の通り修正する。
[修正前のソースコードはこちらで参照可能](https://github.com/ibm-messaging/iot-raspberrypi/tree/master/samples/c)

|修正するファイル|新規で追加するファイル|
|:--|:--|
|iotmain.c<br>mqttPublisher.c|なし|

追加・修正内容は以下の通り。

修正内容1

```c:iotmain.c(修正前　30行目)
char subscribeTopic[MAXBUF] = "iot-2/cmd/reboot/fmt/json";
```
```c:iotmain.c(修正後)
char subscribeTopic[MAXBUF] = "iot-2/cmd/ledext/fmt/json";
```

修正内容2
ソースコードのファイル名が「Publisher」になっていて紛らわしいが、下記の抜粋はSubscribe時の処理。

```c:mqttPublisher.c(修正前　126～130行目)
		sprintf(command,"sudo /sbin/shutdown -r %d", time_delay);
		syslog(LOG_INFO, "Received command to restart in %d minutes.",time_delay);
```

```c:mqttPublisher.c(修正後)
		sprintf(command,"sudo /home/pi/bin/led.sh");
		syslog(LOG_INFO, "Received command to control LED external);
```

#<i class="fa fa-cube" style="font-size:1em;"></i>プログラムの改修手順
作業はRaspberryPi2にログインして行う。
実行時ユーザは次の通り
$ : pi
\# : root

1. 設定ファイルの退避
`# cd /etc/iotsample-raspberrypi/`
``# cp -p device.cfg device.cfg.`date +%Y%m%d`_1``
※これで、アンインストール(dpkg -P)してもフォルダとバックアップファイルが残るので安心。

2. 必要パッケージのインストール
`# apt-get install dpkg-dev build-essential devscripts`
`# apt-get install libssl-dev`

3. ソースコード一式を入手
`$ cd ~`
`$ git clone https://github.com/ibm-messaging/iot-raspberrypi.git`

4. ソースコード修正・追加
`$ cd ~/iot-raspberrypi/samples/c/`
`$ vi iotmain.c`
`$ vi mqttPublisher.c`

5. ビルド
`$ debuild -b`
署名のエラーは無視する。

#<i class="fa fa-cube" style="font-size:1em;"></i>iotサービスの再インストール

1. アンインストール（古いのを）
`# dpkg -P iot`

2. インストール
`# cd /home/pi/iot-raspberrypi/samples/`
`# dpkg -i ./iot_1.0-1_armhf.deb`

3. サービスの確認
`# service iot status`
※起動している(okが表示される)こと。

4. 設定ファイル作成
`# cd /etc/iotsample-raspberrypi/`
``# cp -p device.cfg.`date +%Y%m%d`_1 device.cfg``
※1.でいったん削除されてしまうので、1.で退避したファイルで復元

5. サービスの再起動
`# service iot restart`
※起動している(okが表示される)こと。

6. 起動モードの確認
`# service iot getdeviceid`
※registerd mode で起動している(registerd modeが表示される)こと。

#<i class="fa fa-cube" style="font-size:1em;"></i>BluemixからMQTTプロトコルでJSONデータを送信
##MQTTの構成

BluemixのNode-REDアプリからMQTTプロトコルでpublishし、Raspberry Pi 2上のsampleプログラムからsubscribeする。
　MQTTブローカー　　　　：　Bluemixの[IoT Foundataionサービス](https://internetofthings.ibmcloud.com/)
　MQTTクライアント(pub)　：　Bluemixの[Node-RED](http://nodered.org/)アプリ　※Node-REDでなくても良い。
　MQTTクライアント(sub)　：　[デバイス用のsampleプログラム](https://github.com/ibm-messaging/iot-raspberrypi/releases/tag/1.0.2)
　MQTTのトピック　　　　　：　iot-2/cmd/ledext/fmt/json
　MQTTのメッセージ　　　　：　`{"delay":1}`

##MQTTクライアント(publish)の構成
今回はNode-REDアプリとする。
「inject」ノードと「ibmiot out」ノードを使う。
![Node-RED_MQTT_pub_001.png](https://qiita-image-store.s3.amazonaws.com/0/85506/5b6867a2-4b43-f221-4a27-bf9378d9d9b1.png)

injectノードの中身
着火するだけなので空っぽでよい。
![Node-RED_MQTT_pub_002.png](https://qiita-image-store.s3.amazonaws.com/0/85506/01955da7-8847-38ef-4eb1-a25c6b3ff7c2.png)

ibmiot outノードの中身
![Node-RED_MQTT_pub_ledext_001.png](https://qiita-image-store.s3.amazonaws.com/0/85506/28a73b3c-5bd3-d982-7538-f13332eeacfd.png)



|項目名|設定値|備考|
|:--|:--|:--|
|Output Type|Device Command||
|Device Type|iotsample-raspberrypi|IoT Foundationで登録した通りに。<br>IoTFダッシュボードで確認可能|
|Device Id|xxxxxxxxxxxx|RasPi上で以下のコマンドの出力する値<br>`# service iot getdeviceid`<br>IoTFダッシュボードで確認可能|
|Command Type|ledext|トピックの一部になるため固定|
|Format|json|トピックの一部になるため固定|
|Data|{"delay":1}|数字は何でもよい|
|Name|IoTF|Node-RED上の表示名なだけなので何でもよい|

上記2つのノードを線でつないだら、右上の「Deploy」ボタンを押してデプロイする。
![Node-RED_MQTT_pub_004.png](https://qiita-image-store.s3.amazonaws.com/0/85506/82b4339e-41fa-b597-914a-236d1d336a83.png)

injectノードをポチッとすると、RasPi上でシェル(/home/pi/bin/led.sh)が実行される。
![Node-RED_MQTT_pub_005.png](https://qiita-image-store.s3.amazonaws.com/0/85506/a8a9343a-861c-0a73-5cd1-8457215b3126.png)

すぐにLEDの点滅が始まる。（動画を再掲）
<blockquote class="twitter-video" lang="ja"><p lang="und" dir="ltr"><a href="https://twitter.com/hashtag/RaspberryPi?src=hash">#RaspberryPi</a> <a href="https://twitter.com/hashtag/Bluemix?src=hash">#Bluemix</a> <a href="https://twitter.com/hashtag/IoT?src=hash">#IoT</a> <a href="https://twitter.com/hashtag/MQTT?src=hash">#MQTT</a> <a href="https://t.co/Q0HT8HI6Ox">pic.twitter.com/Q0HT8HI6Ox</a></p>&mdash; m (@getapojim) <a href="https://twitter.com/getapojim/status/658992350358716419">2015, 10月 27</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

#<i class="fa fa-cube" style="font-size:1em;"></i>所感
ここまできてようやく/sys/class/gpioを使ってる感がでてきた。
この先LED以外も「/sys/class/gpio」で済めばよいのだが。。。

<!--
#<i class="fa fa-cube" style="font-size:1em;"></i>続き
<font color=red>(2)　センサーを付けてデータを拾う　温度センサーデジタル編　（これから書く）</font>
-->

#<i class="fa fa-cube" style="font-size:1em;"></i>環境

[Raspberry Pi 2 Model B](https://www.raspberrypi.org/products/raspberry-pi-2-model-b/)
[Raspbian](https://www.raspberrypi.org/downloads/raspbian/)
[Bluemix IoT Foundation](https://internetofthings.ibmcloud.com/)
[Node-RED](http://nodered.org/)

#<i class="fa fa-book" style="font-size:1em;"></i>参考
BluemixのRaspberryPi登録レシピ
https://developer.ibm.com/recipes/tutorials/raspberry-pi-4/

BluemixのRaspberryPi登録レシピに登場するデバイス用のsampleプログラム
(Linux用のdaemonになっている)
https://github.com/ibm-messaging/iot-raspberrypi/blob/master/samples/c/

https://github.com/ibm-messaging/iot-raspberrypi/tree/master/samples/c#command-support