ESP-WROOM-02(Arduino互換)とTwilioで電話をかける

まえがき

(読み飛ばしてかまいません)

2016年夏、息子がヘボコン・ワールドチャンピオンシップにに参加し、Arduino AGのファウンダーの一人であるDavid Cuartielles氏によりArduino賞に選ばれました。そして、副賞としてArduino/Genuinoスタータキットを2セット頂きました。

このイベントはとても盛り上がり、家族のいい思い出となりました。

自分は小学生の頃(40年以上前^^;)から電子工作を始めており、仕事はソフトウェア開発であるものの、ここ十数年PIC、ArduinoRaspberry Pi等いろんなことができるデバイスが簡単に入手できる環境になってきて、手を出したいと思っていました。そこに息子がArduinoをもらうというきっかけがあったので、これ幸いと息子と一緒にArduinoをいじり始めました。

電話を始めとするコミュニケーション・クラウド・サービスであるTwilioにも馴染みがあるので、ヘボコンArduinoTwilioというキーワードの組み合わせで何かできないかと思い、考えたシナリオはこうです。ヘボコンが攻撃を受けたら搭載されたArduinoがTwilio経由で電話を操縦者にかけて、攻撃されていることを音声合成で報告するというものです。

システム 

全体のシステムは下図の通りです。

 

f:id:tsun226:20170206213636p:plain

構成:

ESP-WROOM-02WiFi機能を持ったAdruino互換CPU(今回は開発用のスイッチサイエンス製ESPr Developerを使用)

R … ルータ(iPhoneテザリングを利用)

Twilio … (REST APIによりTwilioデベロッパーセンターのTwiML Binを利用)

動作:

  1. ヘボコン上のスイッチに敵のヘボコンが当たり、プログラムが起動する。
  2. Arduino(互換)がWiFi→ルータ→インターネット経由でTwilio REST APIに接続し、架電のリクエストをする。
  3. Twilioは事前に登録されている指示に従い架電し、音声合成によりメッセージを伝える。

 この記事では、Twilioの設定(TwiML)とESP-WROOM-02(Arduino互換)で動作させるプログラム(スケッチ)について主に説明します。

 

Twilioの設定

Twilioの基本的な使い方については、説明を省略します(Twilioのサイトを参照してください)。

TwiMLの作成

  1. Twilioサイトにログインし、デベロッパーセンター → TwiML Bins を選択します。
  2. 「+」マークをクリックし、TwiML Binを新規作成します。
  3. ConfigurationのFRIENDLY NAMEに任意の名前を、TWIMLには下記内容を記載します。
    「メッセージ」の部分が音声合成されます。任意のメッセージに置き換えてください。

    <?xml version="1.0" encoding="UTF-8"?>
    <Response>
    <Say voice="alice" language="ja-JP" >
    メッセージ
    </Say>
    </Response> 

  4. Save をクリックして登録します。

  5. たった今作成したTwiML Binをクリックしてもう一度内容を表示させると、URLが生成されています。
    このURLはスケッチで使われますので、コピーしておいてください。
  6. Cancelをクリックして閉じます。

ESP_WROOM-02のスケッチ

Mac上のArduino IDE 1.8.1を使いました。

  1. Arduino IDEESP-WROOM-02を開発するための準備をします。
    次のページを参考にしました。
    ESP-WROOM-02開発ボードをArduino IDEで開発する方法
  2. 次の内容のスケッチを作成します。

    #ifdef ESP8266
    extern "C" {
      #include "user_interface.h"
    }
    #endif

    #include <ESP8266WiFi.h>
    #include <WiFiClientSecure.h>

    ADC_MODE(ADC_VCC);

    WiFiClientSecure client;

    // Twilio Call parameters
    const char* asid = "アカウントSID";
    const char* authorization = "Basic ベーシック認証情報";
    const char* twimlUrl = "TwiML BinsのURL";
    const char* to = "通知先電話番号";
    const char* from = "発信元電話番号";

    // Router
    const char* ssid = "ルータのSSID";
    const char* pass = "ルータのパスワード";

    // Twilio REST API endpoint
    const char* twilioHost = "api.twilio.com";
    const char* twilioPath0 = "/2010-04-01/Accounts/";
    const char* twilioPath1 = "/Calls.json";


    void setup() {
      Serial.begin(115200);
      if (wifiConnection()) {
        httpsPost();
      }
    }

    void loop() {

    }

    boolean wifiConnection() {
      WiFi.begin(ssid, pass);
      int count = 0;
      Serial.print("Connecting Wi-Fi");
      while (count < 50) {
        if (WiFi.status() == WL_CONNECTED) {
          Serial.println();
          Serial.println("Connected. IP ADDRESS: " + WiFi.localIP().toString());
          return(true);
        }
        delay(500);
       Serial.print(".");
        count++;
      }
      Serial.println("Timed out.");
      return(false);
    }

    void httpsPost() {
      Serial.println("Connecting to Twilio API endpoint...");
      if (client.connect(twilioHost, 443)) {
        Serial.println("Connected.");
        String data = "Url=" + (String)twimlUrl + "&To=" + (String)to + "&From=" + (String)from;
        String header = "POST " + (String)twilioPath0 + asid +       (String)twilioPath1 + " HTTP/1.1\r\n" +
        "Host: " + (String)twilioHost + "\r\n" +
        "Authorization: " + (String)authorization + "\r\n" +
        "User-Agent: ESP8266/1.0\r\n" +
        "Connection: close\r\n" +
        "Content-Type: application/x-www-form-urlencoded;\r\n" +
        "Content-Length: " + data.length();
        client.println(header);
        client.println();
        client.println(data);
        delay(10);
        Serial.print("Waiting Twilio API response...");
        String response = client.readString();
        int bodypos = response.indexOf("\r\n\r\n") + 4;
        Serial.println();
        Serial.println("RESPONSE: " + response.substring(bodypos));
        return;
      } else {
        Serial.println("ERROR");
        return;
      }
    }

     

動作の様子(デモ動画)

 上記のシステムを少しアレンジしたものの、動作の様子です。

 

とても簡単に、小さなモジュールが電話をかけ音声合成でメッセージを伝えるシステムを作ることができました。

WiFi機能を持つArduino(互換)を使えばインターネットに接続できるので、インターネット・サービスを利用するIoTモジュールを簡単に試作することができますね。