2015年2月7日土曜日

ArduinoとESP8266でTwitterに投稿してみた。

Raspberry Pi鯖から室温とかをTwitterでつぶやきつつ素数なんて数えていたけど、Arduinoでもできるんじゃね?
ということでまずは、ArduinoからESP8266モジュールを使ってWifi経由でTweetできるか試してみた。
ESP8266は例によってシリアルポートで通信しないといけないのでArduino Leonardo互換基板でやってみることに。やはりシリアルポート2ポート有るのは便利ー。
Leonardoじゃない場合はSoft serialを使うという手も。

次にどうやってTwitterからつぶやくかだけど、ArduinoでTwitterのAPIを直接叩いて認証したりするのは結構大変なんじゃないかな…
というわけでStewGate Uを経由してみることに。StewGate UのAPIならPOSTが使えれば一発だし。

登録はTwitterアカウントでログオンして承認するだけなので簡単!
登録するとトークンがもらえます。

試しにシリアルモニタで送信した文字列をつぶやくプログラムを書いてみた。
日本語は非対応だけどこのプログラムの文字数のカウント部分の問題で、ちゃんとカウントできればつぶやけることは確認済み。結局素数Botは数字しか変化しないので問題なさそう。

とりあえずのテストなのでエラー処理とか全くしてないし一応ソースコード貼っときます。(めっちゃ汚いけど…
あらかじめESP8266をルータやアクセスポイントに接続して置く必要あり。
シリアル通信部分はhiramine.comさんから拝借しました。


#define READBUFFERSIZE (32)
char g_szReadBuffer[READBUFFERSIZE] = "";
int  g_iIndexChar = 0;

char addr[] = "\"stewgate-u.appspot.com\",80";
char token[] = "ここにStewGateUのトークンを入力。";

void setup() {
  Serial.begin(9600);
  Serial1.begin(9600);
}

void loop() {
char szLineString[READBUFFERSIZE];
 if( !ReadLineString( g_szReadBuffer, READBUFFERSIZE, g_iIndexChar,
       szLineString, READBUFFERSIZE ) )
 {
  return;
 }

int datalen = 122 + String(szLineString).length();
int contlen = 40 + String(szLineString).length(); 

Serial1.print("AT+CIPSTART=\"TCP\",");
Serial1.print(addr);
Serial1.print("\r\n");
delay(500);
Serial1.print("AT+CIPSEND=");
Serial1.print(datalen);
Serial1.print("\r\n");

Serial1.print("POST /api/post/ HTTP/1.0\r\n"
"Host: stewgate-u.appspot.com\r\n"
"Content-Length: ");
Serial1.print(contlen);
Serial1.print("\r\n"
"\r\n"
"_t=");
Serial1.print(token);
Serial1.print("&msg=");
Serial1.print(szLineString);
Serial1.print("\r\n\r\n");
    delay(10000);
    
}

int ReadLineString( char szReadBuffer[], const int ciReadBufferSize, int& riIndexChar,
     char szLineString[], const int ciLineStringSize )
{
 while( 1 )
 {
  char c = Serial.read();
  if( -1 == c )
  {
   break;
  }
  if( '\r' == c  )
  {
   szReadBuffer[riIndexChar] = '\0';
   strncpy( szLineString, szReadBuffer, ciLineStringSize - 1 );
   szLineString[ciLineStringSize - 1] = '\0';
   riIndexChar = 0;
   return 1;
  }
  else if( '\n' == c )
  {
   ;
  }
  else
  {
   if( (ciReadBufferSize - 1) > riIndexChar )
   {
    szReadBuffer[riIndexChar] = c;
    riIndexChar++;
   }
  }
 }

 return 0;
}

0 件のコメント:

コメントを投稿