itsukichang

フロントエンドが得意なエンジニア.ダーツと旅行とギターが好き

Flashを使用したフィジカルコンピューティング



先日悩んでたこと解消できましたー.
その原因と解決法を含めてFunnelとArduinoの合わせ技について紹介.

Introduction

Flashにはシリアル通信機能がないため、直接ArduinoやGainerといったハードウェアを制御することはができません.
そこで,プロキシサーバーを使って通信を行います.
今回はそのプロキシサーバーのひとつ,「Funnel」を紹介します.

Funnelというツール

Funnelはオープンソースプロジェクトの,フィジカルコンピューティングのためのツールキットです.

ソフトウェアである,FunnelServer.
ライブラリとして,ActionScript3.0,Processing,Rubyに対応.
そして,ハードウェアとしてGainerやArduinoなど.
これらのもので構成されたツールがFunnelです.

未踏ソフトウェア事業として開発され,今もバージョンアップが行われています.
詳しくは公式サイトで.http://funnel.cc/

Arduinoとの通信.

さて,ここからはハードウェアとしてArduinoを使用した,Funnelの使い方を紹介します.

Arduino

ArduinoにはFunnelServerを使用するためのプログラムを転送します.

使用するのは「Firmata」というライブラリです.
ArduinoIDEのバージョンが0012(Arduino0012)以上なら,IDEのSketchBookバー内にあるLibraryの中に,Firmataフォルダがあるはずです.


バージョンが古い場合は,アップデートするか,こちらからダウンロードして,ライブラリフォルダに入れておきましょう.Download - Firmata


ライブラリが準備できたら,Standard_FirmataをArduinoに送信します.
これで,Arduino側の準備は完了です.

FunnelServer

次に,FunnelServerをArduino用に設定します.
これは公式サイトのほうに詳しく載ってるので省略.
http://funnel.cc/Main/GettingStarted


Macの場合だと,ポート設定を自動で行ってくれるので楽です.

ArduinoをPCにつないで,FunnelServerを立ち上げて,以下のような画面になればOK!


ついでにライブラリも一緒にダウンロードしておきましょう.
あとで使います.
Google Code Archive - Long-term storage for Google Code Project Hosting.
Funnel_0XXというファイルです.(2009年10月時点での最新バージョンはfunnel_009)

Flash

さて,ArduinoとFunnelの設定が完了したら,いよいよ次はFlashと連携します.
詳しいAPIリファレンス等は公式にありますが,ここではHelloWorld的なプログラムで全体の流れを紹介します.

公式リファレンス:Adobe Flex 2 Language Reference

Tutorial

ここでは,Flash上で色を選択し,その色に対応した発光ダイオードが光るプログラムを組んでみましょう.


大まかな流れは以下の通りです.

ArduinoをPCに接続する.
・FunnelServerを立ち上げ,接続を確認する.
ArduinoにStandard_Firmataを送信する.
・swfファイルを実行する.


このようになります.
FunnelServer立ち上げる前にswfファイルを動かすと,不具合が発生し,失敗するので,もう一度はじめからやりなおしてください.


Make Project

それではArduinoと連携してフィジカルコンピューティングを行う為の,プロジェクトを作成しましょう!

AS3プロジェクトをいつもの用に作成します.

ここで,Funnel用のAPIを使用する為にライブラリをインポートする必要があります.

プロジェクト(flaファイル)が入っているフォルダにActionScript3.0用のFunnelライブラリを入れておく必要があります.

先ほどダウンロードした,Funnel009の中の,actionscript3 -> src にあるfunnelフォルダをコピー&プロジェクトフォルダにペーストします.


これで,準備はできました.さっそくコーディングしていきましょう.

Let's Cording!

ひとまず,コード全体を提示します.

package {
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import funnel.*; //funnelライブラリをimport

	public class funnelTest extends Sprite {
		private var aio:Arduino; 
		private var hoge1:Sprite;
		private var hoge2:Sprite;
		private var hoge3:Sprite;
		
		public function funnelTest() {
			var config:Configuration = Arduino.FIRMATA; //設定用のConfiguration型のインスタンスを生成
			
			config.setDigitalPinMode(11, DOUT); //11pinをdigitalOutに設定
			config.setDigitalPinMode(12, DOUT); //12pinをdigitalOutに設定
			config.setDigitalPinMode(13, DOUT); //13pinをdigitalOutに設定
			
			aio = new Arduino(config); //Arduino型のインスタンスを生成
			hoge1 = new Sprite();
			hoge2 = new Sprite();
			hoge3 = new Sprite();
			var led1:Pin = aio.digitalPin(13); //それぞれのPin型の変数にPinを割り当てる
			var led2:Pin = aio.digitalPin(12);
			var led3:Pin = aio.digitalPin(11);
			
			hoge1.graphics.beginFill(0xFF0000);
			hoge1.graphics.drawCircle(50,100,20);
			addChild(hoge1);
			
			hoge2.graphics.beginFill(0xF2F10D);
			hoge2.graphics.drawCircle(150,100,20);
			addChild(hoge2);
			
			hoge3.graphics.beginFill(0x0000FF);
			hoge3.graphics.drawCircle(250,100,20);
			addChild(hoge3);
			
			hoge1.addEventListener(MouseEvent.CLICK,function(e:MouseEvent):void { //Spriteがクリックされた時のイベント
				if(led1.value)	led1.value = 0.0;
				else			led1.value = 1.0;
			});
			
			hoge2.addEventListener(MouseEvent.CLICK,function(e:MouseEvent):void {
				if(led2.value)	led2.value = 0.0;
				else			led2.value = 1.0;
			});

			hoge3.addEventListener(MouseEvent.CLICK,function(e:MouseEvent):void {
				if(led3.value)	led3.value = 0.0;
				else			led3.value = 1.0;
			});

		}
	}
}

いっぱい無駄とかあると思うんで,ぜひぜひ指摘してください>< 

さてさて,大体雰囲気が分かると思いますが,噛み砕いて説明していきましょう.


・まず,Arduino型のインスタンスを生成します.

private var aio:Arduino; 
aio = new Arduino(config); //Arduino型のインスタンスを生成

・生成する際,引数として,通信を開始する段階で決定している設定するクラス,コンフィギュレーションインスタンスを渡します.(上記コードのconfigがインスタンス)

//コンフィギュレーションクラスのインスタンス生成
var config:Configuration = Arduino.FIRMATA; //設定用のConfiguration型のインスタンスを生成 初期化は使用するライブラリ,FIRMATAを設定.


・Configuration型のインスタンスの主に使用するメソッドはsetDigitalPinModeです.
ArduinoのそれぞれのPinのモードの初期化を行います.

config.setDigitalPinMode(11, DOUT); //11pinをdigitalOutに設定
config.setDigitalPinMode(12, DOUT); //12pinをdigitalOutに設定
config.setDigitalPinMode(13, DOUT); //13pinをdigitalOutに設定

setDigitalPinModeの第一引数は,設定するPinの番号,第二引数はPinのモード

PinMode
・AIN ・・・アナログインプット
・AOUT ・・・アナログアウトプット
・DIN ・・・ディジタルインプット
・DOUT ・・・ディジタルアウトプット


最後に,それぞれのPin型の変数(インスタンス?)にPinを割り当てます.

var led1:Pin = aio.digitalPin(13);
var led2:Pin = aio.digitalPin(12);
var led3:Pin = aio.digitalPin(11);

あとは適当にイベントを追加して,制御します.


今回のチュートリアルで使用したPinModeはすべてDigitalOutPutなので,出力値は 0 or 1となります.

出力値や入力値はPin型インスタンスvalueプロパティで設定できます.

if(led3.value)	led3.value = 0.0; //一応引数がNumber型
else			led3.value = 1.0;

これで一応,チュートリアル的なプログラムは完成です!

実行画面はこんな感じ. クリックした色に対応したLEDが光ります.

実際に動いてる様子


ArduinoFlashを用いたフィジカルコンピューティングの第一歩を踏み出せましたね!

ActionScript使いな人ならリファレンス読めば大抵の事は理解できると思うので,どんどん素敵な物を作っていきましょう!!




そのうち,ほかの色んなクラスやメソッド使ったサンプルをいくつか投下します.

Bug...

色々なソフトウェアが組み合わさって動作している環境なので,ちょっとしたことで不具合が生じる事もあるかもしれません.

僕も変なバグで数日間悩んでました><


解決方法として,とりあえず手っ取り早いのが,すべての関連ソフトウェア,ライブラリを最新バージョンにすることですかね.

大体これでなんとかなると思います.

To public!

面白い物ができたらどんどんアウトプットしていきましょう!

Web上でFlashが作れるwonderflというサイトで,フィジカルコンピューティングとのコラボ企画があります.
回路図や動画もコードと一緒に公開できるので,積極的に参加していきましょうねv
http://physical.wonderfl.net/index.html


最後に

今回使用した回路とか実際動いてる様子をupしたかったのですが,愛用のデジカメが他界しまして用意できませんでした><;

近日中になんとかしてupしまーす.