Processingでリアルタイムグラフ表示

 いろいろなセンサー値(シリアル通信などの取得データ)などを取り込みながら、リアルタイムのグラフプロットをProcessingで表示してみました。

 

▼グラフ画面▼

 Processingでsin、cosカーブを計算してグラフ化してるサンプル画です。グラフは右から左にプロットしていき、領域いっぱいになったら左にスクロールしていきます。サンプルソースでは3本のグラフを同時に出力。またÝ軸のスケールは値に合わせて可変できるように作成してます。(写真ではいまいち。最後に動画UPしておきました)

▼全体ソース▼

float a, b, c;
int k;
float w = 2.0;

graphMonitor testGraph;

void setup() {
  size(1920, 1080, P3D);
  frameRate(100);
  smooth();
  testGraph = new graphMonitor("graphTitle", 100, 50, 1000, 400);
}

void draw() {
  background(250);
  testGraph.graphDraw(a, b, c);

  a = sin(radians(k));
  b = cos(radians(k) * 10);
  c = sin(radians(k)) * w;
  k++;
}

class graphMonitor {
    String TITLE;
    int X_POSITION, Y_POSITION;
    int X_LENGTH, Y_LENGTH;
    float [] y1, y2, y3;
    float maxRange;
    graphMonitor(String _TITLE, int _X_POSITION, int _Y_POSITION, int _X_LENGTH, int _Y_LENGTH) {
      TITLE = _TITLE;
      X_POSITION = _X_POSITION;
      Y_POSITION = _Y_POSITION;
      X_LENGTH   = _X_LENGTH;
      Y_LENGTH   = _Y_LENGTH;
      y1 = new float[X_LENGTH];
      y2 = new float[X_LENGTH];
      y3 = new float[X_LENGTH];
      for (int i = 0; i < X_LENGTH; i++) {
        y1[i] = 0;
        y2[i] = 0;
        y3[i] = 0;
      }
    }

    void graphDraw(float _y1, float _y2, float _y3) {
      y1[X_LENGTH - 1] = _y1;
      y2[X_LENGTH - 1] = _y2;
      y3[X_LENGTH - 1] = _y3;
      for (int i = 0; i < X_LENGTH - 1; i++) {
        y1[i] = y1[i + 1];
        y2[i] = y2[i + 1];
        y3[i] = y3[i + 1];
      }
      maxRange = 1;
      for (int i = 0; i < X_LENGTH - 1; i++) {
        maxRange = (abs(y1[i]) > maxRange ? abs(y1[i]) : maxRange);
        maxRange = (abs(y2[i]) > maxRange ? abs(y2[i]) : maxRange);
        maxRange = (abs(y3[i]) > maxRange ? abs(y3[i]) : maxRange);
      }

      pushMatrix();

      translate(X_POSITION, Y_POSITION);
      fill(240);
      stroke(130);
      strokeWeight(1);
      rect(0, 0, X_LENGTH, Y_LENGTH);
      line(0, Y_LENGTH / 2, X_LENGTH, Y_LENGTH / 2);

      textSize(25);
      fill(60);
      textAlign(LEFT, BOTTOM);
      text(TITLE, 20, -5);
      textSize(22);
      textAlign(RIGHT);
      text(0, -5, Y_LENGTH / 2 + 7);
      text(nf(maxRange, 0, 1), -5, 18);
      text(nf(-1 * maxRange, 0, 1), -5, Y_LENGTH);

      translate(0, Y_LENGTH / 2);
      scale(1, -1);
      strokeWeight(1);
      for (int i = 0; i < X_LENGTH - 1; i++) {
        stroke(255, 0, 0);
        line(i, y1[i] * (Y_LENGTH / 2) / maxRange, i + 1, y1[i + 1] * (Y_LENGTH / 2) / maxRange);
        stroke(255, 0, 255);
        line(i, y2[i] * (Y_LENGTH / 2) / maxRange, i + 1, y2[i + 1] * (Y_LENGTH / 2) / maxRange);
        stroke(0, 0, 0);
        line(i, y3[i] * (Y_LENGTH / 2) / maxRange, i + 1, y3[i + 1] * (Y_LENGTH / 2) / maxRange);
      }
      popMatrix();
    }
}

void keyPressed() {
  if (keyCode == UP) {
    w = w + 0.1;
  }
  if (keyCode == DOWN) {
    w = w - 0.1;
  }
}

 汎用持たせられるようにグラフ化部分はクラス化してます。またサンプルソースではÝ軸のスケール可変確認のためキーボードの上下ボタンでプロット値を変更できるようにしてます。

 

 簡単ですが解説。

graphMonitor(String _TITLE, int _X_POSITION, int _Y_POSITION, int _X_LENGTH, int _Y_LENGTH)

 インスタンスの引数は順番にグラフタイトル、グラフ位置x座標、y座標、グラフのx軸長さ、y軸長さを引数。

<スポンサーリンク>

 

void graphDraw(float _y1, float _y2, float _y3)

 メソッドでは3本グラフのグラフの値を引数にしてます。1本しか描画しないときは「0」を入れておけばO.K。

 

▼実際の動画▼

使い回しの動画ですみません。見難いですが、画面左隅のほうでグラフ描画してます。動画ではArduinoから6軸センサー値の情報を受け取りリアルタイムで描画。

 

ArduinoIDEのシリアルプロッタでは物足りないときに使用してます。

 

<スポンサーリンク>



この投稿へのコメント

コメントはありません。

コメントを残す

メールアドレスが公開されることはありません。

この投稿へのトラックバック

トラックバックはありません。

トラックバック URL