質問するログイン新規登録

回答編集履歴

1

現象多分解明

2019/12/07 11:00

投稿

thkana
thkana

スコア7769

answer CHANGED
@@ -1,2 +1,96 @@
1
1
  ポート番号が間違っていないと天地神明に誓って言うならば、
2
- 例えばシリアルモニターを開きっぱなしにして、そっちにデバイスを取られているとか。
2
+ 例えばシリアルモニターを開きっぱなしにして、そっちにデバイスを取られているとか。
3
+
4
+ ---
5
+ 追記。
6
+ 真面目にトレースしてみてわかりました。
7
+ > ArduinoにはStandardFilmataが読み込まれています。
8
+ これが間違いというか(綴りも違うけど)。読み込まれている、とはどういう具体的にどういう事態を指していますか?
9
+
10
+ 事象としては、ArduinoでFirmataのFirm Wareが動いていないから、FirmataのProcessing側が接続出来ない、ということのようです。
11
+ 距離センサを持っていないので、Arduino側にはシリアルで見て同様のデータを吐き出すテストプログラム、
12
+ ```
13
+ void setup() {
14
+ Serial.begin(9600);
15
+ }
16
+ float dist = 100;
17
+ void loop() {
18
+ float d1 = random(-10, 11);
19
+ float d2 = random(1, 4);
20
+ dist += d1 / d2;
21
+ dist = constrain(dist, 4, 400);
22
+ Serial.print(dist);
23
+ Serial.print(" cm");
24
+ delay(500);
25
+ }
26
+ ```
27
+ を書き、私はWindows環境なのでシリアルポート名は適宜変更して質問のProcessingプログラムを走らせると質問と同様の症状が再現しました。
28
+ そこで、Arduino側に、Arduino IDEの[ファイル]-[スケッチ例]-[Firmata]-[StandardFirmata]を書き込んだ状態で同じProcessingのプログラムを起動すると、とりあえずエラーは出ません(期待するデータのやり取りはないので画は動きませんが)。
29
+
30
+ Firmataでなにかやりたいのなら、Arduino側もFirmataのライブラリを適切に使ったプログラムにする必要があります。Firmataで距離センサを制御できるのか、私は知りません。
31
+
32
+ 逆に、ArduinoがFirmataを使わないのなら、Processing側もFirmataを使わずにプログラムを作る必要があります。(これが後の質問でPortのエラーが出ないという状況に繋がります)。
33
+ ざっと書いてみましたが、こんな感じになるでしょうか。readstringUntilとか使うともう少し手軽に書けるかもしれませんが、若干応答性は変わるかも。
34
+ ```Processing
35
+ import processing.serial.*;
36
+
37
+ final int SMOOTH=10;//移動平均の数
38
+ final float MAXDATA=400;//画面右端のデータ値
39
+
40
+ Serial port;
41
+ boolean requestDraw;
42
+ String recieved="";//受信文字バッファ
43
+ float distance;//取得距離
44
+ float history[]=new float[SMOOTH];//移動平均データバッファ
45
+ int histPtr;//移動平均格納ポインタ
46
+
47
+ void setup() {
48
+ size(1200, 640);
49
+ String portName="COM5";//適宜状況に合わせて
50
+ port = new Serial(this, portName, 9600);
51
+ if (port==null) {//一応開けなかったときのチェック
52
+ println("Exit");
53
+ exit();
54
+ }
55
+ stroke(50, 255, 255);
56
+ }
57
+
58
+ void draw() {
59
+ if (requestDraw) {
60
+ background(0);
61
+ float x=distance*(width/MAXDATA);
62
+ line(x, 0, x, height);
63
+ requestDraw=false;
64
+ }
65
+ }
66
+
67
+ void serialEvent(Serial p) {
68
+ char c=(char)p.read();//この関数は1文字だけ受信するもの
69
+ if (c!='\n') {
70
+ //通常データならバッファに追加
71
+ recieved+=c;
72
+ } else {
73
+ //行末だったら1データ単位受信処理
74
+ recieved=recieved.trim(); //'\r'除去
75
+
76
+ //計算用バッファにデータ追加
77
+ try {//通信絡みの変換失敗エラーを捕捉
78
+ history[histPtr++]=Float.parseFloat(recieved);
79
+ histPtr%=history.length;
80
+
81
+ //移動平均を求める
82
+ float sum=0;
83
+ for (float dist : history) {
84
+ sum+=dist;
85
+ }
86
+ distance=sum/history.length;
87
+ requestDraw=true; //データ準備出来たので描画指示
88
+ }
89
+ catch(java.lang.NumberFormatException ex) {
90
+ }
91
+ finally {
92
+ recieved="";//バッファはクリアする
93
+ }
94
+ }
95
+ }
96
+ ```