LoginSignup
10
6

More than 5 years have passed since last update.

地球の反対側にあるESP8266を複数台連携させる

Posted at

概要

IoTはモノとモノがつながる世界!

ということで「インターネット経由でデバイスがデバイスを動かす」を試してみます。具体的にはWiFi接続された2つのESP8266を用いて、IoTプラットフォームThingSpeak を介し、片方がもう一方を動作させる方法を紹介します。インターネット経由なので、各々Wi-Fi接続されていれば、一方が地球の反対にあっても同じ動作をします。

SW_talkback.gif

これは磁気スイッチの開閉を検知して、離れた場所でLチカ(開くとON)するシンプルな例ですが、入出力は様々なものに置き換えて応用できます。
デバイスの遠隔操作というと難しそうなイメージがあるかもしれませんが、今回はThingSpeakのTalkBackという機能を利用し、各デバイスではコマンドの「書き換え」「読み取り」のみの簡単なコーディングで連携できます。

image.png

もくじ

1. 準備
2. ThingSpeakのTalkBack設定
3. 磁気スイッチON/OFFデータを収集する(コマンドの書き換え)
4. TalkBackのコマンドに連動してLチカさせる(コマンドの読み取り)
5. まとめ

1. 準備

■ハードウェア

●ESPr® One ×2 https://www.switch-science.com/catalog/2620/
●リードスイッチ(磁石付セット) http://akizukidenshi.com/catalog/g/gP-04025/
●その他(LED,抵抗,ジャンパワイヤ、USBmicroケーブル等)

■開発環境

Arduino IDE (作成時は1.6.5を利用)

■ThingSpeakのアカウント、Channel作成

IoT プラットフォーム ThingSpeak
https://thingspeak.com/

ThingSpeakは無料で使い始めることができるIoTプラットフォームで、「データ収集と可視化」「解析」「アクション」の機能を持っています。

ThingSpeakの基本的な使い方は、こちらでわかりやすくまとめられています。
データを簡単に保存&グラフ化できるThingSpeakが便利!
http://iwathi3.hatenablog.com/entry/Data-to-Graph-ThingSpeak

データロギングに使うChannel IDWrite API Keyをメモっておきます。

2. ThingSpeakのTalkBack設定

TalkBackの作成

ThingSpeakの[Apps][TalkBack]をクリックします。

image.png

つづいて[New TalkBack]をクリックします。

image.png

次にTalkBackの名前と[Add a new Command]をクリックし、Command Stringに「SW_OFF」と入力します。これは事前にCommand IDを取得するのが目的なので、このCommand Stringはデバイスから書き換えて利用します。入力が終わったら[Save TalkBack]を押します。

image.png

TalkBack ID / API Key / Command IDの確認

表示されている①TalkBack ID(TalkBackの)API KeyCommand IDを控えておきます。

image.png

3. 磁気スイッチON/OFFデータを収集する(コマンドの書き込み)

データ収集デバイスのコーディング

準備ができたら、デバイス連携を行います。まずはデータ収集とコマンドの書き換えから。
一つ目(データ収集側)のデバイスで行うのは下記です

image.png

ESPr® Oneの入力PinはIO2を利用し、磁気スイッチの他方のリードはGNDに接続します。
Pin2をInputモードにし、その状態に応じて「SW_ON」もしくは「SW_OFF」のコマンドをThingSpeakのTalkBackに送ります。磁石が離れているとPin2はHighになります。 下記のサンプルではputTalkBack()でコマンドの書き換え、writefield()でChannelへのデータロギングを行っています。

image.png

コマンドの書き換えは、Talkbackのページにアップデート方法が書かれているので、この通りにESP8266からコマンドを送ります。

image.png

サンプルコード

#include <ESP8266WiFi.h>

char thingSpeakAddress[] = "api.thingspeak.com"; 
unsigned long myChannelNumber = ******; // Channel ID
String myWriteAPIKey = "****************"; // Channel Write API Key
String talkBackID = "*****"; // TalkBack ID
String talkBackAPIKey = "****************"; // TalkBack API Key
String COMMAND_ID ="*******"; // TalkBackで作成したCommand ID
String url = "/talkbacks/"+talkBackID+"/commands/"+COMMAND_ID;
const char* host = "api.thingspeak.com";
String magsw ="0";

char ssid[] = "******";   //  無線LANのSSID 
char pass[] = "******";   // 無線LANのpassword

int status = WL_IDLE_STATUS;
WiFiClient  client;

void setup() {
  Serial.begin(115200);
  WiFi.begin(ssid, pass); // WiFi接続
  pinMode(2, INPUT); // IO2を入力Pinに設定
}

void loop() {
// スイッチが離れ、IO2がHighになったら
// Channel Fieldへの書き込みとTalkBackのコマンドの書き換えを行う
  if (digitalRead(2) == HIGH){ 
    String magsw = "1";
    String commandstr = "SW_ON";
    writefield(magsw); // Channelへのデータ書き込み
    putTalkBack(commandstr); // TalkBackコマンドの変更
  }
  else{
    String magsw = "0";
    String commandstr = "SW_OFF";
    writefield(magsw);
    putTalkBack(commandstr);
  }

  delay(100); // 無料版使用の場合はChannelへの書き込みは15秒に1回に変更。delay(15000)
}

  void putTalkBack(String commandstr) 
 {
    if (client.connect(thingSpeakAddress, 80))
  { 
    Serial.println("Connected to ThingSpeak.");
    Serial.println("talkback post: " + commandstr);
    String tsData = "api_key="+ talkBackAPIKey +"&command_string="+commandstr;
    // talkbackコマンド書き換えのためにhttpコマンド送信
    client.print(String("PUT ") + url + "&headers=false" + " HTTP/1.1\r\n" 
                                      + "Host: " + host + "\r\n"
                                      + "Connection: close\r\n"
                                      + "Content-Type: application/x-www-form-urlencoded\r\n"
                                      + "Content-Length: "+tsData.length()+"\n\n"+tsData+"\n\n");
    client.stop();
    delay(100);
  }
  else
  {
     Serial.println("Connection failed.");
  }
 }

  void writefield(String magsw) 
 {
    if (client.connect(thingSpeakAddress, 80))
  { 
    Serial.println("Connected to ThingSpeak for write field.");
    Serial.println("write data: " + magsw);
    String SWData = "api_key="+ myWriteAPIKey +"&field1="+ magsw;
    // Channel fieldへのデータ書き込みのためにhttpコマンド送信
    client.print(String("POST /update HTTP/1.1\r\n") 
                                      + "Host: " + host + "\r\n"
                                      + "Connection: close\r\n"
                                      + "Content-Type: application/x-www-form-urlencoded\r\n"
                                      + "Content-Length: "+SWData.length()+"\n\n"+SWData+"\r\n\r\n");
    client.stop();
  }
  else
  {
   Serial.println("Connection failed.");
  }
 }

4. TalkBackのコマンドに連動してLチカさせる(コマンドの読み取り)

Lチカするデバイスのコーディング

3ではスイッチの変化でTalkBackのコマンドが定義される状態になりました。
続いてもうひとつの(コマンドに連動しアクションする)デバイスで用意する機能は下記です。

image.png

TalkBackのコマンドは下記のようにGET コマンドで読み取ることができます。
ここでも必要なのは①TalkBack ID(TalkBackの)API KeyCommand ID

image.png

取得ができたら、コマンドに応じて出力Pinの「HIGH」「LOW」を切り替えるだけです。

image.png

サンプルコード

#include <ESP8266WiFi.h>

const char* ssid     = "***"; // 無線LAN SSID
const char* password = "***"; // 無線LAN password
const char* host = "api.thingspeak.com";
String TalkBackID ="*****"; //Talkback ID
String TalkBackAPIKey ="****************"; // Talkback API key
String Command_ID ="*******"; // Talkbackで作成したコマンドID
// TalkBackコマンド取得のためのURL
String url = "/talkbacks/"+TalkBackID+"/commands/"+Command_ID+"?api_key="+TalkBackAPIKey;

// Use WiFiClient class to create TCP connections
WiFiClient client;
const int ledPin =  13; //Pinの指定IO13

void setup() {
  Serial.begin(115200);
  delay(100);

  // WiFiに接続
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

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

  pinMode(ledPin, OUTPUT);
}

void loop() {

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

  if (client.connect(host, 80)) {
    Serial.println("Tcp Connection eastablished with thingSpeak API");
  }
  else {
    Serial.println("connection failed");
    return;
  }
  // 接続が確認されたらTalkBackの現在のコマンドの状態を取得する
  client.print(String("GET ") + url + "&headers=false" + " HTTP/1.1\r\n" + "Host: " + host + "\r\n" + "Connection: close\r\n\r\n");

  delay(100); 
  // メッセージの読み取り
  String messageBody = "";
  while (client.available()) {
    String line = client.readStringUntil('\n');
    if (line.length() == 1) { 
      messageBody = client.readStringUntil('\n');
      break;
    }
  }
  // コマンドのON/OFFに応じて出力を変更する
  Serial.print("Found a message, the message is: ");
  if(messageBody == "SW_ON"){
    Serial.print(messageBody);
    digitalWrite(ledPin, HIGH);
  }
  if(messageBody == "SW_OFF"){
    Serial.print(messageBody);
    digitalWrite(ledPin, LOW);
  }

  client.stop();

  Serial.println();
  Serial.println("closing connection");
  Serial.println();
  delay(100);

}

5. まとめ

ThingSpeakのTalkBackを用いて
・HTTPコマンドを投げる
・Lチカ(Pin I/Oの制御)
の基本的な機能で複数のESP8266を連携することができました。
コマンドで管理することで、動かす側、動かされる側それぞれ分けて接続を考えればよく、
Channel Fieldへの結果のロギングも合わせてデバックも非常に簡単になります。
デバイスを3個4個と拡張していくこともできます。

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