[perl mac serial] twitterからUSBシリアルでArduinoに信号を送る メモ

  • 投稿日:
  • by
  • カテゴリ:
twitterで任意につけたハッシュタグとRGBの指定で、
USBシリアルで接続されたArduinoのBlinkMの色を変更させてみるメモ

今回は [ff0000] #testhoge1 のようにツイートするとUSBシリアルで接続された
ArduinoのBlinkMの色が変更するプログラムを書いてみます。
twitterのリアルタイムAPIを利用して実装してゆきます。

1. ArduinoとBlinkMの設定
[perl mac serial] Device::SerialPortでArduinoに信号を送る メモ
を参考にArduinoのプログラムを書きます。

今回もBlinkMのサイトのサンプルからBlinkM_funcs.hを利用させていただきます。
初期化で消灯し、色の変化を瞬時に変わる設定を行い、
待受ループでシリアルからRGBの色指定が送信されてくるのを待ちます。
#include "Wire.h"
#include "BlinkM_funcs.h"

#define BLINKM_ARDUINO_POWERED 1

byte blinkm_addr = 0x00;  
char serInStr[30];

void setup()
{
    if( BLINKM_ARDUINO_POWERED ) {
        BlinkM_beginWithPower();
    } else {
        BlinkM_begin();
    }
 
    Serial.begin(19200);
    //Serial.print("start");
   
    // stop seq
    BlinkM_stopScript( blinkm_addr );
    
    // set default color
    BlinkM_setRGB( blinkm_addr, 0xff,0xff,0xff); // white
    
    // fade time
    BlinkM_setFadeSpeed( blinkm_addr, 255);
    
    // change color
    BlinkM_fadeToRGB( blinkm_addr, 0x00,0x00,0x00); //red

}

void loop()
{
	
  int num;
  if( readSerialString() ) {
    //Serial.println(serInStr);
    char* str = serInStr;
    //while( *++str == ' ' );
    num = atoi(str);
    byte a = toHex( str[0],str[1] );
    byte b = toHex( str[2],str[3] );
    byte c = toHex( str[4],str[5] );
    //Serial.print("Fade to r,g,b:");
     BlinkM_fadeToRGB( blinkm_addr, a,b,c);
  }
}

#include 
uint8_t toHex(char hi, char lo)
{
  uint8_t b;
  hi = toupper(hi);
  if( isxdigit(hi) ) {
    if( hi > '9' ) hi -= 7;      // software offset for A-F
    hi -= 0x30;                  // subtract ASCII offset
    b = hi<<4;
    lo = toupper(lo);
    if( isxdigit(lo) ) {
      if( lo > '9' ) lo -= 7;  // software offset for A-F
      lo -= 0x30;              // subtract ASCII offset
      b = b + lo;
      return b;
    } // else error
  }  // else error
  return 0;
}

uint8_t readSerialString()
{
  if(!Serial.available()) {
    return 0;
  }
  delay(10);
  int i = 0;
  while (Serial.available()) {
    serInStr[i] = Serial.read();
    i++;
  }
  serInStr[i] = 0;
  return i;
}

2. twitterからデータを取得する
twitterはStreaming APIが提供されており
リアルタイムにツイートの検索結果を取得できるので、
投稿をトリガーとしてLEDの色変更をリアルタイムに行えます。
参考: Streaming API Documentation

perlでこのAPIを利用するには、
miyagawaさんが作成したAnyEvent::Twitter::Streamが便利です。

APIの仕様書やStreamAPIを理解してなくても、
user_idとpasswordと検索に使いたいfilterの文字列を設定するだけで
お手軽にStreaming APIを利用できます。

[色指定(RGB)] 任意の文字列 ハッシュタグ
形式のツイートが投稿されたとき色を変更したいので
methodをfilterにし、trackにハッシュタグを設定します。
   method   => 'filter',
   track => '#testhoge1',
上記のfilterにマッチする投稿があった場合on_tweetが呼び出されます。
呼び出されたら指定した形式の確認と色指定を
正規表現で確認します。
形式に適合してればusb serial接続されているArduinoに送信します
    $p->write($1) if($tweet->{text} =~ /\[([0-9A-Fa-f]{6})\]/);
[ff0000] blinkm #testhoge1と入力した時は
twitter arduino usb

[00ff00] blinkm green #testhoge1と入力した時は
twitter arduino usb
になりました。
無事に色が変更される事が確認できました。


ソースは以下のようになります。
#!/usr/bin/perl                                                                                                         
use strict;
use Device::SerialPort;
use AnyEvent::Twitter::Stream;

my $done = AnyEvent->condvar;

# Arduino 
my $p = Device::SerialPort->new("/dev/tty.usbserial-A8004JhW");
$p->databits(8);
$p->baudrate(19200);
$p->parity("none");
$p->stopbits(1);
sleep(3); # For Arduino bootup wait.

# Twitter API
my $user = "epic_yoshimax";
my $password = "PASSWORD";
my $keyword = "#testhoge1";

binmode STDOUT, ":utf8";

my $streamer = AnyEvent::Twitter::Stream->new(
   username => $user,
   password => $password,
   method   => 'filter',
   track => $keyword,
    on_tweet => sub {
        my $tweet = shift;
        # [COLOR] #KEYWORD ex) [aa0000] ANY MESSAGE #testhoge1
        $p->write($1) if($tweet->{text} =~ /\[([0-9A-Fa-f]{6})\]/);
        print "$tweet->{user}{screen_name}: $tweet->{text}\n";
    },
    on_error => sub {
        my $error = shift;
        warn "ERROR: $error";
        $done->send;
    },
    on_eof   => sub {
        $done->send;
    },
    );

$done->recv;

参考にさせていただいたサイト
ArduinoとAnyEventを使って,モールス信号でSOS !
Arduino BlinkM I2C通信テスト part1
thingm :: an electronic product studio: BlinkM