Prototyping Lab: Recipe 23.4

by kotobuki
♥0 | Line 58 | Modified 2010-04-17 15:11:30 | 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/sCz5
 */

package {
  import flash.display.Sprite;
  import flash.events.Event;

  import funnel.*;

  public class Smooth extends Sprite {
    // バッファ長
    private static const BUFFER_LENGTH:int = 5;

    // バッファの中央の値のインデックス
    private static const INDEX_OF_MIDDLE:int = 2;

    // Arduino
    private var arduino:Arduino;

    // センサを接続したピン
    private var sensorPin:Pin;

    // センサから読み取った値を保持するバッファ
    private var buffer:Array;

    // ソート用のバッファ
    private var sortBuffer:Array;

    // 比較用のシグナルスコープ
    private var scopes:Array;

    public function Smooth() {
      // Arduinoのインスタンスを生成してsensorPinをセット
      arduino = new Arduino(Arduino.FIRMATA);
      sensorPin = arduino.analogPin(0);

      // センサから読み取った値を保持するバッファとソート用のバッファを初期化
      buffer = new Array(BUFFER_LENGTH);
      sortBuffer = new Array(buffer.length);
      for (var i:int = 0; i < buffer.length; i++) {
        buffer[i] = 0;
        sortBuffer[i] = 0;
      }

      // 比較用に3つのシグナルスコープを生成
      scopes = new Array(3);
      scopes[0] = new SignalScope(10, 10, 200, "Raw");
      addChild(scopes[0]);
      scopes[1] = new SignalScope(10, 70, 200, "Mean");
      addChild(scopes[1]);
      scopes[2] = new SignalScope(10, 130, 200, "Median");
      addChild(scopes[2]);

      // 毎フレームごとに発生するイベントのイベントリスナをセット
      addEventListener(Event.ENTER_FRAME, onEnterFrame);
    }

    // 毎フレームごとに以下を実行
    private function onEnterFrame(e:Event):void {
      // センサの値を読み取る
      var value:Number = sensorPin.value;

      // バッファに読み取った値を追加して一番古い物を削除
      buffer.unshift(value);
      buffer.pop();

      // MeanフィルタとMedianフィルタをそれぞれ実行
      var smoothedByMeanFilter:Number 
          = smoothByMeanFilter();
      var smoothedByMedianFilter:Number 
          = smoothByMedianFilter();

      // 元の値、Meanフィルタをかけた値、Medianフィルタをかけた値を表示
      scopes[0].update(value);
      scopes[1].update(smoothedByMeanFilter);
      scopes[2].update(smoothedByMedianFilter);
    }

    // Meanフィルタ
    private function smoothByMeanFilter():Number {
      // バッファの値の合計を集計するための変数
      var sum:Number = 0;

      // バッファの値の合計を集計
      for (var i:int = 0; i < buffer.length; i++) {
        sum += buffer[i];
      }

      // 平均をフィルタの出力結果として返す
      return (sum / buffer.length);
    }

    // Medianフィルタ
    private function smoothByMedianFilter():Number {
      // ソートに使用するバッファにデータをコピー
      for (var i:int = 0; i < sortBuffer.length; i++) {
        sortBuffer[i] = buffer[i];
      }

      // ソート
      sortBuffer.sort();

      // ソート結果の中央の値を出力結果として返す
      return sortBuffer[INDEX_OF_MIDDLE];
    }
  }
}