Prototyping Lab: Recipe 16.3

by kotobuki
♥0 | Line 55 | Modified 2010-05-18 16:39:58 | MIT License
play

ActionScript3 source code

/**
 * Copyright kotobuki ( http://wonderfl.net/user/kotobuki )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/xGyi
 */

package {
  import flash.display.Sprite;
  import flash.events.TimerEvent;
  import flash.text.TextField;
  import flash.utils.Timer;
  
  import funnel.*;

  public class ControlDCSolenoid extends Sprite {
    // ソレノイドに通電する時間
    private static const POWER_ON_DURATION:Number = 40;

    // Arduino
    private var arduino:Arduino;

    // 可変抵抗器に接続したピン
    private var sensorPin:Pin;

    // ソレノイドに接続したピン
    private var solenoidPin:Pin;

    // メトロノーム用のタイマ
    private var metronome:Timer;

    // ソレノイドコントロール用のタイマ
    private var solenoidTimer:Timer;

    // テンポを表示するテキストフィールド
    private var textField:TextField;

    // 前回セットしたテンポ
    private var lastTempo:Number = 0;

    public function ControlDCSolenoid() {
      // ソレノイドに接続したピンのモードを出力にセット
      var config:Configuration = Arduino.FIRMATA;
      config.setDigitalPinMode(9, OUT);
      arduino = new Arduino(config);

      // 出力ピンの自動アップデートを停止
      arduino.autoUpdate = false;

      // 可変抵抗器のピンにスケーラとイベントリスナをセット
      // スケーラでは0から1までの入力を40から208までにスケーリングする
      sensorPin = arduino.analogPin(0);
      sensorPin.addFilter(new Scaler(0, 1, 40, 208));
      sensorPin.addEventListener(PinEvent.CHANGE, onChange);

      // ソレノイドに接続したピン
      solenoidPin = arduino.digitalPin(9);

      // 現在のテンポを表示するテキストフィールドを追加
      textField = new TextField();
      addChild(textField);

      // メトロノーム用のタイマを生成してスタート
      metronome = new Timer(500);
      metronome.addEventListener(TimerEvent.TIMER, onTick);
      metronome.start();

      // ソレノイドをコントロールするタイマを生成してスタート
      solenoidTimer = new Timer(POWER_ON_DURATION, 1);
      solenoidTimer.addEventListener(
        TimerEvent.TIMER_COMPLETE, onTimeOut);
    }

    // 可変抵抗器の値が変化した時に以下を実行
    private function onChange(e:PinEvent):void {
      // 可変抵抗器の値をテンポとして読み取る
      var tempo:Number = sensorPin.value;

      // 前回テンポをセットしてから大きな変化がなければ無視する
      // この処理を行わないと、ノイズなどの影響でセンサの値が
      // 変化する度にタイマの間隔が更新され続け、結果として
      // メトロノームとしての役割を果たさなくなってしまう
      if (Math.abs(tempo - lastTempo) < 2) {
        return;
      }

      // テンポの値からタイマの間隔を求めてセット
      metronome.delay = 1000 / (tempo / 60);

      // 小数点以下1桁までテンポを表示
      textField.text = "Tempo: ";
      textField.appendText(sensorPin.value.toFixed(1));

      // 前回のテンポとして今回の値をセット
      lastTempo = tempo;
    }

    // メトロノームのTIMER_EVENTで以下を実行
    private function onTick(e:TimerEvent):void {
      // ソレノイドに接続したピンの値を1にセット
      solenoidPin.value = 1;
      arduino.update();

      // ソレノイドをコントロールするタイマをスタート
      solenoidTimer.reset();
      solenoidTimer.start();
    }

    // ソレノイドをコントロールするタイマのTIMER_EVENTで以下を実行
    private function onTimeOut(e:TimerEvent):void {
      // ソレノイドに接続したピンの値を0にセット
      solenoidPin.value = 0;
      arduino.update();
    }
  }
}