2012/11/04

How to Make 『デフコンメーター』

概略



デフコンメータは、Twitterを通じてコントロールできるガジェットです。
ハードウェアとしてはArduinoとEhterShieldを使っています。

Twitterを読んだり書いたりするのにはOAuth認証が必要になりますが、
その認証手続きを肩代わりしてくれる素晴らしいサービス『StewGate』と、
これらをArduino用ライブラリとしてまとめた『Stewitter』を使うことで、
大変手軽にArduinoからTwitterにアクセスすることができます。

arm22さん『何でも作っちゃう、かも』
アクセンス・テクノロジーさん 『StewGate』

ありがとうございます。




動作

このガジェットは、あなたがどのくらい切迫しているかを、
PCから離れている人に対しても明確に伝達するために製作しました。

以下のような動作を行います。

ツイッターから、専用アカウントに対してメッセージを送ると、
5段階のランプがメッセージに応じて変化します。

たとえば、『@defcon_nekotoro defcon4』 とtwitterから送ると
日本のどこかにあるデフコンメータのランプが4になり、
警戒態勢4を室内のメンバーに警告します。

このように、スマートフォンやPCからTwitterを通じて、
ネットにつながったガジェットをコントロールすることができます。



製作


ハードウェアは、単純にArduinoにEtherSheldを重ねて実装し、LEDを5個接続しただけです。





次に、Twitterのアカウントを用意します。次にログインした状態でhttp://stewgate.appspot.com/sg1/ にアクセスして、認証を行います。
これで、トークンが取得できるはずです。

環境ですが、Stewitter のライブラリをArm22さんのブログからダウンロードし、
arduino-1.0.1\libraries 以下に置きます。

あとは、スケッチを書いていきます。


#include <SPI.h>
#include <Ethernet.h>
#include <Stewitter.h>

//Todo : MACアドレスをあなたのボードに記載されているものに変更してください。
byte mac[] = { 
  0x90, 0xA2, 0xDA, 0x0D, 0x53, 0x30 };

// Todo : "YourToken"をあなたのトークンで書き換えてください。
Stewitter twitter("YourToken");

String old_tw_Tick = "0";
String old_tw_Whois =" ";

String tw_Date;
String tw_Tick;
String tw_Whois;
String tw_Massage;

char t_msg[140+1] = "";

#define LED_D1   9
#define LED_D2   8
#define LED_D3   7
#define LED_D4   6
#define LED_D5   5


int defcon_level = 5;

boolean set_post     = false;
boolean report_post   = false;



void setup()
{


  pinMode(LED_D1, OUTPUT);
  pinMode(LED_D2, OUTPUT);
  pinMode(LED_D3, OUTPUT);
  pinMode(LED_D4, OUTPUT);
  pinMode(LED_D5, OUTPUT);
  delay(1000);

  set_led(1); 
  delay(500);
  set_led(2); 
  delay(500);
  set_led(3); 
  delay(500);
  set_led(4); 
  delay(500);
  set_led(5); 
  delay(3000);

  set_led(0); 
  delay(500);


  Ethernet.begin(mac);

  Serial.begin(9600);
  Serial.println("connecting ...");

  set_led(defcon_level);

  set_post     = false;
  report_post   = false;


  // twitterに接続して、 最後のメンション(@yourname の入ったメッセージ)を取得

}

void loop()
{
  check_mention();
  set_led(defcon_level);

  delay(10000);
}


void  set_led(int level)
{
  digitalWrite(LED_D1, LOW);
  digitalWrite(LED_D2, LOW);
  digitalWrite(LED_D3, LOW);
  digitalWrite(LED_D4, LOW);
  digitalWrite(LED_D5, LOW);

  switch (level){
  case 1: 
    digitalWrite(LED_D1, HIGH);
    break;
  case 2: 
    digitalWrite(LED_D2, HIGH);
    break;
  case 3: 
    digitalWrite(LED_D3, HIGH);
    break;
  case 4: 
    digitalWrite(LED_D4, HIGH);
    break;
  case 5: 
    digitalWrite(LED_D5, HIGH);
    break;
  }
}


void check_mention()
{
  int i;
  if (twitter.lastMention()) {
    // 完了を待つ
    int status = twitter.wait();
    // status が 200なら正常に完了
    if (status == 200) {
      // 最後のメンションを表示
      // ex) 20100111082341|874453678|whosaysni|@yourname whats up?
      //Serial.println(twitter.response());

      //str = twitter.response();
      String str =twitter.response();

      //Serial.println(twitter.response());
      //Serial.println(str);

      // find date
      int s_pos = 0;
      int e_pos = 0;

      e_pos = str.indexOf("|",s_pos);
      String tw_Date = str.substring(s_pos,e_pos);
      //Serial.println(tw_Date);
      s_pos = e_pos + 1;

      // find tw_chick
      e_pos = str.indexOf("|",s_pos);
      String tw_Tick = str.substring(s_pos,e_pos);
      //Serial.println(tw_Tick);
      s_pos = e_pos + 1;

      // find whoistw
      e_pos = str.indexOf("|",s_pos);
      String tw_Whois = str.substring(s_pos,e_pos);
      //Serial.println(tw_Whois);
      s_pos = e_pos + 1;

      // find message

      String tw_Massage = str.substring(s_pos);
      //Serial.println(tw_Massage);


      if (!tw_Tick.equals(old_tw_Tick)){

        Serial.println(tw_Date);
        Serial.println(tw_Tick);
        Serial.println(tw_Whois);
        Serial.println(tw_Massage);
        old_tw_Tick = tw_Tick;



        if(tw_Massage.indexOf("?defcon",0) != -1 ){

          //report_post();

          set_post     = false;
          report_post   = true;
        }
        if(tw_Massage.indexOf("defcon1",0) != -1 ){
          Serial.println("DEFCON LEVEL 1" );
          defcon_level = 1;
          //setlevel_post();

          set_post     = true;
          report_post   = false;
        }
        if(tw_Massage.indexOf("defcon2",0) != -1 ){
          Serial.println("DEFCON LEVEL 2" );
          defcon_level = 2;
          //setlevel_post();

          set_post     = true;
          report_post   = false;
        }
        if(tw_Massage.indexOf("defcon3",0) != -1 ){
          Serial.println("DEFCON LEVEL 3" );
          defcon_level = 3;
          //setlevel_post();
          set_post     = true;
          report_post   = false;
        }
        if(tw_Massage.indexOf("defcon4",0) != -1 ){
          Serial.println("DEFCON LEVEL 4" );
          defcon_level = 4;
          //setlevel_post();
          set_post     = true;
          report_post   = false;
        }
        if(tw_Massage.indexOf("defcon5",0) != -1 ){
          Serial.println("DEFCON LEVEL 5" );
          defcon_level = 5;
          //setlevel_post();
          set_post     = true;
          report_post   = false;
        }


        if(set_post){
          set_post = false;
          
          String msg = "@";
          msg += tw_Whois;
          msg += " SET DEFCON LEVEL ";
          msg += defcon_level;
          msg += " / ";
          msg += tw_Date;

          for(i=0;i<msg.length();i++){
            t_msg[i] = msg[i];
          }

          // sprintf(t_msg,"%s",msg);
          Serial.println(t_msg);
          post(); 
        }

      if(report_post){
          report_post = false;
          
          String msg = "@";
          msg += tw_Whois;
          msg += " NOW DEFCON LEVEL ";
          msg += defcon_level;
          msg += " / ";
          msg += tw_Date;

          for(i=0;i<msg.length();i++){
            t_msg[i] = msg[i];
          }

          // sprintf(t_msg,"%s",msg);
          Serial.println(t_msg);
          post(); 
        }
      }
    } 
    else {
      Serial.print("failed : code ");
      Serial.println(status);
    }
  } 
  else {
    Serial.println("connection failed.");
  }
}

void post()
{
  Serial.println("connecting ...");
  if (twitter.post(t_msg)) {
    int status = twitter.wait();
    if (status == 200) {
      Serial.println("OK.");
    } 
    else {
      Serial.print("failed : code ");
      Serial.println(status);
    }
  } 
  else {
    Serial.println("connection failed.");
  }
  delay(1000);
}


やっていることは、

  1. 10秒に1回、自分あてのメンションが来ているかどうか問い合わせ
  2. 以前に来ていたメンションと比較して、違っていたら最新のデータとして更新
  3. メッセージを解析して、状態変更のコマンドだったらLEDを変更
  4. 現在の状態をツイッターに書き込み

です。

現在のところ、誰からのメンションでも反応するようになっています。
必要に応じて、whois を使ってフィルタをかけることができると思います。


最後に
やはり、自作のガジェットがネットに接続できると、大変面白いです。
またStewGateやStewitterのお蔭で、大変簡単に作ることができました。

ぜひ、皆さんも自分のアイデアを形にしてみてください!


0 件のコメント:

コメントを投稿