質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.44%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Arduino

Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。

Processing

Processingは、オープンソースプロジェクトによるCGのためのプログラミング言語です。Javaをベースにしており、グラフィック機能に特化しています。イメージの生成やアニメーションなど、視覚的なフィードバックを簡単に得ることが可能です。

Q&A

解決済

2回答

1251閲覧

Processingでのグラフが表示されない

h.n

総合スコア6

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Arduino

Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。

Processing

Processingは、オープンソースプロジェクトによるCGのためのプログラミング言語です。Javaをベースにしており、グラフィック機能に特化しています。イメージの生成やアニメーションなど、視覚的なフィードバックを簡単に得ることが可能です。

0グッド

0クリップ

投稿2023/06/02 16:07

編集2023/06/02 16:41

実現したいこと

Arduino側でのデータをprocessingに渡し、そのデータをプロットし折れ線グラフを書こうとしているのですがうまくいきません。

前提

processingで折れ線グラフを表示したいのですが、実行をしても画面が真っ暗でなにも出てきません。
どこに問題があるんでしょうか・・・。
初学者なもので、教えていただけたら幸いです。
参考にしたサイト:https://okasho-engineer.com/processing-real-time-graph/

該当のソースコード

processing

1import processing.serial.*; 2 3Serial port; 4 5int[] PlotData = new int[300]; 6int data; //リアルタイムデータ 7 8void setup() { 9 //fullScreen(); // windowのサイズを画面いっぱいにする 10 size(500,500); 11 smooth(); 12 background(0); // 背景を黒にする 13 frameRate(10); // frame rateを5fpsに設定 14 port = new Serial(this,"COM5",115200); 15 port.clear(); 16 for(int i=0; i<300; i++) // plotするデータの初期化 17 { 18 PlotData[i] = 0; 19 } 20} 21 22void draw() { 23 background(0); 24 TimeHistory(-width/2, -height/2+height/2/5, "ECG[deg]", data); // 時間履歴の表示 25} 26 27void TimeHistory(int positionX, int positionY, String name, int data) 28{ 29 // 引数説明 // 30 // positionX, positionYはグラフを表示する枠の左上の点 31 // nameはグラフの縦軸のラベル名 32 // dataはリアルタイムのデータ 33 // 枠線の描画 34 float Width = width/3*0.85; // 枠の幅 35 float Height = height/2*0.6; // 枠の高さ 36 pushMatrix(); // 座標系の保存 37 noFill(); // 塗りつぶしなし 38 stroke(100); // 枠線の色 39 strokeWeight(3); // 枠線の幅 40 translate(positionX, positionY); // 枠の左上の点を指定 41 rect(0, 0, Width, Height); // 枠の描画 42 // メモリ線の描画 43 strokeWeight(1); // メモリ線の幅 44 for (int i=1; i<6; i++) // メモリ線の描画 45 { 46 line(0, Height/6*i, Width, Height/6*i); // 縦軸 47 line(Width/6*i, 0, Width/6*i, Height); // 横軸 48 } 49 // メモリ値の描画 50 stroke(0); 51 fill(100); // メモリ値の文字色 52 // 縦軸のメモリ値 53 textSize(Height*0.06); // 文字の大きさ 54 textAlign(RIGHT); // 文字の座標指定位置 55 int j = -300; // 縦軸の目盛りの最低値 56 for (int i=6; i>=0;i--) // メモリ戦の描画 57 { 58 text(j, -width/3*0.02, Height/6*i); // 文字の描画 59 j = j + 100; // 縦軸の目盛りの更新 60 } 61 pushMatrix(); // 座標系の保存 62 rotate(radians(-90)); // 座標軸を90度回転 63 textAlign(CENTER); // 文字の座標指定位置 64 text(name, -Height/2, -width/3*0.1); // 縦軸ラベルの描画 65 popMatrix(); // 保存した座標系の出力 66 // 横軸のメモリ値 67 textAlign(CENTER); // 文字の座標指定位置 68 text("now", Width, Height*1.08); // 文字の描画 69 j = 0; // 横軸の目盛りの最低値 70 for(int i=0; i<=5; i++) 71 { 72 text(j, Width/6*i, Height*1.08); // 文字の描画 73 j = j + 5; // 横軸の目盛りの更新 74 } 75 text("time [s]", Width/2, Height*1.2); // 横軸ラベルの描画 76 // グラフの描画 77 pushMatrix(); 78 translate(0, Height/2); // 座標の原点を縦軸の中心に移動 79 PlotData[299] = data; // データの更新 80 for(int i=0; i<300-1; i++) // plotするデータ処理 81 { 82 PlotData[i] = PlotData[i+1]; 83 } 84 for(int i=0; i<300-1; i++) 85 { 86 stroke(255, 0, 0); // 線の色 87 line(Width/300*i, Height/6*PlotData[i]/30, Width/300*(i+1), Height/6*PlotData[i+1]/30); 88 } 89 popMatrix(); 90 stroke(0); // 線の色を戻す 91 popMatrix(); // 保存した座標系の出力 92} 93 94void serialEvent(Serial port){ 95 if(port.available() >=3){ 96 if(port.read() == 'H'){ 97 int high = port.read(); 98 int low = port.read(); 99 int data = high*256 + low; 100 101 for(int i = 0; i < 300-1;i++){ 102 PlotData[i] = PlotData[i+1]; 103 } 104 PlotData[299] = data; 105 } 106 } 107} 108

Arduino

1//test01 2 3const int ECG_sensor = 0; 4 5void setup() { 6 Serial.begin(115200); 7} 8 9void loop() { 10 int value = analogRead(0); 11 Serial.write('H'); 12 Serial.write(highByte(value)); 13 Serial.write(lowByte(value)); 14 delay(100); 15} 16 17

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

jimbe

2023/06/02 16:19

まず通信出来ているのかを確認してみては如何でしょうか。
h.n

2023/06/02 16:42

すいません、シリアル通信に関してコードを修正しました。 ただ、これでも動きません
jimbe

2023/06/02 17:05

通信は出来ていたのでしょうか。
h.n

2023/06/02 17:07

シリアル通信はできていました
jimbe

2023/06/02 17:37

データが受信出来て PlotData に値が溜っていっているのであれば、 arduino 側と processing の受信関数は問題無いことになります。 次は TimeHistory 関数が呼ばれているか、また、固定的にいつでも表示されるはずの目盛り等が書かれているかを確認する必要があるでしょう。 また TimeHistory の第4引数の data とか 79~83行目とかは serialEvent でやっているのですから削除するべきではないでしょうか。
h.n

2023/06/02 17:55

固定的に表示される目盛り、縦軸横軸のラベルは表示されていません。
jimbe

2023/06/02 19:31 編集

draw 関数そして TimeHistory 関数はちゃんと呼ばれているでしょうか。また、例えば幅高さや各座標の値は正しいかを確かめたり、0,0から100,100への線を一本書くだけをしてみるとか、確認・試せることはあると思います。
guest

回答2

0

あちこちから拾ったプログラム片をその動作を理解しないまま貼り合わせても動くプログラムにはならない典型、という気がしますがどうでしょうか。

まず。

そのデータをプロットし

では、そのプロットの横軸はどうなることを期待していますか? frameRateをいじっているところをみると、一定時間で流れて行くことを期待しているようでもありますが、しかしシリアルのイベントにフックしているデータの取得方法から考えると(時間に関係なく)送られてきたデータの個数でグラフを描くことを期待しているようにも見えなくはありません。どちらも100ms毎だから同期するという期待をしているのなら、「二つの時計が合っている保証なんてない」です。Arduino (UNO)のクロック精度は純正品で0.5%だったはず。PC側の時計精度が完璧だったとしても、200データ送受を繰り返したら1個分の周期ズレを起こしている可能性がある、ということです。

それと、「変数のスコープ」について復習してください。Processing側6行目で宣言した変数dataは、値は設定されることがなく(つまり0のまま)24行目で描画関数のコールに使われています。
その変数dataと、79行目に登場するdata、104行目のdataはそれぞれ互いに「赤の他人」です。
それぞれのdataの内容は一体どうあるべきなのか、ちゃんと説明できますか?

ついでに言えば、79行目と104行目はなにかそっくりに見えますが、それぞれの処理の意味は明確に説明できますか?(言ってしまえばこの二つが両方あるというのは異常だと思います)

もちろん、既に指摘があるように、描画のための座標系がどうなっているのかもちゃんと理解することが必要です。
私だったら、TimeHistory()を呼び出す前にtranslate()で座標系をシフトするかなぁ...

現時点でどういう入力に対してどういうグラフが描ければ満足なのかが不明なのでサンプルは書きません。

投稿2023/06/03 02:09

thkana

総合スコア7667

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

Webページのコードが間違っていることはよくあります(転記の際に書き損じるとか・そもそも動作確認してないとか^^;
あまり信用しすぎないことです。

processingで折れ線グラフを表示したいのですが、実行をしても画面が真っ暗でなにも出てきません。

// 引数説明 //
// positionX, positionYはグラフを表示する枠の左上の点

と書いてあるにもかかわらず、

TimeHistory(-width/2, -height/2+height/2/5,

positionXpositionYがマイナスになっています。これでは画面外に描画しています。
参考サイトがどういうつもりだったのかはわかりませんが、プラスの数値を適当に入れればいいでしょう。

あと参考サイトでは、Y軸が90-90の固定です(その上なぜか反転してる)
回答ではめんどくさいので、dataのほうを加工しました^^;

シリアル通信はできているということなので、ダミーデータで検証しました(動作確認済^^

Processing

1import processing.serial .*; 2 3Serial port; 4int[] PlotData = new int[300]; 5int data; 6 7void setup() { 8 size(500, 500); 9 smooth(); 10 background(0); 11 frameRate(10); 12 13 //port = new Serial(this, "COM5", 115200); 14 //port.clear(); 15 16 // ゼロ初期化ならいらない(javaでは「new int[300]」の時点ですべてゼロ) 17 //for (int i = 0; i < 300; i++) { 18 // PlotData[i] = 0; 19 //} 20} 21 22void draw() { 23 background(0); 24 25 // ダミーデータ(300 ~ -300) 26 data = int(noise(frameCount * 0.05) * 600 - 300); 27 println(data); 28 29 // グラフ描画が90 ~ -90固定なので、90 ~ -90に圧縮 30 data = int(map(data, 300, -300, 90, -90)); 31 32 // XYオフセットを適当に入れる 33 TimeHistory(50, 50, "ECG[deg]", -data); // なぜかY軸が逆なので 【マイナス】data 34} 35 36void TimeHistory(int positionX, int positionY, String name, int data) { 37 float Width = width / 3 * 0.85; 38 float Height = height / 2 * 0.6; 39 40 pushMatrix(); 41 noFill(); 42 stroke(100); 43 strokeWeight(3); 44 translate(positionX, positionY); 45 rect(0, 0, Width, Height); 46 47 strokeWeight(1); 48 for (int i = 1; i < 6; i++) { 49 line(0, Height / 6 * i, Width, Height / 6 * i); 50 line(Width / 6 * i, 0, Width / 6 * i, Height); 51 } 52 53 stroke(0); 54 fill(100); 55 56 textSize(Height * 0.06); 57 textAlign(RIGHT); 58 int j = -300; 59 for (int i = 6; i >= 0; i--) { 60 text(j, -width / 3 * 0.02, Height / 6 * i); 61 j += 100; 62 } 63 64 pushMatrix(); 65 rotate(radians(-90)); 66 textAlign(CENTER); 67 text(name, -Height / 2, -width / 3 * 0.1); 68 popMatrix(); 69 70 textAlign(CENTER); 71 text("now", Width, Height * 1.08); 72 j = -30; 73 for (int i = 0; i <= 5; i++) { 74 text(j, Width / 6 * i, Height * 1.08); 75 j += 5; 76 } 77 text("time [s]", Width / 2, Height * 1.2); 78 79 pushMatrix(); 80 translate(0, Height / 2); 81 82 PlotData[299] = data; 83 //for (int i = 0; i < 300 - 1; i++) { 84 // PlotData[i] = PlotData[i + 1]; 85 //} 86 // ↑↓同じ意味(まとめて移動したほうが早いはず) 87 arrayCopy(PlotData, 1, PlotData, 0, PlotData.length - 1); 88 89 for (int i = 0; i < 300 - 1; i++) { 90 stroke(255, 0, 0); 91 line(Width / 300 * i, Height / 6 * PlotData[i] / 30, Width / 300 * (i + 1), Height / 6 * PlotData[i + 1] / 30); 92 } 93 popMatrix(); 94 popMatrix(); 95} 96 97void serialEvent(Serial port) { 98 if (port.available() >= 3) { 99 if (port.read() == 'H') { 100 int high = port.read(); 101 int low = port.read(); 102 103 // ローカル変数じゃダメ 104 //int data = high * 256 + low; 105 data = high * 256 + low; 106 107 // TimeHistory内でやってる 108 //for (int i = 0; i < 300 - 1; i++) { 109 // PlotData[i] = PlotData[i + 1]; 110 //} 111 //PlotData[299] = data; 112 } 113 } 114}

アプリ画像


調べていたらこんなものがありました(デバイスがないので動作確認はしてません)
chillibasket/processing-grapher: Terminal and graphing program for analysis and recording of data from serial devices

投稿2023/06/02 21:31

編集2023/06/02 22:04
TN8001

総合スコア9441

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.44%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問