Prototyping Lab: Recipe 26.3
/**
* Copyright kotobuki ( http://wonderfl.net/user/kotobuki )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/jeGz
*/
package {
import flash.display.Sprite;
import flash.events.Event;
import flash.events.TimerEvent;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
import flash.utils.Timer;
import funnel.*;
import funnel.ui.LED;
[SWF(backgroundColor="0x808080")]
public class WaitUntilStabilized extends Sprite {
// 各状態を表すための定数
private static const UNKNOWN:int = 0;
private static const BRIGHT:int = 1;
private static const DARK:int = 2;
// 各状態を表す文字列
private static const STATE_NAME:Array
= ["UNKNOWN", "BRIGHT", "DARK"];
// 現在の状態と次に移行する状態
private var state:int = UNKNOWN;
private var nextState:int = UNKNOWN;
// Arduino
private var arduino:Arduino;
// 入力波形と出力波形を表示するためのシグナルスコープ
private var scopeForInput:SignalScope;
private var scopeForOutput:SignalScope;
// 光センサに接続したピン
private var sensorPin:Pin;
// LED
private var led:LED;
// センサの状態が変化した一定時間後に状況を更新するためのタイマ
private var timer:Timer;
// 現在の状態と次に移行する状態を表示するためのテキストフィールド
private var textField:TextField;
public function WaitUntilStabilized() {
// LEDに接続したピンのモードを出力にセット
var config:Configuration = Arduino.FIRMATA;
config.setDigitalPinMode(9, OUT);
arduino = new Arduino(config);
// センサに接続したピンにSetPointフィルタとイベントリスナをセット
sensorPin = arduino.analogPin(0);
sensorPin.addFilter(new SetPoint([0.5, 0.2]));
sensorPin.addEventListener(PinEvent.RISING_EDGE,
onRisingEdge);
sensorPin.addEventListener(PinEvent.FALLING_EDGE,
onFallingEdge);
// LEDのインスタンスを生成
led = new LED(arduino.digitalPin(9));
// 入出力を表示するシグナルスコープを生成してセット
scopeForInput = new SignalScope(10, 10, 200,
"Brightness");
addChild(scopeForInput);
scopeForOutput = new SignalScope(10, 65, 200, "LED");
addChild(scopeForOutput);
// テキストフィールドで使用するテキストフォーマットを準備
var format:TextFormat = new TextFormat();
format.font = "Monaco";
format.size = 12;
// テキストフィールドを生成してセット
textField = new TextField();
textField.x = 15;
textField.y = 240;
textField.defaultTextFormat = format;
textField.autoSize = TextFieldAutoSize.LEFT;
addChild(textField);
// タイムアウト用のタイマを生成
timer = new Timer(1000, 1);
timer.addEventListener(TimerEvent.TIMER_COMPLETE,
onTimeout);
// 状態の表示を更新
updateTextDisplay();
// 毎フレームごとに発生するイベントに対してイベントリスナをセット
addEventListener(Event.ENTER_FRAME, onEnterFrame);
}
// 毎フレームごとに以下を実行
private function onEnterFrame(e:Event):void {
// 入出力を表示するスコープを更新
scopeForInput.update(sensorPin);
scopeForOutput.update(led.value);
}
// センサの値が0から1に変化したら
private function onRisingEdge(e:PinEvent):void {
// 次に移行する状態をセットして一定時間後に状態を更新するためのタイマをスタート
nextState = BRIGHT;
timer.reset();
timer.start();
updateTextDisplay();
}
private function onFallingEdge(e:PinEvent):void {
// 次に移行する状態をセットして一定時間後に状態を更新するためのタイマをスタート
nextState = DARK;
timer.reset();
timer.start();
updateTextDisplay();
}
// タイマがタイムアウトしたら
private function onTimeout(e:TimerEvent):void {
// 現在の状態を更新
state = nextState;
// 状態に応じてLEDの状態を更新
if (state == BRIGHT) {
led.off();
} else if (state == DARK) {
led.on();
}
// 状態の表示を更新
updateTextDisplay();
}
// 現在の状態と次に移行する状態を表示
private function updateTextDisplay():void {
textField.text = "State: " + STATE_NAME[state];
textField.appendText(", Next state: "
+ STATE_NAME[nextState]);
}
}
}