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

回答編集履歴

1

追記

2021/11/10 13:33

投稿

thkana
thkana

スコア7735

answer CHANGED
@@ -15,4 +15,118 @@
15
15
  の結果が-256になるあたりからみて、
16
16
  `P1 = (inBuf[1]<<8)+(inBuf[2]&0xff);;`
17
17
  はまともに変換できないケースがでてくるでしょう。なぜだめかは「符号拡張」という言葉について調べてみるとよろしいかと思います。
18
- (ところでなぜセミコロンが2つ?)
18
+ (ところでなぜセミコロンが2つ?)
19
+
20
+ ---
21
+ 若干意地になって...「本当に質問のままのArduinoプログラム」でもデータを切り出して取得するProcessing側プログラム
22
+ ```Processing
23
+ import processing.serial.*;
24
+
25
+ final int SENSOR_NUM = 8; //センサー数 Arduino側と同じであること
26
+ final char START_TRIG = 's'; //送信リクエスト文字 Arduino側と同じであること
27
+ final char START_CHAR = 's'; //データヘッダ Arduino側と同じであること
28
+ final char END_CHAR = 'e'; //データ終端 Arduino側と同じであること
29
+
30
+ final int REQ_PERIOD = 50; //データリクエスト周期
31
+
32
+ //この通信方法では浮動小数点数データは転送できない..,
33
+ //こともないけれど普通やらないのでデータを取る変数はint
34
+ int[] P = new int[SENSOR_NUM];
35
+ int serialTimer;
36
+ Serial myPort;
37
+
38
+ int count;
39
+ byte[] inBuf = new byte[SENSOR_NUM*2+2];
40
+
41
+ void setup() {
42
+ size(500, 500);
43
+ myPort=new Serial(this, "COM13", 57600);//こちらの環境にあわせて
44
+ delay(3000); //Arduinoの起動を待つ
45
+ serialTimer=millis();
46
+ myPort.write(START_TRIG); //リクエスト送信
47
+ }
48
+
49
+ void draw() {
50
+ if (millis()-serialTimer > REQ_PERIOD) { //送信リクエスト周期?
51
+ if (count==0) { //前回データ受信がなかった
52
+ println("NO DATA.");
53
+ } else if (count<SENSOR_NUM*2+2) {
54
+ println("TIMEOUT."); //リクエスト周期内に通信が完了しなかった
55
+ } else if (count>SENSOR_NUM*2+2) {
56
+ println("OVERRUN."); //余計な文字受信があった
57
+ }
58
+ myPort.write(START_TRIG); //リクエスト送信
59
+ serialTimer=millis();//時刻記録
60
+ count=0;//データ蓄積開始
61
+ }
62
+ while (myPort.available()!=0) { //受信済文字がある間ループ
63
+ int data=myPort.read();
64
+ if (count<SENSOR_NUM*2+2) {
65
+ //規定文字数未受信なのでデータを溜める
66
+ inBuf[count]=(byte)data;
67
+ } else {
68
+ //既に受信完了しているので表示だけ
69
+ print((char)data);
70
+ }
71
+ count++;
72
+ if (count==SENSOR_NUM*2+2) {//規定のバイト数を受信した
73
+ if (inBuf[0]!=START_CHAR || inBuf[SENSOR_NUM*2+1]!=END_CHAR) {
74
+ //正しいフォーマットでなかったので一文字捨ててやり直し
75
+ print((char)inBuf[0]);//捨てられる一文字を表示しておく
76
+ for (int i=0; i<SENSOR_NUM*2+1; i++) {
77
+ inBuf[i]=inBuf[i+1];
78
+ }
79
+ count--;
80
+ } else {
81
+ //正しいフォーマットだったので値取り込み
82
+ for (int i=0; i<SENSOR_NUM; i++) {
83
+ P[i]=((inBuf[i*2+1]<<8)&0xff00) + (inBuf[i*2+2]&0xff);
84
+ }
85
+ count++;
86
+ }
87
+ }
88
+ }
89
+
90
+ background(0);
91
+ fill(240);
92
+ textSize(24);
93
+ for (int i=0; i<SENSOR_NUM; i++) {
94
+ text(P[i], 50, 50+30*i);
95
+ }
96
+ }
97
+ ```
98
+ そして、できればこのくらいに書きたいな、というArduino側プログラム
99
+ ```Arduino
100
+ const int SENSOR_NUM = 8; //センサー数 Processing側と同じであること
101
+ const char START_TRIG = 's'; //送信リクエスト文字 Processing側と同じであること
102
+ const char START_CHAR ='s'; //データヘッダ Processing側と同じであること
103
+ const char END_CHAR ='e'; //データ終端 Processing側と同じであること
104
+
105
+ const int INTERNAL_AD = 6; //内蔵AD数 INTERNAL_AD<=SENSOR_NUMであること
106
+ const int SENSOR_PIN[INTERNAL_AD] = {A0, A1, A2, A3, A4, A5}; // 内蔵ADピンアサイン
107
+
108
+ void setup() {
109
+ Serial.begin(57600);
110
+ }
111
+
112
+ void loop() {
113
+ uint16_t ads[SENSOR_NUM];
114
+ //データ取得 (内蔵ADC)
115
+ for ( int i = 0; i < INTERNAL_AD; i++) {
116
+ ads[i] = analogRead(SENSOR_PIN[i]);
117
+ }
118
+ // 内蔵AD以外のデータ。質問に情報がないので乱数
119
+ for( int i=INTERNAL_AD;i<SENSOR_NUM; i++){
120
+ ads[i]=random(1024);
121
+ }
122
+
123
+ if (Serial.read() == START_TRIG) {//送信リクエストを受信したら
124
+ Serial.print(START_CHAR);//開始文字送信
125
+ for(int i=0;i<SENSOR_NUM;i++){//各データ送信
126
+ Serial.write(ads[i]/256);
127
+ Serial.write(ads[i]);
128
+ }
129
+ Serial.print(END_CHAR);//終端文字送信
130
+ }
131
+ }
132
+ ```