ESP-WROOM-02(ESP8266)からTwitter投稿


ThingSpeakを経由してESP-WROOM-02からTwitterに投稿します。
日本語は投稿できるかわかりません。文字数のカウントがなんとかなれば大丈夫かも?

##ThingSpeak
[ThingSpeak: Internet Of Things](https://thingspeak.com/)

ThingSpeakは、IoT機器で取得したデータを収集・可視化するサービスです。
"Channel"と呼ばれるページを作成し、そこにPOSTすることで複数のデータをグラフ化することが可能。こんな感じ。
[Channels - Solar Home](https://thingspeak.com/channels/34247)

今回はThingSpeakの機能の一つであるThingTweetを使ってTwitterへ投稿します。
ArduinoなどのマイコンからTwitterに投稿しようとすると色々と面倒ですが、ThingTweetはPOSTを投げるだけでTwitterにStatusを投稿してくれます。

##ThingTweetの準備
手始めにThingSpeakホーム左上の"Sign Up"からアカウントを作成しておきます。
ThingSpeakのマイページに来たら、"Apps"から[ThingTweet](https://thingspeak.com/apps/thingtweets)を開きます。
"Link Twitter Account"から投稿先のTwitterアカウントと連携。連携が完了するとAPI Keyが発行されるはずです。これを後述のソースに突っ込みます。

以下ThingSpeakの [Arduino to ThingTweet Example](https://github.com/iobridge/ThingSpeak-Arduino-Examples/blob/master/Ethernet/Arduino_to_ThingTweet.ino) をベースに解説。これはArduino Ethernet Shield向けなので、WifiClientを使うように少しだけ変更します。

##Wifiに接続
ExampleではArduino Ethernet Shield用のソースになっていますが、今回はWifi経由で接続したいので少々書き換えます。アクセスポイントに接続するまでは[ESP-WROOM-02 + ArduinoOTAでスケッチのWiFi経由アップロード](http://qiita.com/minori24/items/4a3fdc0b037e9d1c09a1)に含まれてたコードと同じです。

setup()はこんな感じ。シリアルモニタ経由で接続状況を覗くことができます。

```cpp
void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  Serial.println("Booting...");
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  while(WiFi.waitForConnectResult() != WL_CONNECTED){
    Serial.println("Connection Failed. Rebooting...");
    delay(5000);
    ESP.restart();  
  }

  Serial.println("Connected to wifi");
}
```

##ThingSpeakへ接続してPOST
WifiClientのconnectメソッドでThingSpeakサーバに接続したら、あとはExampleに書いてある通りにPOST Messageを生成してPOSTするだけ。簡略化のためにソース少し変えてるけど細かいことは気にせずコピペすればヨロシ。
printメソッドで一行ずつ置いていけばいいんですね。


```cpp

void updateTwitterStatus(String tsData)
{
  if (client.connect(thingSpeakAddress, 80))
  { 
    Serial.println("Connected to ThingSpeak.");
    Serial.println("Posted:" + tsData);

    // Create HTTP POST Data
    tsData = "api_key="+thingtweetAPIKey+"&status="+tsData;
            
    client.print("POST /apps/thingtweet/1/statuses/update HTTP/1.1\n");
    client.print("Host: api.thingspeak.com\n");
    client.print("Connection: close\n");
    client.print("Content-Type: application/x-www-form-urlencoded\n");
    client.print("Content-Length: ");
    client.print(tsData.length());
    client.print("\n\n");

    client.print(tsData);
    client.stop();
  }
  else
  {
     Serial.println("Connection failed.");
  }
}
```

全体としてはこんな感じ。
Tweetしたい時にはupdateTwitterStatus()にStringを渡してあげればOK。今回はloop()から10秒ごとに投稿しています。Twitterは重複したTweetを受け付けないため、適当にmillis()で避けています。
コピペするときは、

* SSID
* Password
* API Key

を自分の環境に合わせて変えて下さい。

```cpp
#include <ESP8266WiFi.h>

const char* ssid = "wifissid";
const char* password = "passwd";

char thingSpeakAddress[] = "api.thingspeak.com";
String thingtweetAPIKey = "BLAHBLAHBLAH1234";

WiFiClient client;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  Serial.println("Booting...");
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  while(WiFi.waitForConnectResult() != WL_CONNECTED){
    Serial.println("Connection Failed. Rebooting...");
    delay(5000);
    ESP.restart();  
  }

  Serial.println("Connected to wifi");
}

void loop() {
  // put your main code here, to run repeatedly:
  String twStr = "Tweeting from ESP8266. " + String(millis());
  updateTwitterStatus(twStr);
  delay(10000);
}

void updateTwitterStatus(String tsData)
{
  if (client.connect(thingSpeakAddress, 80))
  { 
    Serial.println("Connected to ThingSpeak.");
    Serial.println("Posting: " + tsData);
    
    // Create HTTP POST Data
    tsData = "api_key="+thingtweetAPIKey+"&status="+tsData;
            
    client.print("POST /apps/thingtweet/1/statuses/update HTTP/1.1\n");
    client.print("Host: api.thingspeak.com\n");
    client.print("Connection: close\n");
    client.print("Content-Type: application/x-www-form-urlencoded\n");
    client.print("Content-Length: ");
    client.print(tsData.length());
    client.print("\n\n");

    client.print(tsData);
    client.stop();
  }
  else
  {
     Serial.println("Connection failed.");
  }
}


```