BluemixでRaspberryPi2を制御する (4)アクチュエータを動かす　音編

#<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](http://qiita.com/getapojim/items/b8028d1aeb975432afda)
(4)　アクチュエータを動かす　音編　(これ)

#<i class="fa fa-cube" style="font-size:1em;"></i>外付けのパーツを動かす方法
光の次は音を出してみる。[圧電スピーカー](http://qiita.com/getapojim/items/c90edd38c0ad9d5eb379#14-圧電スピーカー)を使う。
ケーブルが赤黒の2本のみなのでLEDと同じようにつないで`/sys/class/gpio`配下に値を書き込めばよいのかな？と思ったが、

　1. [ムック](https://www.google.co.jp/search?q=ムック「日経Linux ラズパイマガジン 2015年春号 」)に「他励式」「自励式」というキーワードが出てきた。
　2. シンプルなはずの[ムック](https://www.google.co.jp/search?q=ムック「日経Linux ラズパイマガジン 2015年春号 」)のソースコードがわざわざライブラリを使って書かれている。

この２点から気になってググったところ、以下のことが判明した。
　・自励式は電池につなぐと音が出る。
　・他励式は電池につなぐだけでは音は出ず、文字通り誰かが励ましてあげないと音が出ない（らしい）。

手元のパーツセットに入っているのはどうやら他励式らしいので、素直にライブラリを使うこととする。

#<i class="fa fa-cube" style="font-size:1em;"></i>回路（ネタ）
ムック「日経Linux ラズパイマガジン 2015年春号 」第3部 はじめての電子工作ステップ50の内、「No.28 WiringPiのSoftware Toneライブラリを活用　圧電スピーカーで音を鳴らそう」に記載されている回路でやってみる。

掲載されていた図（Excelで作図）
![No28_圧電スピーカー.png](https://qiita-image-store.s3.amazonaws.com/0/85506/cf61ba3e-319b-cd91-fdf4-cde494314be8.png)

#<i class="fa fa-cube" style="font-size:1em;"></i>回路（設計）
元ネタの図の通りにFritzingで作ってみた。
![No28_圧電スピーカー_ブレッドボード.png](https://qiita-image-store.s3.amazonaws.com/0/85506/da240157-62f1-8acc-5c64-e72b9aab295d.png)

#<i class="fa fa-cube" style="font-size:1em;"></i>回路（実装）
Fritzingで作った絵の通りにつなげてみた。
![No28_圧電スピーカー.jpg](https://qiita-image-store.s3.amazonaws.com/0/85506/4f33d0a8-5b21-1342-21af-c5481ea36f40.jpeg)

##WiringPiの導入
`# cd /var/tmp`
`# git clone git://git.drogon.net/wiringPi`
`# cd wiringPi`
`# ./build`

導入確認のためにバージョンを確認してみる。
`# gpio -v`
バージョンが表示されること。

##<i class="fa fa-cube" style="font-size:1em;"></i>Raspberry Pi 2上で音を出してみる
ムック読者限定サイトに用意されたプログラム「software_tone.c」をコンパイル・実行してみる。
ドレミファソラシドを1度だけ鳴らす。
root権限が必要。

`$ cd ~/bin`
`$ ll software_tone.c`
`$ gcc -o software_tone software_tone.c -lwiringPi`
`$ sudo ./adc_lm35dz`

![音を出してみる.png](https://qiita-image-store.s3.amazonaws.com/0/85506/89646e79-a8f2-b37d-da58-eaad19d7e9f8.png)


出力例）
音　　：　ドレミファソラシド
画面　：　数値はドレミファソラシドの各音の周波数値を表す。

<!--
##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をクローズ
```
-->

動画を撮ってみた。
<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/l5ynRtj2oD">pic.twitter.com/l5ynRtj2oD</a></p>&mdash; m (@getapojim) <a href="https://twitter.com/getapojim/status/659356311381934080">2015, 10月 28</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/buzzer/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/software_tone");
		syslog(LOG_INFO, "Received command to control buzzer");
```

#<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/buzzer/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_buzzer_001.png](https://qiita-image-store.s3.amazonaws.com/0/85506/c86e0f9b-5a24-48ad-7c5f-373ef10384f4.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|buzzer|トピックの一部になるため固定|
|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/software_tone)が実行される。
![Node-RED_MQTT_pub_005.png](https://qiita-image-store.s3.amazonaws.com/0/85506/a8a9343a-861c-0a73-5cd1-8457215b3126.png)

ドレミファソラシドが鳴る。（動画を再掲）
<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/l5ynRtj2oD">pic.twitter.com/l5ynRtj2oD</a></p>&mdash; m (@getapojim) <a href="https://twitter.com/getapojim/status/659356311381934080">2015, 10月 28</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`を使ってるんだと信じたい！

<!--
#<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