LoginSignup
4
6

More than 5 years have passed since last update.

④ESP8266で取得したセンサ情報をM2xにアップロード

Last updated at Posted at 2016-09-16

はじめに

この記事は、電子工作の基礎からESP8266というWifi機能を持ったArduino互換の端末を使って取得した情報をM2Xという、センサ情報を受け取りグラフ表示してくれるクラウドサービスにセンサ情報をアップするところまでをカバーした記事です。
全部で4つの記事から構成されています。
①から順番にご覧ください。

①かんたんな回路を作って電子工作の基本を習得する
http://qiita.com/windows222/private/6f11904f30ff540dcc37
②ESP8266(Arduino)に簡単なプログラムをアップする
http://qiita.com/windows222/private/c60d086a5909d2bff39e
③ESP8266で人感センサ情報を取得する
http://qiita.com/windows222/private/e6bcea0bef795c8cb30c
④ESP8266で取得したセンサ情報をM2xにアップロード (←本記事)
http://qiita.com/windows222/private/9d77cc3fe0094b78a4db


記事概要

ここでは、前の記事で取得した人感センサの情報を、Wifiを通じてM2Xにアップします。
その後、アップされたM2Xの情報をグラフで確認してみます。

M2xアカウント作成

M2Xとは?

M2Xとは、IoT端末からRESTやMQTT等で送られる情報を受け取り、自動的にグラフを作成してくれるWEBサービスです。一日あたりのデータ受信件数に限りがありますが、無料で利用することができます。

アカウント作成手順

アカウントの作成手順は下記の通りです。

M2Xサイトにアクセス
https://m2x.att.com/create-account

必要情報を入力し、アカウントを作成
画面右上のSign upをクリックし、必要情報を入力してアカウント情報を作成します。
(Githubアカウントがある場合は、情報の入力を省略できる)

デバイスを作成
アカウントの作成が完了したら、Create New > Create Deviceを選択し、必要情報を入力し、デバイスを作成します。
rows_as_groups.png

(オプション)Curlでの動作確認
実際にRESTリクエストを送信し、グラフが更新されることを確認します。RESTリクエストの送信は、curlが必要です(Linux)
作成が完了したら、ApicheetSheetというボタンをクリックします。表示された画面の中にUpdating a specific stream's current valueと書かれている箇所を探して、値をコピーします。
image

コピーしたコマンドを実行して、結果を確認します。下記の様な文字列が返ってきたら成功です。

実行コマンド
curl -i -X PUT http://api-m2x.att.com/v2/devices/33d8824f9deee514852ee77258d74b42/streams/PIR_sensor/value -H "X-M2X-KEY: 7e7b47ba14a03597d6ad729c0313e4ae" -H "Content-Type: application/json" -d "{ \"value\": \"40\" }"
実行結果例
HTTP/1.1 202 Accepted
Content-Type: application/json; charset=UTF-8
Date: Sun, 18 Sep 2016 08:59:53 GMT
Server: nginx
Vary: Accept-Encoding
X-M2x-Version: v2.100.4
Content-Length: 21

{"status":"accepted"}192:~ nagase$ curl -i -X PUT http://api-m2x.att.com/v2/devi52ee77258d74b42/streams/PIR_sensor/value -H "X-M2X-KEY: 7e7b47ba14a03597d6ad729c0313e4ae" -H "Content-Type: application/json" -d "{ \"value\": \"40\" }"
HTTP/1.1 202 Accepted
Content-Type: application/json; charset=UTF-8
Date: Sun, 18 Sep 2016 08:59:58 GMT
Server: nginx
Vary: Accept-Encoding
X-M2x-Version: v2.100.4
Content-Length: 21

デバイスIDの取得
情報入力後、画面にデバイスIDが表示されるので、PRIMARY ENDPOINTとPREIMARY API KEYの2つを記録します。(後で再度表示することも可能)
rows_as_groups.png

Wifi接続情報の入手

次に、ESP8266をWifiに接続するための環境の設定、情報を入手します。
必要となるのはwifiのSSIDとパスワードの2つです。
(Wifi環境がない場合、携帯のテザリングでも構いません。)

プログラム修正

③で作成したプログラムに、---ここから----, ---ここまで----の間のプログラムを追加します。
最後に、loop()の中を同じように更新します。

#include <Arduino.h>
#include <stdio.h>
#include <string.h>

#include <ESP8266WiFi.h>

#define PIR_MOTION_SENSOR 4  //人感センサを示す番号
#define GREEN_LED  15  //緑のLEDを示す番号(15番ピンに接続)

int loopCount = 0; //現在のループ数
int detectedCount = 0; //人感センサの検知回数


 //------ここから↓----------
// Use WiFiClient class to create TCP connections
WiFiClient client;
WiFiClient m2xClient;

int requestFreq = 10; //サーバへの更新頻度
const char* ssid     = "NAGA12345"; //★接続するWifiのSSID
const char* password = "nagase222"; //★接続するWifiのパスワード
const char* m2xHost = "api-m2x.att.com"; //接続するホストのアドレス
String m2xKey = "7e7b47ba14a03597d6ad729c0313e4ae";//★M2Xに接続する為のKey
String m2xURL =  "/v2/devices/33d8824f9deee514852ee77258d74b42/streams/PIR_sensor/value";//★デバイスを示すURL
const int httpPort = 80;//ポート番号

/*
 * Wifiに接続する
 */
void startWIFI() {
  Serial.println("starting wifi");
  WiFi.begin(ssid, password);

  int failedcount = 0;
  while (WiFi.waitForConnectResult() != WL_CONNECTED) {
    failedcount++;
    Serial.println("Connection Failed! retriying.");
    delay(2000);
    if (failedcount >= 5) {
      Serial.println("Connection Failed! Rebooting...");
      ESP.restart();
    }
  }
  Serial.println("M2xに接続します");
  //M2Xサーバに接続する
  if (!client.connect(m2xHost, httpPort)) {
    Serial.println("接続に失敗しました。");
  }
}

/**
   M2xにデータを送信する
 * */
void submitToM2X(int PIRNumber, int returnValue) {

  if (returnValue >= 1) {  //検出数が0でない場合は送信対象とする
//m2xサーバーに接続する
    if (!m2xClient.connect(m2xHost, 80)) {
      Serial.println("connection failed 1");
      delay(1000);

    }
    //M2xにデータを送信する
    m2xClient.print("PUT " + m2xURL + " HTTP/1.1\r\n" +
                    "Host: " + m2xHost + "\r\n" +
                    "User-Agent: curl/7.43.0\r\n" +
                    "Accept: */*\r\n" +
                    "X-M2X-KEY: " + m2xKey + "\r\n" +
                    "Content-Type: application/json\r\n" +
                    // "Connection: close\r\n" +
                    "Content-Length: 17\r\n\r\n" +
                    "{ \"value\": \"" + returnValue + "\" }\r\n");

    Serial.printf("sent %d to the m2x server\n", returnValue);
    String response = m2xClient.readString();
    Serial.println(response);
  } else {
    Serial.println("値が0なのでM2xには送信しません");

  }
}
//-----↑ここまで-----------

/**
   LEDを点滅させる
*/
void blinkLED(int pinNo, int waitTime, int repertCount) {
  for (int i = 0; i <= repertCount; i++) {
    digitalWrite(pinNo, HIGH);
    delay(waitTime);
    digitalWrite(pinNo, LOW);
    delay(waitTime);
  }
}
/**
 * 人感センサの情報をチェックし、現在の検知状態を調べる。
 */
boolean isPeopleDetected(){
  int sensorValue = digitalRead(PIR_MOTION_SENSOR);
  if (sensorValue == HIGH){ //検知状態
    return true;  //yes,return ture
  }
  else if(sensorValue == LOW){  //未検知状態
    return false;  //no,return false
  }
}

/*
 * 人感センサをチェックし、結果をコンソールに出力
 */
void sensePIR() {
  loopCount++;
  int returnValue = 0;

  //センサの状態を調べて、周りに人がいるかをチェック
  if (isPeopleDetected()==true) { //人がいたら 
    digitalWrite(GREEN_LED, HIGH); //人感センサ検知したらLED点灯
    detectedCount++;
    Serial.printf("PIR1:find someone! loopCount=%d detectedCount=%d\n",loopCount,detectedCount);
  }
  else {        //人がいなかったら
    digitalWrite(GREEN_LED, LOW); //人感センサ検知なければLED消灯
    Serial.printf("PIR1:no one can find..loopCount=%d \n", loopCount);
  }
}

/**
 * 準備開始(最初に呼ばれる関数)
 */
void setup(){
  Serial.begin(115200);//シリアルポートを通信速度115200で開始
  Serial.println("start setup");

  pinMode(PIR_MOTION_SENSOR, INPUT); //ピンを入力状態にセット
  pinMode(GREEN_LED, OUTPUT); //ピンを出力状態にセット

  Serial.println("end of setup");
}

/**
 * セットアップの後に連続して呼ばれる
 */
void loop(){
  //人感センサの情報を取得
  sensePIR();
  delay(1000);

  if (loopCount >= requestFreq) { //送信頻度を超えたら実行
    //wifiに接続
    startWIFI();
    delay(1000);
    //m2xに検出数を送信
    submitToM2X(1, detectedCount);
    //ループカウントをリセット
    loopCount = 0;
    //検知数をリセット
    detectedCount = 0;
  }
}

動作確認

書き換えが完了したら、プログラムを動かす。
下記のようなメッセージが表示されたら、情報のアップが成功している。
6495AC35-8E1F-4755-9E18-BB87EE079841.png

結果確認

M2Xにアクセスし、結果がグラフとして表示されることを確認する。
image

電池で動かす

これまでは、USBからの電源を使ってESP8266を動かしていましたが、電池で動作させることも可能です。
下記の手順で試してください。
・ESP8266をPCから外し、電池を接続する。
・スイッチをBootに切り替えてRESETボタンを押す。
・M2Xをみて、M2Xに情報がアップされていることを確認する。

応用/参考情報

単3電池2本使った場合の稼働時間はどのくらい?

単3電池2本で動かし続けた場合、どのぐらい連続動作が可能なのかを計算してみる。

ESP8266の消費電力
Wifi接続時 3v 80mA
Wifi切断時 3v 30mA
単3電池2本の容量
3v 2000mA
持ち時間(答え)
2000mA(x3v)÷80mA(x3v)=25時間

電池の持ち時間の計算方法について詳細に知りたい場合はコチラを参照してください。
http://qiita.com/windows222/items/1f4834cecb63f578877c

単1電池で動かした場合は?

単1電池の容量は、単3電池の6.5倍
https://note.mu/a_hisano/n/na87bcca3f0c4
答え
25x6.5 = 162.5 = 約1週間

もっと長く動かしたい場合は?

もっと長く動作させたい場合は、スリープモードを利用することで更に長く動作させることも可能です。
例えば気温や気圧を調べる場合、センサの情報は5分〜10分に一度の情報で十分です。その場合、センサの情報を取得→データをサーバにアップ→スリープ(10分)を繰り返せば、1ヶ月以上の連続動作が可能となります。
(スリープ中の消費電力は10uAと非常に低い)
http://qiita.com/azusa9/items/65a5c3772c41631b5ca1

センサを変える

本記事では人感センサを利用しましたが、光センサ、圧力センサ、音センサなど、センサを付け替えることで様々な情報の取得が可能です。取得したい情報に応じて、センサーを変えるだけで様々な情報の取得が可能となります。

まとめ

・本日学んだことを応用することで、様々なセンサの情報をインターネットに保管し、グラフ化する仕組みを簡単につくれる
・ESP8266は安価で、高機能で、扱いやすい端末

応用課題

・光センサを取り付け、取得した情報をM2Xにアップしてみましょう。(上級編)
 >http://qiita.com/windows222/private/8649eb7c96a6429c4a9a

4
6
2

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
4
6