LoginSignup
7
16

More than 5 years have passed since last update.

ESP8266を使って温度センサ情報をIFTTTに投げる

Posted at

やったこと

Boschの温度・気圧・湿度センサ(BME280)をWifiボードESP8266に接続。
IFTTTと連携してデータをスプレッドシートに格納

はじめに

 近年、IoTという言葉で表されるように、センサ機器をインターネットに接続することで、センサ情報を手軽に、リアルタイムに、集約的に扱うことが可能になってきました。

 ホビーユースでこのブームに火をつけた要因の一つはなんといってもESP8266だと思います。それ以前だと、センサ情報を処理してインターネットに接続することを考えると、ArduinoとWifiボードを用いるか、もしくはラズパイを用いることを考えました。どちらも数千円のコストがかかります。

 ESP8266ならば、数百円、評価用ボードを用いても2000円くらいで済んでしまいます。

 最近では後継機種であるESP32も出てきており、こちらはWiFiに加えてBluetoothも扱えるようですが、ESP8266もまだまだ現役ですし、先行機種であるがゆえに情報の蓄積も多いと思います。

 今回は記事としては目新しさはないですが、ESP8266と温度(+湿度+圧力)センサであるBME280を接続し、WiFiアクセスによりIFTTTに情報を投げてみます。

ソースコードはgithubに公開しています。

設定

ESP8266

Arduino用の開発環境を用います。
また、センサ情報は5分に一回IFTTT側に送ればいいと考えから、deepsleepモードを使っています。
deepsleepに関する記事はこちらが参考になりました。
ESP8266の真骨頂Deep-Sleepモードの使い方
IFTTTサーバへの接続状態を判断するために4番ピンにLEDを接続し、接続試行中にLEDが点滅するようにしています。

BME280

BME280は通信にSPIとI2Cが使えますが、今回はI2Cを選択します。
I2Cアドレスを0x76として使うために、BME280のSDO端子をグラウンドに落としておきます。

コードは基本的に、スイッチサイエンスさんが公開しているBME280用のサンプルコード をベースに、ESP8266の機能や、IFTTTへの接続部分を追加していきます。

ESP8266とBME280の接続

留意点、ピン配置としては

  • Wire.begin関数で12,13番ピンを指定
    • ESP8266の12番ピンをBME280のSDI番に接続
    • ESP8266の13番ピンをBME280のSCKに接続

ESP8266によるI2Cの使い方は
macsbug - ESP8266 と I2C
BME280のI2C接続での使い方は
AmbientでIoTをはじめよう

WiFiの設定

  • SSID
  • パスワード を把握

IFTTTの設定

  • event名
  • WebHookアプリのsecret keyを設定

IFTTT側の設定は特に書かないので各自やりたいことをやってください。設定方法は例えば
ESP8266とBME280とIFTTTでIoTボタンをつくった
に詳しく書かれています。同じような事をしていらっしゃるかたが既にいました。

コードの解説

Wifi, IFTTTの設定

#include <ESP8266WiFi.h>
#include <Wire.h>


char* ssid     = "put your SSID";
const char* password = "put your password"

const char* host = "maker.ifttt.com";
const char* event = "put your event";
const char* secretkey = "put your secretkey";

最初の2行はSSID名、パスワードを指定します。下の3行はIFTTT側の設定。通知したいイベント名を設定します。また、Webhooksを用いるので、 webhookのsecretkeyを入手しておき、指定しておきます。
secretkeyの確認に関してはこちらなどが参考になると思います。eventはIFTTT側の設定と同じにしておきます。

ちなみにこのコードではポート80を使ってhttp通信をおこなっています。つまり、パスワードが平文で流れるので、セキュリティ的に非常によろしくないです。ゲスト用のアクセスポイントを使うなどしてください。(それでもwebhook側のsecret keyはわかってしまいますが)。https通信については確認中です。(180711)

データの取得とIFTTTへのデータ転送


void loop()
{
  double temp_act = 0.0, press_act = 0.0, hum_act = 0.0;
  signed long int temp_cal;
  unsigned long int press_cal, hum_cal;

  readData();

  temp_cal = calibration_T(temp_raw);
  press_cal = calibration_P(pres_raw);
  hum_cal = calibration_H(hum_raw);
  temp_act = (double)temp_cal / 100.0;
  press_act = (double)press_cal / 100.0;
  hum_act = (double)hum_cal / 1024.0;
  Serial.print("TEMP : ");
  Serial.print(temp_act);
  Serial.print(" DegC  PRESS : ");
  Serial.print(press_act);
  Serial.print(" hPa  HUM : ");
  Serial.print(hum_act);
  Serial.println(" %");


  Serial.print("connecting to ");
  Serial.println(host);

  // Use WiFiClient class to create TCP connections
  WiFiClient client;
  const int httpPort = 80;
  if (!client.connect(host, httpPort)) {
    Serial.println("connection failed");
    return;
  }

  // We now create a URI for the request
  String url = "/trigger/";
  url += event;
  url += "/with/key/";
  url += secretkey;
  url += "?value1=";
  url += String(temp_act);
  url += "&value2=";
  url += String(press_act);
  url += "&value3=";
  url += String(hum_act);

  Serial.print("Requesting URL: ");
  Serial.println(url);

  // This will send the request to the server
  client.print(String("GET ") + url + " HTTP/1.1\r\n" +
               "Host: " + host + "\r\n" +
               "Connection: close\r\n\r\n");

  // Read all the lines of the reply from server and print them to Serial
  while (client.available()) {
    String line = client.readStringUntil('\r');
    Serial.print(line);
  }
}

readData関数でI2C通信を用いてBME280から温度、圧力、湿度データを取得します。
取得したデータはグローバル変数であるtemp_raw, pres_raw, hum_rawに格納され、
さらにcalibration_X (X=T, P, H)関数とスケール変換により実際の値に変換されます。

その後、WiFiClientクラスのインスタンス変数clientを作成し、host変数を用いてIFTTTに接続します。
先ほどの測定値を文字列に変換し、event, secretkeyと連結することでリクエストのためのURIを作成します。

最後にclientインスタンスのprintメソッドでサーバーにGETリクエストを送信します。
さらにサーバーからの返信があればシリアルコンソールに表示します。

Deep sleepモード

 Serial.println("Deep sleep start!");
  ESP.deepSleep(300 * 1000 * 1000, WAKE_RF_DEFAULT);
  delay(1000);

loop関数の最後に上記のように記述してESP8266をディープスリープさせます。時間の単位はマイクロ秒なので、ここでは止めたい時間である300秒を1,000,000倍しています。
WAKE_RF_DEFAULTと最後のdelay関数に関しては
ESP8266の真骨頂Deep-Sleepモードの使い方
を参考にしてみてください。

deepSleepモードに入ったあとは、設定時間後にもう一度プログラムが再起動されます。起動から接続、データ送信完了まで大体数秒でしょうか。ですので、10秒とか20秒間隔でデータを送信したい場合はdeepsleepモードは有効ではありません。(もっともそんな使い方する人はいないと思いますが。。)

最後に

簡単にですが、ESP8266を用いてIFTTTにセンサ情報を投げる方法を解説しました。
私の使い方としてはwebhookを受け取った後にgoogle spreadsheetに書き込んでいます。

実はこのあとが本当にやりたいことで、google homeと連携して「今の温度は?」と聞いたら答えてくれるようにできたらと思っています。また進展しましたら記事にしたいと思います。

7
16
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
16