BluemixでRaspberryPi2のセンサーデータを拾う (3)センサーを付けてデータを拾う　温度センサーアナログ編

#<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)は、どんなにセンサーがたくさん付いていようが固定の4項目のデータのみをBluemixに送信する作りになっている。

Raspberry Pi 2にセンサーを付け加えて固定4項目以外のデータをBluemixで取得するには、[sampleプログラムのソースコード](https://github.com/ibm-messaging/iot-raspberrypi/blob/master/samples/c/)を修正してビルドすれば良い。その方法を整理する。

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

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

#<i class="fa fa-cube" style="font-size:1em;"></i>前提
RaspberryPi2がBluemixのIoTFサービスに[「レシピ」](https://developer.ibm.com/recipes/tutorials/raspberry-pi-4/)を使って接続済みであること。

#<i class="fa fa-cube" style="font-size:1em;"></i>回路（ネタ）
ムック「日経Linux ラズパイマガジン 2015年春号 」第3部 はじめての電子工作ステップ50の内、「No.34 A/D変換機を実際に活用　アナログ温度センサーで温度を測定してみよう」に記載されている回路でやってみる。

掲載されていた図（Excelで作図）
ムックには「MISO (22ピン)」と記載されていたが「MISO (21ピン)」の誤植ではないかと思うので修正した。
![温度を測定するための回路_アナログ.png](https://qiita-image-store.s3.amazonaws.com/0/85506/684e236c-bfae-ee79-524a-b748b768d586.png)

#<i class="fa fa-cube" style="font-size:1em;"></i>回路（設計）
元ネタの図の通りに[Fritzing](http://fritzing.org/download/)で作ってみた。
MCP3002のパーツはここからから入手して、[Fritzing](http://fritzing.org/download/)にインポートした。
http://fritzing.org/media/fritzing-repo/projects/r/rpi-radio/fritzing/RPi_radio.fzz
![温度を測定するための回路_アナログ2.png](https://qiita-image-store.s3.amazonaws.com/0/85506/fe3f535f-7138-e057-c004-ca4b74f3ef27.png)

#<i class="fa fa-cube" style="font-size:1em;"></i>回路（実装）
Fritzingで作った絵の通りにつなげてみた。
![温度デジタル_回路(実装)2.jpg](https://qiita-image-store.s3.amazonaws.com/0/85506/8b152882-2b62-e889-6080-ddfed5640c8f.jpeg)

#<i class="fa fa-cube" style="font-size:1em;"></i>Raspberry Pi 2上でSPIの有効化
作業はRaspberry Pi 2にログインして行う。
実行時ユーザは次の通り
$ : pi
\# : root

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

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

##SPI有効化
Raspberry Pi 2はraspi-configから設定する。
`# raspi-config`

「8 Advanced Options」を選択して、「Select」を押下
![SPI有効化1.png](https://qiita-image-store.s3.amazonaws.com/0/85506/fdae1465-e76f-ad2a-2de3-7aeffa008764.png)

「A6 SPI」を選択して、「Select」を押下
![SPI有効化2.png](https://qiita-image-store.s3.amazonaws.com/0/85506/a0efa6c0-231f-4a2f-7834-f169cd11ece7.png)

「はい」を押下
![SPI有効化3.png](https://qiita-image-store.s3.amazonaws.com/0/85506/0904d679-b20a-a847-b470-a3c04c9c7d7d.png)

「了解」を押下
![SPI有効化4.png](https://qiita-image-store.s3.amazonaws.com/0/85506/7f8a4fed-7afb-9771-eeb7-2f9403e55af7.png)

「はい」を押下
![SPI有効化5.png](https://qiita-image-store.s3.amazonaws.com/0/85506/92b08493-8b60-4ebc-13fb-1e9d8709d0af.png)

「了解」を押下
![SPI有効化6.png](https://qiita-image-store.s3.amazonaws.com/0/85506/46107739-75a9-0c61-0fc9-dd063bf8c138.png)

「Finish」を押下。どれが選択されていても良い。
![SPI有効化7.png](https://qiita-image-store.s3.amazonaws.com/0/85506/c440a40d-bd6c-986a-413f-f1004023544d.png)

「はい」を押下。再起動される。
![SPI有効化8.png](https://qiita-image-store.s3.amazonaws.com/0/85506/44a5d25d-9bb9-05b2-31a4-d9903e2a20f0.png)

再起動後にSPI用のモジュールが読み込まれていることを確認する。
`$ lsmod | grep spi`
「spi_bcm2708」が表示されること。


#<i class="fa fa-cube" style="font-size:1em;"></i>Raspberry Pi 2上で温度を読んでみる

ムック読者限定サイトに用意されたプログラム「adc_lm35dz.c」をコンパイル・実行してみる。
画面に温度を出力する。5秒間隔で20回。
センサーを指でつまむと温度が上がり、離すと下がる。

`$ mkdir -p ~/bin`
`$ cd ~/bin`
`$ ll adc_lm35dz.c`
`$ gcc -o adc_lm35dz adc_lm35dz.c -lwiringPi`
`$ ./adc_lm35dz`

画面出力例）
`t = 28.037109, v = 87`
v　：　読み取った値
t　：　温度　(100 * 3.3 * v / 1024で計算した結果)

![温度を出力してみる_アナログ.png](https://qiita-image-store.s3.amazonaws.com/0/85506/b5d6f448-78ef-1cd5-1d30-c04de278eb7d.png)

#<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>iot.h<br>jsonator.c<br>Makefile|lm35dz.c|

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

修正内容1

```c:iotmain.c(修正前　61行目)

```

```c:iotmain.c(修正後)
//lm35dz.c
float getLm35dzTemp();

```

修正内容2

```c:iotmain.c(修正前　152～153行目)
		JsonMessage json_message = { DEVICE_NAME, getCPUTemp(), sineVal(
				MIN_VALUE, MAX_VALUE, 16, count), GetCPULoad() };
```

```c:iotmain.c(修正後)
		JsonMessage json_message = { DEVICE_NAME, getCPUTemp(), sineVal(
				MIN_VALUE, MAX_VALUE, 16, count), GetCPULoad(), getLm35dzTemp() };
```

修正内容3

```c:iot.h(修正前　22～27行目)
  struct json {
	  char myname[100];
	  float cputemp;
	  float sine;
	  float cpuload;
  };
```

```c:iot.h(修正後)
  struct json {
	  char myname[100];
	  float cputemp;
	  float sine;
	  float cpuload;
	  float lm35dztemp;
  };
```

修正内容4

```c:jsonator.c(修正前　51行目)

```

```c:jsonator.c(修正後)
	strcat(jsonReturned, ",");

	strcat(jsonReturned, "\"lm35dztemp\":");
	sprintf(buffer, "%.2f", passedrpi.lm35dztemp);
	strcat(jsonReturned, buffer);

```

修正内容5

```c:Makefile(修正前　12～14行目)
iot: iotmain.c cpustat.c mac.c mqttPublisher.c jsonator.c iot.h jsonReader.c
	export LIBRARY_PATH=$(COMPILELIBDIR):$(LIBRARY_PATH)
	$(CC) iotmain.c cpustat.c mac.c mqttPublisher.c jsonator.c cJSON.c jsonReader.c -o $@ -l$(LIBNAME) -lpthread -lssl -lm -L $(COMPILELIBDIR) -I .
```

```c:Makefile(修正後)
iot: iotmain.c cpustat.c mac.c mqttPublisher.c jsonator.c iot.h jsonReader.c lm35dz.c
	export LIBRARY_PATH=$(COMPILELIBDIR):$(LIBRARY_PATH)
	$(CC) iotmain.c cpustat.c mac.c mqttPublisher.c jsonator.c cJSON.c jsonReader.c lm35dz.c -o $@ -l$(LIBNAME) -lpthread -lssl -lwiringPi -lm -L $(COMPILELIBDIR) -I .
```

追加内容1　（ムック読者限定サイトに用意されたプログラム「adc_lm35dz.c」をベースに作成）

```c:lm35dz.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wiringPi.h>

const int PI_CE  = 0; // CE0を使う場合は 0、CE1を使う場合は 1を指定
const int ADC_CH = 1; // ADコンバータのCH0を使う場合は 0、CH1を使う場合は 1を指定
const int CLOCK_SPEED = 3200000; // 500,000 から 32,000,000 の間で指定

unsigned int readMCP3002(int pi_channel, int adc_channel);
float getLm35dzTemp();

unsigned int readMCP3002(int pi_channel, int adc_channel) {
  unsigned int v = 0;
  unsigned char data[2] = {};
  data[0] |= 0x60; // ここでは固定
  data[0] |= adc_channel==0 ? 0x00 : 0x10; // ADコンバータのCH0、CH1のどちらを使うかで変わる
  wiringPiSPIDataRW(pi_channel, data, 2);  // pi_channelにつなげたADコンバータからSPIでデータ読み取り
  v = ((data[0] & 0x03) << 8) + data[1];   // 1バイト目の下位2ビットと2バイト目にデータ値が入っているので取り出す
  return v;
}

float getLm35dzTemp() {
  unsigned int v; // MCP3002から読み取った値
  float t; // 温度
  int i;   // カウンタ
  if (wiringPiSPISetup(PI_CE, CLOCK_SPEED) < 0) { // SPI初期化
    return EXIT_FAILURE;
  }
  v = readMCP3002(PI_CE, ADC_CH);
  t = 100.0 * 3.3 * (float)v / 1024.0;
  return t;
}
```

#<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 iot.h`
`$ vi jsonator.c`
`$ vi Makefile`
`$ vi lm35dz.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``
※6.でいったん削除されてしまうので、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 IoT Foundationサービスで確認
IoT Foundationのダッシュボードで、センサー情報欄にて確認する。
センサーの温度データを受信できた！
![BluemixでLM35DZの温度を表示.png](https://qiita-image-store.s3.amazonaws.com/0/85506/99f0da88-b099-907d-f1a5-4f71f9b40143.png)

#<i class="fa fa-cube" style="font-size:1em;"></i>所感
「/sys/class/gpio配下を参照する」というのはなんだったのか。。。
デジタルの温度センサーや他のセンサーはそれで行けるのか？？

#<i class="fa fa-cube" style="font-size:1em;"></i>続き
[(4)　センサーを付けてデータを拾う　温度センサーデジタル編（リベンジ）](http://qiita.com/getapojim/items/0ea4c7369d342d5b00d5)

#<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/)

#<i class="fa fa-book" style="font-size:1em;"></i>参考
Fritzingダウンロード
http://fritzing.org/download/

Fritzing用のMCP3002のパーツ
http://fritzing.org/media/fritzing-repo/projects/r/rpi-radio/fritzing/RPi_radio.fzz

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/