回答編集履歴

1

現象多分解明

2019/12/07 11:00

投稿

thkana
thkana

スコア7639

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