ESP8266 ＋ NifiでBigdata（IoT)の基礎を作ってみた話

# スキル
・ハードウェアほぼ経験なし。
・開発能力 おおむね0
・サーバ側 Hadoopボチボチ

#経緯
2017/10/22に秋葉に技術書典3にぶらりと行ったついでになぜか秋月によりたくなった。
会社でIoTがどうとかという話を色々聞くからだと思う。

Arduino互換で小さくてよさげなヤツを発見

![IMG_20171026_200711.jpg](https://qiita-image-store.s3.amazonaws.com/0/121950/eefcb860-18e4-e322-9130-61dd69f7e4f9.jpeg)

#準備
###Arduinoインストール
まずは、Arduinoというソフトをダウンロードするらしい。
この時（2017/10/26）のバージョンは1.8.5だった。

https://www.arduino.cc/en/Main/Software

![SnapCrab_NoName_2017-10-26_21-29-39_No-00.png](https://qiita-image-store.s3.amazonaws.com/0/121950/3382240d-c99d-41f7-7528-2f47d6475611.png)

ダウンロードしてインストール
###ボード情報入手
秋月の説明書によると、次は以下のページを確認しながらESP8266のボード情報を入手するらしい。

http://www.arduinesp.com/getting-started

このページによるとからダウンロードするらしいが、存在せず。
http://arduino.esp8266.com/package_esp8266com_index.json

以下に見つかった。これをArduinoの設定に追加。
http://arduino.esp8266.com/stable/package_esp8266com_index.json

![SnapCrab_NoName_2017-10-26_21-37-12_No-00.png](https://qiita-image-store.s3.amazonaws.com/0/121950/e6520b8e-3cf7-1a07-b931-a6dc832704f0.png)


あとは、ページに従って設定していけばOK。

###Lチカ動作確認

手元にLEDを準備してチカチカさせてみる。

```
void setup() {
  // put your setup code here, to run once:
  pinMode(16,OUTPUT);
}

void loop() {
  // put your main code here, to run repeatedly:
  digitalWrite(16,HIGH);
  delay(500)
  digitalWrite(16,LOW);
  delay(500)
}
```
を書いて、
![IMG_20171026_213840.jpg](https://qiita-image-store.s3.amazonaws.com/0/121950/25743159-0d1b-8832-f3cf-a8ede137b425.jpeg)
に従ってボタンをポチポチしたのち、書き込み。

![SnapCrab_NoName_2017-10-26_21-47-28_No-00.png](https://qiita-image-store.s3.amazonaws.com/0/121950/73bc9e09-6053-8203-330c-c151b71da1c5.png)

100%になると0.5秒刻みでチカチカし始める。

<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">エルチカ <a href="https://t.co/eG6XIyNNbs">pic.twitter.com/eG6XIyNNbs</a></p>&mdash; もんた (@___monta___) <a href="https://twitter.com/___monta___/status/923532164938870784?ref_src=twsrc%5Etfw">October 26, 2017</a></blockquote>

うむ、悪くない。

#本番
安くて色々ついてるという理由で準備したセンサー
・BME280搭載 温湿度・気圧センサモジュール
![BME280.jpg](https://qiita-image-store.s3.amazonaws.com/0/121950/25632fb5-0d36-7cb5-63f5-f4a240b24c18.jpeg)

※記載時点でどう読み取るのかさっぱりわかっていません。

##BME280
まず、BME280の仕様回りをあさる。

ほほーBOSCHのチップなのか。（名前をきいたことがあるくらいだけど）
http://akizukidenshi.com/download/ds/bosch/BST-BME280_DS001-10.pdf

秋月にも同じようなものの情報が。
http://akizukidenshi.com/catalog/g/gK-09421

よくわからんが、I2C、またはSPIという規格で情報通信するとのこと。さっぱりわからんが、I2Cでいこう。

###I2CとBME280の仕様
I2Cの規格は2線で通信するものらしい。
https://ja.wikipedia.org/wiki/I2C

詳細は調べてないけど、サンプルコードを眺める限り、ArduinoはGPIOにつなげば、データを送受信できる。しかもESP8266シリーズの場合、どのPINを使っても設定でどうにかしてくれるらしい（すげー）。
https://macsbug.wordpress.com/2015/10/23/esp8266-%E3%81%A8-i2c/
https://tockn.com/entry/20170309234918


アドレスはSD0のつなぎ方で変わるらしい。
・GND　…　0x76
・VDD　…　0x77
とりあえずGNDにつなごう。

###BME280の接続
・VCC　…　DC1.71V ～ 3.6V とあるので、Arduinoの3.3V出力を使う
・GND　…　俺でもわかるグランドだ。ArduinoのGNDを使う
・SCL　…　クロック信号。ArduinoのGPIO4を使う
・SDA　…　データ信号。ArduinoのGPIO5を使う
・CSB　…　Interfaceの選択。HighでI2Cとのこと。Arduinoの3.3V出力を使う
・SD0　…　I2Cのアドレス選択。ArduinoのGNDを使う

<details><summary>この間に起きたトラブル~ボードが替わっている理由~</summary>
このあと、手元がくるってショートさせたらしく、秋月で購入したESP8266は昇天しました。
落ち込んでいてもしょうがないので、Amazonで新しいESP8266ボードを探して、翌日届きそうなものを購入しました。
それがこちら。
ESP8266 IOT Board
![ESP8266-2.jpg](https://qiita-image-store.s3.amazonaws.com/0/121950/86183223-f6b1-4135-1606-b64804475538.jpeg)
いやらしいことに、ESP8266はいくつかバージョンがあり、ピン配置が異なるようです。
https://www.elecrow.com/wiki/index.php?title=ESP8266_IOT_Board(Arduino_IDE_or_NodeMCU_Lua_Programming)
...えっ... D0とかD1とか、Arduinoで行くと何に相当するんでしょう...
皆さん気を付けましょう
</details>

で、注意ポイントなんですが、SCL、SDAはプルアップと言われるやつで、通常Highにしておく必要があるようです。秋月の回路を見ると4.7KΩなので、理由はわかりませんが、同じくらいの抵抗をくっつけておきます。

ArduinoのPIN番号とESP8266 IOT Boardの番号、そしてさらにはSCL、SDAの対応番号がわかりませんが、調べたところ以下のようになるようです。
SCL は 5（D1）
SDA は 4（D2）
https://qiita.com/exabugs/items/9d1b66aa1d22805afbc8


ここまでで、ハードウェアの接続情報が集まりました。
つなげてみたものが以下です。

![BME280_ブレッドボード.png](https://qiita-image-store.s3.amazonaws.com/0/121950/18a89afe-483d-6971-2cab-22d75bb76203.png)

![BME280_picture.jpg](https://qiita-image-store.s3.amazonaws.com/0/121950/dbc57c5a-13f3-bf5b-06ed-bbbb0fe719b4.jpeg)


で、スイッチサイエンスさんのページにBME280の読み取りコードがあったので、そちらを流用。
https://www.switch-science.com/catalog/2236/

ライセンスコードが明記していないので、コードの記載できません。（すいません）
コードを引っ張ってきてベタっと貼り付けてください。
動きます。

![SnapCrab_NoName_2017-11-3_0-12-40_No-00.png](https://qiita-image-store.s3.amazonaws.com/0/121950/d362847e-b664-0fb0-8d5b-8cf252511741.png)

おー。ぞろぞろデータが取れている。
これだけだとデータを取捨てることになるので、IoTっぽくNifiで受け取ってみましょう。


このあたりを参考に、Wifi接続をします。
https://qiita.com/azusa9/items/7f78069cb09872cf6cbf

```ruby:Wifi接続関数
#include <ESP8266WiFi.h>

#define MYSSID         "XXXXXXXX";
#define SSIDPASSWORD   "YYYYYYYYYYY";
#define NIFISERVERPORT 9000
static const char *NIFISERVERADDR = "192.168.11.8";

void setup() {
   ~BME280の読み込みコード~
Serial.begin(9600);
WiFiConnect();
}
void WiFiConnect()
{
  WiFi.mode(WIFI_STA);
  WiFi.printDiag(Serial);
  WiFi.begin(SSID, SSIDPASSWORD);
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");

  WiFi.printDiag(Serial);
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
}

void loop()
{
   ~BME280の読み込みコード~
  WiFiClient client;
  if (!client.connect(NIFISERVERADDR, NIFISERVERPORT)) {
    Serial.println("Failed to send!");
    return;
  }else{
    client.print(temp_act);
    client.print(",");
    client.print(press_act);    
    client.print(",");
    client.println(hum_act);
  }
  client.stop();
  delay(1000);
```

ほとんどがコピペで修正もしていないので、統一感なくてすいません。

###サーバ側（NiFi）
Nifi側も設定します。
※すぐにDBが準備できないので、ローカルディスクにまとめて保存します。

![SnapCrab_NoName_2017-11-3_1-32-10_No-00.png](https://qiita-image-store.s3.amazonaws.com/0/121950/5e5a3749-0bba-67b9-0a9b-75490778ea4e.png)

TCPを受信するだけ。
Port番号をArduinoに合わせて変更
![SnapCrab_NoName_2017-11-3_1-10-36_No-00.png](https://qiita-image-store.s3.amazonaws.com/0/121950/a3d1df80-283f-e2e6-0fc0-e2f9cec9bbb1.png )

ここだけ少し工夫した。
MergeContentした際に、改行が入っていなかったため、改行処理を追加。
ついでにArduinoは時刻を持っていないので、最初のカラムに時刻を追加。

![SnapCrab_NoName_2017-11-3_10-17-15_No-00.png](https://qiita-image-store.s3.amazonaws.com/0/121950/57581044-2572-1cd5-f14a-3af79516d1b4.png)

あとは一秒ごとに送られてくるデータのマージ。

![SnapCrab_NoName_2017-11-3_1-11-27_No-00.png](https://qiita-image-store.s3.amazonaws.com/0/121950/7c040ad5-c5eb-4424-d1a6-b4d3128f9f5f.png)

とりあえずC:\tmp に突っ込む。

![SnapCrab_NoName_2017-11-3_1-23-43_No-00.png](https://qiita-image-store.s3.amazonaws.com/0/121950/1fb0bb5e-ab09-827c-dbd9-90603eaac64c.png)

で、最終的にC:\tmp\nifiフォルダに出来上がるファイルがこれ。

![SnapCrab_NoName_2017-11-3_10-15-59_No-00.png](https://qiita-image-store.s3.amazonaws.com/0/121950/74923534-2b15-c5e7-4f9a-1eaf24cff606.png)


やったね！