500円以下で作成する行き先表（ESP8266、SG90で作成）

#はじめに
●サーボモータ(SG90)を購入したので行き先表をESP8266開発ボードで作成してみました。
![pict-IMG_20190210_012015.jpg](https://qiita-image-store.s3.amazonaws.com/0/222582/3a0e8adf-35d2-aa46-079b-e12867ad6009.jpeg)

IFTTTのButton widgetでfirebaseに"1"から"5"の文字を書き込むAppletsを５つ作成します。
スマホのウィジェットでIFTTTを指定し、行き先のボタンを５個設置します。
ボタンを押すとfirebaseにテキストが書き込まれ、ESP8266がテキストを読み込み、指定角度にモータを回転させ、行き先を表示します。
"1":行き先１：角度0
"2":行き先２：角度45
"3":行き先３：角度90
"4":行き先４：角度135
"5":行き先５：角度180

#使用したもの
ESP8266開発ボード(３００円)、サーボモータSG90(１２０円)
SG90のPWMをESP8266のGPIO4に接続する
SG90のVCCをESP8266のVin(5V)に接続する
SG90のGNDをESP8266のGNDに接続する

#環境
●WindowsにArduinoIDEをインストールする
●ArduinoIDEにESP8266のライブラリとFirebaseArduinoのライブラリをインクルードする
●ArduinoIDEを使用し、下記のプログラムをESP8266に書き込む
●firebaseのDatabaseはplace-wordにしています
●iftttでButton widget(this)でfirebaseにテキスト(例"1")をPUTする(that)ようにAppletsを作成する
●スマホ画面のウィジェットで作成したAppletsをスマホ画面に配置する

#スケッチ
●firebaseとWiFi設定は自分のKeyに置き換えてください

    #include <ESP8266WiFi.h>
    #include <FirebaseArduino.h>
    #include<Servo.h>
    
    #define FIREBASE_HOST "XXXXX.firebaseio.com"
    #define FIREBASE_AUTH "XXXXXXXXXXXXXXXXXXXXXX"
    #define WIFI_SSID "XXXXXXXXXXXXXXX"
    #define WIFI_PASSWORD "XXXXXXXXXXXXX"
      
    Servo servo1; //任意のサーボモータークラスを用意。
    void setup() {
      servo1.attach(4); //4番ピンをサーボモーターの出力ピンとして設定
      Serial.begin(115200);
      WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
      while (WiFi.status() != WL_CONNECTED) {
        delay(500);
      }
      Firebase.begin(FIREBASE_HOST, FIREBASE_AUTH);
      Firebase.stream("/place/word");
    }
    
    void loop() {
      if (Firebase.failed()) {
        Serial.println("streaming error");
        Serial.println(Firebase.error());
        ESP.reset();
      }
      if (Firebase.available()) {
        Serial.print("2\r\n");
        FirebaseObject event = Firebase.readEvent();
        Serial.print("event\r\n");
        if (Firebase.success()) {
          Serial.print("success\r\n");
          String eventType = event.getString("type");
          eventType.toLowerCase();
    
          if (eventType == "put") {
            String data = event.getString("data");
            Serial.print("data: ");
            Serial.println(data);
            if(data=="1"){
               servo1.write(0);
               Firebase.setString("place/word", "");
            } else if(Firebase.getString("place/word")=="2"){
               servo1.write(45);
               Firebase.setString("place/word", "");
            } else if(Firebase.getString("place/word")=="3"){
               servo1.write(90);
               Firebase.setString("place/word", "");
            } else if(Firebase.getString("place/word")=="4"){
               servo1.write(135);
               Firebase.setString("place/word", "");
            } else if(Firebase.getString("place/word")=="5"){
               servo1.write(180);
               Firebase.setString("place/word", "");
            }
          }
        }
      }
    }
#プログラム(行き先をGooglehomeで話すプログラムをラズパイに作成しています)
    var firebase = require('firebase');
    var iconv = require('iconv-lite');
    
    //firebase config
    var config = {
        apiKey: "XXXXXXXXXXXXXXXXXXXXXXXXX",
        authDomain: "XXXXXXXX.firebaseapp.com",
        databaseURL: "https://XXXXXXXX.firebaseio.com",
        projectId: "XXXXXXXX",
        storageBucket: "XXXXXXXX.appspot.com",
        messagingSenderId: "XXXXXXXXXXX"
    };
    
    firebase.initializeApp(config);
    
    //jsonからvalueに一致する値取得
    const getJsonData = (value, json) => {
      for (var word in json)  if (value == word) return json[word]
      return json["default"]
    }
    
    //database更新時
    const path = "/place"
    const key = "word"
    const db = firebase.database()
    db.ref(path).on("value", function(changedSnapshot) {
    //値取得
    let value = changedSnapshot.child(key).val()
    if (!value) return
    
    if(value === "1") {
      command = 'curl -X POST -d "text=お父さんは行き先１にいます" http://192.168.1.82:8080/google-home-notifier'
    } else if(value === "2") {
      command = 'curl -X POST -d "text=お父さんは行き先２にいます" http://192.168.1.82:8080/google-home-notifier'
    } else if(value === "3") {
      command = 'curl -X POST -d "text=お父さんは行き先３にいます" http://192.168.1.82:8080/google-home-notifier'
    } else if(value === "4") {
      command = 'curl -X POST -d "text=お父さんは行き先４にいます" http://192.168.1.82:8080/google-home-notifier'
    } else if(value === "5") {
      command = 'curl -X POST -d "text=お父さんは行き先５にいます" http://192.168.1.82:8080/google-home-notifier'
    }
    var exec = require('child_process').exec;
    exec(command, {maxBuffer: 1000*1024}, function(error, stdout, stderr) {
      if (error !== null) {
        console.log('Exec error: ' + error);
      }
    });
    })

#まとめ
●IFTTTのthisはButton widgetでなく、GPS指定(You enter an area)に変更することも可能です
●Firebase.failedの場合、ESP.resetを入れるとfirebaseを読めるようになりました
●最初、１秒周期でfirebaseデータを読み込んでいましたが、１時間ももたずにメモリ不足で動作しなくなりました。Firebase.streamを使用すると解決しました。
【追記】2019-4-8
最近、動作しなくなったので、調査したところ、firebaseのfingerprintが変更になったそうです。
下記の箇所を修正してください。
「C：¥Users¥ユーザー名¥Documents¥Arduino¥libraries¥firebase-arduino-master¥src¥FirebaseHttpClient.h」に移動します。
static const char kFirebaseFingerprint [] = 
"E2 34 53 7A 1E D9 7D B8 C5 02 36 0D B2 77 9E 5E 0F 32 71 17";
【追記】2019-8-16
fingerprintは不定期で変更されるので、最新データを確認お願いします。