4

COM ポートに関連付けられた Reactive Extensions Observable データ ストリームを使用しており、時間間隔で取得されたそのデータ ストリームからのバッファを表示しています。

これは、バイト データが 25 ミリ秒単位で返される私の基本的な Rx コードです。特定のしきい値に初めて到達したときにバッファの生成を開始し、前のバッファが収集された後にのみ再度実行したいと考えています。

var o = serialData.Buffer(TimeSpan.FromMilliseconds(25))
                  .ObserveOn(SynchronizationContext.Current);
var mySerialObserver = o.Subscribe<IList<byte>>(SubscribeAction());

serialData オブジェクトは、USB COM ポートからのバイト値の連続ストリームの IObservable です。このコードは、Bart De Smet の投稿から改作されました。

Rx で SerialPort パーサーを実装する方法

Rx Buffer(TimeSpan) メソッドを使用して、serialData をサンプリングし、バッファ値をグラフに表示できます ( SubscribeAction メソッド内でDynamicDataDisplayを使用)。

オシロスコープ トリガーのように動作するように機能を拡張したいと考えています。これには、serialData 値が特定のしきい値を超えた時点で Rx バッファー メソッドを呼び出すことも含まれますが、オーバーラップするバッファーは収集しません (これは、オシロ スコープのタイムベース トリガーに似ています)。スイープが完了するまで再びトリガしない)

これがどのように実装されるかについて、誰かが私にいくつかのアイデアを教えてください。

4

1 に答える 1

3

バッファーは、バッファーが閉じるまですべての値のみを解放します。これは、リアルタイム グラフにはあまり役に立ちません。値を重複しないウィンドウに分割する必要があります。これは、特定のトリガーで開始し、スイープ条件が完了すると閉じます。つまり、1 つの完全なスイープ サイクルのウィンドウです。残念ながら、ウィンドウは開始時にまだ値を提供するため、トリガーが起動する前に入ってくるすべての値をスキップする必要があります。

    static IObservable<IObservable<T>> TriggeredSweep<T>(
        this IObservable<T> source,
        Func<T, bool> triggerCondition,
        Func<T, bool> sweepEnd
        )
    {
        source = source.Publish().RefCount();
        return source.Window(() => source.Where(triggerCondition).Sample(source.Where(sweepEnd)))
                     .Select(s => s.SkipWhile(v => !triggerCondition(v)));

    }

これをテストする最良の方法は、これが前提となるオシロスコープ モデルです。

        double period = 1000 / 0.5; //0.5 Hz
        int cycles = 4;             //cycles to display
        int quantization = 100;     //cycles to display            
        int amplitude = 10;         //signal peak            

        int range = quantization * cycles;    //full range 

        //Sine wave generator for n cycles
        //makes tuple of (t, sin(t))
        var source = Observable.Interval(TimeSpan.FromMilliseconds(period / range))
                               .Select(s => s % (range + 1))
                               .Select(s => Tuple.Create(s, amplitude * Math.Sin((double)s / ((double)range / (double)cycles) * 2 * Math.PI)));


        source.TriggeredSweep(
            value => value.Item2 > 5, //Trigger when Signal value > 5
            value => value.Item1 / quantization >= cycles //end sweep when all cycles are done
            )
              .Subscribe(window =>
              {
                  Console.Clear(); //Clear CRO Monitor

                  window.Subscribe(value =>
                  {
                      //Set (x, y)
                      Console.CursorLeft = (int)((double)value.Item1 / range * (Console.WindowWidth - 1));
                      Console.CursorTop = (int)((amplitude - value.Item2) / (2 * amplitude) * (Console.WindowHeight - 1));

                      //draw
                      Console.Write("x");
                  });
              });

        //prevent close
        Console.ReadLine();

出力:

    xxx                   xxxx                   xxx                   xxxx
   xx  x                  x  x                  xx  x                  x  x
   x   x                 xx   x                 x   x                 xx   x
  xx    x                x    x                xx    x                x    x
  x     x               xx     x               x     x               xx     x
  x      x              x      x               x      x              x      x
  x      x              x      x              xx      x              x      x
         x              x       x             x       x              x       x
         x             x        x             x       x             x        x
          x            x        x             x        x            x        x
          x            x        xx           x         x            x        xx
          x           x          x           x         x           x          x
           x          x          x           x          x          x          x
           x          x          x           x          x          x          x           x
           x          x          x          x           x          x          x          x
           x          x           x         x           x          x           x         x
           xx        x            x         x           xx        x            x         x
            x        x            x        x             x        x            x        x
            x        x             x       x             x        x             x       x
            x       x              x       x             x       x              x       x
             x      x              x      xx              x      x              x      xx
             x      x               x     x               x      x               x     x
             x     xx               x     x               x     xx               x     x
              x    x                x    xx                x    x                x    xx
              x   xx                 x   x                 x   xx                 x   x
               x  x                  x  xx                  x  x                  x  xx
               xxxx                   xxx                   xxxx                   xxx
                x                      x                     x                      x

このコードが、Rx を使用した単純な信号処理機能のテストに役立つことを願っています。:)

于 2012-09-28T22:53:23.177 に答える