XBee Wi-FiでセンサーデータをAWSにアップロードする

![pic](http://f.st-hatena.com/images/fotolife/s/satzz/20140727/20140727191356_original.jpg?1406456048)

温湿度センサーのデータをArduinoからXBee Wi-Fiを介してAWSにアップロードする。

## 準備
###センサー回路
- センサー:
扱いやすいセンサーがよいだろう。温湿度センサー[RHT03](https://strawberry-linux.com/catalog/items?code=18158)(950円)など。(秋月店頭で買ったときは950円もしなかった気がするが、正確に覚えていない。アウトレット品だったかもしれない)
ついでの以下のものを買う。安いものでよい。
- ブレッドボード
- ジャンパー線セット
- 0.1μFセラミックコンデンサ

###XBee Wi-Fi

[スイッチサイエンス](http://www.switch-science.com/catalog/1364/)などで買える。4000円程度。
###Arduino XBeeシールド
[スイッチサイエンス](http://www.switch-science.com/catalog/1323/)などで買える。1300円程度だが、ハンダ付けのためハンダとこて、こて台が必要。
写真を見ながらハンダ付けしておく。
※XBeeとArduinoを接続するだけなのでプロトタイピング段階ではブレッドボードなどで代用してもよいかも。
とくにArduinoからシールドへの通信とMacへの通信がバッティングするので、MacからArduinoへプログラムを書き込むたびにシールドを抜き差しすることになりあまりよくない。

###Arduino Uno
Amazonでも買える。3000円程度。
###ACアダプター
回路全体に電源を入力する。家庭用ACを6V以上のDCに変換できればなんでもよい。
[マルツ](http://www.marutsu.co.jp/shohin_87053/)などで買えば1900円程度。

## 回路組み立て
回路図はMacでいいソフトを知らないので割愛。
センサの[データシート](http://dlnmh9ip6v2uc.cloudfront.net/datasheets/Sensors/Weather/RHT03.pdf)を見ながら、組み立てたシールドと接続する。
RHT03をブレッドボードに差し、左から1,2,3,4番ピンとして、ジャンパ線で1をVCC(3.3V)、2をArduinoの入力（ここでは7番とする）、4をGNDにつなぐ。
1と4の間に0.1μFを渡す。

## ソフトウェア設定
### Webサーバー
AWSのEC2インスタンスに[Sinatra](http://www.sinatrarb.com/)などを準備する。
inbound/outboundの`4567`番(Sinatraのデフォルト)を開けたセキュリティグループにインスタンスを割り当てる。ポートは別に変更してもよい。

```
$ gem install sinatra
```

```ruby:api.rb
require 'sinatra'

post '/api/measurements' do
  vals = request.body.read
  logger.info vals
end
```
```
$ ruby api.rb  -o 0.0.0.0
```
### Arduino
[Web](http://arduino.cc/en/Main/Software)でArduinoをDLしておく。

今回のセンサは回路は単純だがデータの読み取りはやや複雑(温度と湿度のデータが1本の線にパルス化して乗ってくる)で、専用のライブラリがあるのでArduinoのライブラリディレクトリに配置。

```
$ git clone https://github.com/adafruit/DHT-sensor-library /Applications/Arduino.app//Contents/Resources/Java/libraries/DHT
```

Arduinoを起動し、`Sketch` > `Import Library` > `DHT`と追加されていることを確認。

透過モードのXBeeに対してデータを送るためには、Arduinoからは`Serial.print`を使えばよい。

新しいスケッチを書いて`Command + U`でArduinoに転送。

- ライブラリは華氏温度を返すので摂氏温度にする。
- `DHT22_PIN`を`7`にしているのはArduinoの7番にセンサをつないでいるから。
- floatからStringへの変換はArduino Unoの場合は`dtostrf`を使う。


```c++:DHTtest.ino
#include <DHT.h>
#define DHTTYPE DHT22
#define DHT22_PIN 7
DHT dht(DHT22_PIN, DHTTYPE);

void setup() {
  pinMode(DHT22_PIN, INPUT);      
  Serial.begin(9600);
}

char ch[10];
char ct[10];

void loop()
{
  float h  = dht.readHumidity() ;
  float t  = 5.0/9.0*(dht.readTemperature(true)-32.0); // fahrenheit -> celsius
  dtostrf(h, 6, 2, ch);
  dtostrf(t, 6, 2, ct);
  
  String postData = "{humidity:";
  postData.concat(ch);
  postData.concat(",temperture:");
  postData.concat(ct);
  postData.concat("}");

  Serial.print("POST /api/measurements HTTP/1.1\r\n");
  Serial.print("Content-Length: " + String(postData.length()) + "\r\n\r\n");
  Serial.print(postData);
  
  delay(2000);

}

```

### XBee Wi-Fi

[前回](http://qiita.com/satzz@github/items/814eee8dd37347fcb4e6#2-2)と同様にXBeeの設定を行う。変更が必要なのは以下くらいだろう。

- Destination IP Address : (EC2インスタンスのpublic IP)
- Source Port : `11D7` (4567 = 0x11D7)
- Destination Port : `11D7`

## 確認
XBee Wi-Fiとシールド、Arduinoを組み合わせ、電源を入れる。
サーバーログを見て

```
"{humidity: 59.40,temperture: 27.50}"
xxx.xx.xxx.xxx - - [27/Jul/2014 14:24:43] "POST /api/measurements HTTP/1.1" 200 35 0.0005
XXX.ne.jp - - [27/Jul/2014:14:24:43 UTC] "POST /api/measurements HTTP/1.1" 200 35
- -> /api/measurements
```
のようにJSONが2秒おきに送られ始めたら成功(だめなら`tcpdump port 4567`も見る)。
湿度は59.40%、気温は27.50度ということらしい。
濡れたタオルなどを近づけると湿度が上がるのを確認する。
あとはWebサーバー側で煮るなり焼くなりすればよい。

## 参考
- [XBee Wi-FiをWebに接続する](http://qiita.com/satzz@github/items/814eee8dd37347fcb4e6)