Tunnel(Serial To IEEE1888)
修订版 | c52108a770b4d01e8474236a1a20ba0263af8975 (tree) |
---|---|
时间 | 2015-07-10 15:01:30 |
作者 | MirrgieRiana Kurilab |
Commiter | MirrgieRiana Kurilab |
tunnel_SerialReader -> AcsSerialReader
@@ -0,0 +1,73 @@ | ||
1 | +#ifndef INCLUDE_AcsSerialReader_h | |
2 | +#define INCLUDE_AcsSerialReader_h | |
3 | + | |
4 | +const static int ACS_SERIAL_READER_ARGUMENTS_INT_MAX_LENGTH = 100; | |
5 | +const static int ACS_SERIAL_READER_ARGUMENTS_DOUBLE_MAX_LENGTH = 10; | |
6 | +const static int ACS_SERIAL_READER_ARGUMENTS_STRING_MAX_LENGTH = 4; | |
7 | +const static int ACS_SERIAL_READER_ARGUMENT_STRING_MAX_LENGTH = 100; | |
8 | +const static int ACS_SERIAL_READER_BUFFER_MAX_LENGTH = 100; | |
9 | + | |
10 | +// シリアルからの命令 | |
11 | +// "I21\n" int型引数をpush | |
12 | +// "D3.14\n" double型引数をpush | |
13 | +// "Sstring123%&\n" 99文字までの改行を含まない文字列型引数をpush | |
14 | +// "C\n" 引数の全破棄 | |
15 | +// "M\n" コマンドの実行(コマンド名のために文字列引数が1個必要) | |
16 | +// | |
17 | +// readOneOperationをすると、Serialから一行分の命令を読み込んで実行する。 | |
18 | +// 命令の区切り文字は\nのほかに;も可能 | |
19 | +class AcsSerialReader { | |
20 | +public: | |
21 | + | |
22 | + int argumentsInt[ACS_SERIAL_READER_ARGUMENTS_INT_MAX_LENGTH]; | |
23 | + int argumentsIntLength; | |
24 | + | |
25 | + double argumentsDouble[ACS_SERIAL_READER_ARGUMENTS_DOUBLE_MAX_LENGTH]; | |
26 | + int argumentsDoubleLength; | |
27 | + | |
28 | + char argumentsString | |
29 | + [ACS_SERIAL_READER_ARGUMENTS_STRING_MAX_LENGTH] | |
30 | + [ACS_SERIAL_READER_ARGUMENT_STRING_MAX_LENGTH]; | |
31 | + int argumentsStringLength; | |
32 | + | |
33 | + AcsSerialReader(); | |
34 | + | |
35 | + void reset(); | |
36 | + | |
37 | + boolean readOneOperation(); | |
38 | + | |
39 | +private: | |
40 | + | |
41 | + int lastShownAcceptedChars; | |
42 | + | |
43 | + int acceptedChars; | |
44 | + | |
45 | + int read(); | |
46 | + | |
47 | + void showAcceptedChars(); | |
48 | + | |
49 | + boolean pushInt(int value); | |
50 | + | |
51 | + boolean pushDouble(double value); | |
52 | + | |
53 | + // 文字列長が長すぎる場合、失敗してfalseが返る。 | |
54 | + boolean pushString(char* value); | |
55 | + | |
56 | + // シリアルから読みだした文字のバッファ | |
57 | + char buffer[ACS_SERIAL_READER_BUFFER_MAX_LENGTH]; | |
58 | + int bufferLength; | |
59 | + | |
60 | + // 指定キャラクタまで読み込んでbufferに入れる | |
61 | + // @return 正常終了してbufferが更新された場合にtrue | |
62 | + // @param containStopper 指定キャラクタをバッファに含めるかどうか | |
63 | + boolean readUntil(char stopper1, char stopper2, char escape); | |
64 | + | |
65 | +}; | |
66 | + | |
67 | +// メソッド名は最初の文字列引数。 | |
68 | +void AcsSerialReader_invokeCommand(AcsSerialReader* acsSerialReader); | |
69 | + | |
70 | +#endif | |
71 | + | |
72 | + | |
73 | + |
@@ -0,0 +1,246 @@ | ||
1 | +#include "AcsSerialReader.h" | |
2 | + | |
3 | +AcsSerialReader::AcsSerialReader() | |
4 | +{ | |
5 | + reset(); | |
6 | +} | |
7 | + | |
8 | +void AcsSerialReader::reset() | |
9 | +{ | |
10 | + argumentsIntLength = 0; | |
11 | + argumentsDoubleLength = 0; | |
12 | + argumentsStringLength = 0; | |
13 | + bufferLength = 0; | |
14 | + lastShownAcceptedChars = 0; | |
15 | + acceptedChars = 0; | |
16 | +} | |
17 | + | |
18 | +int AcsSerialReader::read() | |
19 | +{ | |
20 | + if (!Serial.available()) { | |
21 | + showAcceptedChars(); | |
22 | + while (!Serial.available()); | |
23 | + } | |
24 | + | |
25 | + if (acceptedChars > lastShownAcceptedChars + 20) showAcceptedChars(); | |
26 | + | |
27 | + acceptedChars++; | |
28 | + return Serial.read(); | |
29 | +} | |
30 | + | |
31 | +void AcsSerialReader::showAcceptedChars() | |
32 | +{ | |
33 | + Serial.print("C:"); | |
34 | + Serial.println(acceptedChars); | |
35 | + lastShownAcceptedChars = acceptedChars; | |
36 | +} | |
37 | + | |
38 | +boolean AcsSerialReader::pushInt(int value) | |
39 | +{ | |
40 | + if (argumentsIntLength >= ACS_SERIAL_READER_ARGUMENTS_INT_MAX_LENGTH) return false; | |
41 | + argumentsInt[argumentsIntLength] = value; | |
42 | + argumentsIntLength++; | |
43 | +} | |
44 | + | |
45 | +boolean AcsSerialReader::pushDouble(double value) | |
46 | +{ | |
47 | + if (argumentsDoubleLength >= ACS_SERIAL_READER_ARGUMENTS_DOUBLE_MAX_LENGTH) return false; | |
48 | + argumentsDouble[argumentsDoubleLength] = value; | |
49 | + argumentsDoubleLength++; | |
50 | +} | |
51 | + | |
52 | +boolean AcsSerialReader::pushString(char* value) | |
53 | +{ | |
54 | + if (argumentsStringLength >= ACS_SERIAL_READER_ARGUMENTS_STRING_MAX_LENGTH) return false; | |
55 | + if (strlen(value) >= ACS_SERIAL_READER_ARGUMENT_STRING_MAX_LENGTH) return false; | |
56 | + strcpy(argumentsString[argumentsStringLength], value); | |
57 | + argumentsStringLength++; | |
58 | +} | |
59 | + | |
60 | +boolean AcsSerialReader::readUntil( | |
61 | +char stopper1, | |
62 | +char stopper2, | |
63 | +char escape) | |
64 | +{ | |
65 | + | |
66 | + // 既に受け取った'\0'を含めない文字列長=これから代入すべき添え字。 | |
67 | + // 実際のバッファサイズも超える。 | |
68 | + bufferLength = 0; | |
69 | + | |
70 | + // この文字はエスケープ済みである | |
71 | + boolean escaped = false; | |
72 | + | |
73 | + while (true) { | |
74 | + int c = read(); | |
75 | + | |
76 | + // 謎エラー | |
77 | + if (c == -1) { | |
78 | + Serial.println("Warning:readUntil -1"); | |
79 | + continue; | |
80 | + } | |
81 | + | |
82 | + // ストッパーやエスケープ文字が着たか否か | |
83 | + boolean isStopper = (c == stopper1) || (c == stopper2); | |
84 | + boolean isEscape = c == escape; | |
85 | + | |
86 | + // この文字が特殊文字として処理されないべきか否か | |
87 | + boolean appendable; | |
88 | + | |
89 | + // この文字自体がエスケープ済みなら、 | |
90 | + if (escaped) { | |
91 | + escaped = false; | |
92 | + | |
93 | + // 特殊文字ではない。 | |
94 | + appendable = true; | |
95 | + } | |
96 | + else { | |
97 | + // エスケープ済みではなくて、 | |
98 | + | |
99 | + // ストッパーやエスケープ文字なら、 | |
100 | + if (isStopper || isEscape) { | |
101 | + // 特殊文字として処理されるべき。 | |
102 | + appendable = false; | |
103 | + } | |
104 | + else { | |
105 | + // そうでなければ通常文字として処理されるべき。 | |
106 | + appendable = true; | |
107 | + } | |
108 | + } | |
109 | + | |
110 | + /////////////////////////////////////////// メイン処理 | |
111 | + | |
112 | + // この文字が通常文字として処理されるべきならば、 | |
113 | + if (appendable) { | |
114 | + | |
115 | + // バッファがあふれていなければ、 | |
116 | + if (bufferLength <= ACS_SERIAL_READER_BUFFER_MAX_LENGTH - 1 - 1) { | |
117 | + // バッファに追加。 | |
118 | + buffer[bufferLength] = c; | |
119 | + } | |
120 | + | |
121 | + // どちらにしろ既に受け取った文字列長を増やす。 | |
122 | + bufferLength++; | |
123 | + continue; | |
124 | + } | |
125 | + | |
126 | + // エスケープ文字が来た場合、 | |
127 | + if (isEscape) { | |
128 | + | |
129 | + // 次の文字をエスケープ済みに指定 | |
130 | + escaped = true; | |
131 | + | |
132 | + continue; | |
133 | + } | |
134 | + | |
135 | + // 区切り文字が来た場合、 | |
136 | + if (isStopper) { | |
137 | + // バッファがあふれていなければ、 | |
138 | + if (bufferLength <= ACS_SERIAL_READER_BUFFER_MAX_LENGTH - 1) { | |
139 | + // 終端文字を追加。 | |
140 | + buffer[bufferLength] = '\0'; | |
141 | + } | |
142 | + else { | |
143 | + // あふれていても追加。 | |
144 | + buffer[ACS_SERIAL_READER_BUFFER_MAX_LENGTH - 1] = '\0'; | |
145 | + } | |
146 | + | |
147 | + break; | |
148 | + } | |
149 | + | |
150 | + } | |
151 | + | |
152 | + // bufferLength: 文字列長 | |
153 | + if (bufferLength <= ACS_SERIAL_READER_BUFFER_MAX_LENGTH - 1) { | |
154 | + return true; | |
155 | + } | |
156 | + else { | |
157 | + Serial.print("Warning:line length over: "); | |
158 | + Serial.print(bufferLength); | |
159 | + Serial.println(""); | |
160 | + return false; | |
161 | + } | |
162 | +} | |
163 | + | |
164 | +boolean AcsSerialReader::readOneOperation() | |
165 | +{ | |
166 | + if (!Serial.available()) return false; | |
167 | + | |
168 | + int c = read(); | |
169 | + if (c == -1) { | |
170 | + Serial.println("Warning:readOneOperation -1"); | |
171 | + return false; | |
172 | + } | |
173 | + else if (c == 'I') { | |
174 | + if (readUntil('\n', ';', '\\')) { | |
175 | + int value = atoi(buffer); | |
176 | + pushInt(value); | |
177 | + Serial.print("Message:(int) "); | |
178 | + Serial.print(value); | |
179 | + Serial.println(""); | |
180 | + return true; | |
181 | + } else { | |
182 | + Serial.println("Warning:readUntil == false"); | |
183 | + } | |
184 | + } | |
185 | + else if (c == 'D') { | |
186 | + if (readUntil('\n', ';', '\\')) { | |
187 | + double value = atof(buffer); | |
188 | + pushDouble(value); | |
189 | + Serial.print("Message:(double) "); | |
190 | + Serial.print(value); | |
191 | + Serial.println(""); | |
192 | + return true; | |
193 | + } else { | |
194 | + Serial.println("Warning:readUntil == false"); | |
195 | + } | |
196 | + } | |
197 | + else if (c == 'S') { | |
198 | + if (readUntil('\n', ';', '\\')) { | |
199 | + pushString(buffer); | |
200 | + Serial.print("Message:(string) "); | |
201 | + Serial.print(buffer); | |
202 | + Serial.println(""); | |
203 | + return true; | |
204 | + } else { | |
205 | + Serial.println("Warning:readUntil == false"); | |
206 | + } | |
207 | + } | |
208 | + else if (c == 'M') { | |
209 | + readUntil('\n', ';', '\\'); | |
210 | + AcsSerialReader_invokeCommand(this); | |
211 | + return true; | |
212 | + } | |
213 | + else if (c == 'C') { | |
214 | + readUntil('\n', ';', '\\'); | |
215 | + argumentsIntLength = 0; | |
216 | + argumentsDoubleLength = 0; | |
217 | + argumentsStringLength = 0; | |
218 | + Serial.println("Message:clear operator"); | |
219 | + return true; | |
220 | + } | |
221 | + else if (c == 'R') { | |
222 | + readUntil('\n', ';', '\\'); | |
223 | + reset(); | |
224 | + Serial.println("Message:reset SerialReader"); | |
225 | + return true; | |
226 | + } | |
227 | + else if (c == '\n') { | |
228 | + Serial.println("Message:blank operator"); | |
229 | + return true; | |
230 | + } | |
231 | + else if (c == ';') { | |
232 | + Serial.println("Message:blank operator"); | |
233 | + return true; | |
234 | + } | |
235 | + else { | |
236 | + readUntil('\n', ';', '\\'); | |
237 | + Serial.print("Warning:unknown operator: "); | |
238 | + Serial.print((char) c); | |
239 | + Serial.println(""); | |
240 | + return false; | |
241 | + } | |
242 | + | |
243 | + return false; | |
244 | +} | |
245 | + | |
246 | + |
@@ -2,7 +2,7 @@ | ||
2 | 2 | #define INCLUDED_TunnelSerialToIEEE1888_H |
3 | 3 | |
4 | 4 | #include <FIAPUploadAgent.h> |
5 | -#include "tunnel_SerialReader.h" | |
5 | +#include "AcsSerialReader.h" | |
6 | 6 | |
7 | 7 | // ------------------------- グローバル変数 ------------------------- |
8 | 8 |
@@ -16,7 +16,7 @@ | ||
16 | 16 | |
17 | 17 | // ------------------------- シリアル通信からの引数関連 ------------------------- |
18 | 18 | |
19 | -extern tunnel::SerialReader serialReader; | |
19 | +extern AcsSerialReader acsSerialReader; | |
20 | 20 | |
21 | 21 | // ------------------------- メッセージ関連 ------------------------- |
22 | 22 |
@@ -9,7 +9,7 @@ | ||
9 | 9 | |
10 | 10 | #include "TunnelSerialToIEEE1888.h" |
11 | 11 | #include "core.h" |
12 | -#include "tunnel_SerialReader.h" | |
12 | +#include "AcsSerialReader.h" | |
13 | 13 | |
14 | 14 | ///////////////////////// 初期化定数 ///////////////////////// |
15 | 15 |
@@ -53,7 +53,7 @@ | ||
53 | 53 | boolean isRunnable = true; // 初期化が正常終了した場合にtrue |
54 | 54 | int waitMs = 500; |
55 | 55 | |
56 | -tunnel::SerialReader serialReader; | |
56 | +AcsSerialReader acsSerialReader; | |
57 | 57 | |
58 | 58 | boolean delayCanceled = false; |
59 | 59 |
@@ -71,7 +71,7 @@ | ||
71 | 71 | error("initializing error!"); |
72 | 72 | } |
73 | 73 | else { |
74 | - if (serialReader.readOneOperation()) { | |
74 | + if (acsSerialReader.readOneOperation()) { | |
75 | 75 | delayCanceled = true; |
76 | 76 | } |
77 | 77 | tick(); |
@@ -1,7 +1,7 @@ | ||
1 | 1 | #ifndef INCLUDED_core_H |
2 | 2 | #define INCLUDED_core_H |
3 | 3 | |
4 | -#include "tunnel_SerialReader.h" | |
4 | +#include "AcsSerialReader.h" | |
5 | 5 | |
6 | 6 | ////////////////////// core.inoに書くべき関数群 ////////////////////// |
7 | 7 |
@@ -12,7 +12,7 @@ | ||
12 | 12 | void tick(); |
13 | 13 | |
14 | 14 | // シリアルからのコマンド受付 |
15 | -void tunnel::invokeCommand(SerialReader* serialReader); | |
15 | +void AcsSerialReader_invokeCommand(AcsSerialReader* acsSerialReader); | |
16 | 16 | |
17 | 17 | #endif |
18 | 18 |
@@ -24,9 +24,9 @@ | ||
24 | 24 | |
25 | 25 | FiapPacketBuffer fiapPacketBuffer; |
26 | 26 | |
27 | -void tunnel::invokeCommand(SerialReader* serialReader) | |
27 | +void AcsSerialReader_invokeCommand(AcsSerialReader* acsSerialReader) | |
28 | 28 | { |
29 | - if (strcmp(serialReader->argumentsString[0], "ShowTime") == 0) { | |
29 | + if (strcmp(acsSerialReader->argumentsString[0], "ShowTime") == 0) { | |
30 | 30 | |
31 | 31 | // 操作 |
32 | 32 |
@@ -35,22 +35,22 @@ | ||
35 | 35 | { |
36 | 36 | char buf[50]; |
37 | 37 | sprintf(buf, "%02d/%02d/%02d %02d:%02d:%2d", |
38 | - serialReader->argumentsInt[0], | |
39 | - serialReader->argumentsInt[1], | |
40 | - serialReader->argumentsInt[2], | |
41 | - serialReader->argumentsInt[3], | |
42 | - serialReader->argumentsInt[4], | |
43 | - serialReader->argumentsInt[5]); | |
38 | + acsSerialReader->argumentsInt[0], | |
39 | + acsSerialReader->argumentsInt[1], | |
40 | + acsSerialReader->argumentsInt[2], | |
41 | + acsSerialReader->argumentsInt[3], | |
42 | + acsSerialReader->argumentsInt[4], | |
43 | + acsSerialReader->argumentsInt[5]); | |
44 | 44 | Serial.println(buf); |
45 | 45 | } |
46 | 46 | sendMessageEnd(); |
47 | 47 | |
48 | 48 | return; |
49 | 49 | } |
50 | - if (strcmp(serialReader->argumentsString[0], "SetIdPrefix") == 0) { | |
50 | + if (strcmp(acsSerialReader->argumentsString[0], "SetIdPrefix") == 0) { | |
51 | 51 | |
52 | 52 | // 操作 |
53 | - strcpy(fiap_id_prefix, serialReader->argumentsString[1]); | |
53 | + strcpy(fiap_id_prefix, acsSerialReader->argumentsString[1]); | |
54 | 54 | |
55 | 55 | |
56 | 56 | sendMessageBegin(); |
@@ -60,7 +60,7 @@ | ||
60 | 60 | |
61 | 61 | return; |
62 | 62 | } |
63 | - if (strcmp(serialReader->argumentsString[0], "FlushFiapPacket") == 0) { | |
63 | + if (strcmp(acsSerialReader->argumentsString[0], "FlushFiapPacket") == 0) { | |
64 | 64 | |
65 | 65 | // 操作 |
66 | 66 | fiapPacketBuffer.flush(); |
@@ -70,38 +70,38 @@ | ||
70 | 70 | |
71 | 71 | return; |
72 | 72 | } |
73 | - if (strcmp(serialReader->argumentsString[0], "PushFiapPacket") == 0) { | |
73 | + if (strcmp(acsSerialReader->argumentsString[0], "PushFiapPacket") == 0) { | |
74 | 74 | |
75 | 75 | // 操作 |
76 | 76 | { |
77 | 77 | DateTime dateTime; |
78 | - dateTime.year = serialReader->argumentsInt[0]; | |
79 | - dateTime.month = serialReader->argumentsInt[1]; | |
80 | - dateTime.day = serialReader->argumentsInt[2]; | |
81 | - dateTime.hour = serialReader->argumentsInt[3]; | |
82 | - dateTime.minute = serialReader->argumentsInt[4]; | |
83 | - dateTime.second = serialReader->argumentsInt[5]; | |
78 | + dateTime.year = acsSerialReader->argumentsInt[0]; | |
79 | + dateTime.month = acsSerialReader->argumentsInt[1]; | |
80 | + dateTime.day = acsSerialReader->argumentsInt[2]; | |
81 | + dateTime.hour = acsSerialReader->argumentsInt[3]; | |
82 | + dateTime.minute = acsSerialReader->argumentsInt[4]; | |
83 | + dateTime.second = acsSerialReader->argumentsInt[5]; | |
84 | 84 | |
85 | 85 | fiapPacketBuffer.acceptElement( |
86 | - serialReader->argumentsString[1], | |
87 | - serialReader->argumentsString[2], | |
86 | + acsSerialReader->argumentsString[1], | |
87 | + acsSerialReader->argumentsString[2], | |
88 | 88 | dateTime); |
89 | 89 | } |
90 | 90 | |
91 | 91 | |
92 | 92 | sendMessageBegin(); |
93 | 93 | Serial.println("Push Fiap Packet"); |
94 | - Serial.println(serialReader->argumentsString[1]); | |
95 | - Serial.println(serialReader->argumentsString[2]); | |
94 | + Serial.println(acsSerialReader->argumentsString[1]); | |
95 | + Serial.println(acsSerialReader->argumentsString[2]); | |
96 | 96 | { |
97 | 97 | char buf[50]; |
98 | 98 | sprintf(buf, "%02d/%02d/%02d %02d:%02d:%2d", |
99 | - serialReader->argumentsInt[0], | |
100 | - serialReader->argumentsInt[1], | |
101 | - serialReader->argumentsInt[2], | |
102 | - serialReader->argumentsInt[3], | |
103 | - serialReader->argumentsInt[4], | |
104 | - serialReader->argumentsInt[5]); | |
99 | + acsSerialReader->argumentsInt[0], | |
100 | + acsSerialReader->argumentsInt[1], | |
101 | + acsSerialReader->argumentsInt[2], | |
102 | + acsSerialReader->argumentsInt[3], | |
103 | + acsSerialReader->argumentsInt[4], | |
104 | + acsSerialReader->argumentsInt[5]); | |
105 | 105 | Serial.println(buf); |
106 | 106 | } |
107 | 107 | sendMessageEnd(); |
@@ -112,18 +112,18 @@ | ||
112 | 112 | |
113 | 113 | sendMessageBegin(); |
114 | 114 | Serial.print("Command: "); |
115 | - Serial.println(serialReader->argumentsString[0]); | |
116 | - for (int i = 0; i < serialReader->argumentsIntLength; i++) { | |
115 | + Serial.println(acsSerialReader->argumentsString[0]); | |
116 | + for (int i = 0; i < acsSerialReader->argumentsIntLength; i++) { | |
117 | 117 | Serial.print("Int: "); |
118 | - Serial.println(serialReader->argumentsInt[i]); | |
118 | + Serial.println(acsSerialReader->argumentsInt[i]); | |
119 | 119 | } |
120 | - for (int i = 0; i < serialReader->argumentsDoubleLength; i++) { | |
120 | + for (int i = 0; i < acsSerialReader->argumentsDoubleLength; i++) { | |
121 | 121 | Serial.print("Double: "); |
122 | - Serial.println(serialReader->argumentsDouble[i]); | |
122 | + Serial.println(acsSerialReader->argumentsDouble[i]); | |
123 | 123 | } |
124 | - for (int i = 0; i < serialReader->argumentsStringLength; i++) { | |
124 | + for (int i = 0; i < acsSerialReader->argumentsStringLength; i++) { | |
125 | 125 | Serial.print("String: "); |
126 | - Serial.println(serialReader->argumentsString[i]); | |
126 | + Serial.println(acsSerialReader->argumentsString[i]); | |
127 | 127 | } |
128 | 128 | sendMessageEnd(); |
129 | 129 |
@@ -1,74 +0,0 @@ | ||
1 | -#ifndef INCLUDE_tunnel_SerialReader_h | |
2 | -#define INCLUDE_tunnel_SerialReader_h | |
3 | - | |
4 | -namespace tunnel | |
5 | -{ | |
6 | - | |
7 | - const static int ARGUMENTS_INT_MAX_LENGTH = 100; | |
8 | - const static int ARGUMENTS_DOUBLE_MAX_LENGTH = 10; | |
9 | - const static int ARGUMENTS_STRING_MAX_LENGTH = 4; | |
10 | - const static int ARGUMENT_STRING_MAX_LENGTH = 100; | |
11 | - const static int BUFFER_MAX_LENGTH = 100; | |
12 | - | |
13 | - // シリアルからの命令 | |
14 | - // "I21\n" int型引数をpush | |
15 | - // "D3.14\n" double型引数をpush | |
16 | - // "Sstring123%&\n" 99文字までの改行を含まない文字列型引数をpush | |
17 | - // "C\n" 引数の全破棄 | |
18 | - // "M\n" コマンドの実行(コマンド名のために文字列引数が1個必要) | |
19 | - // | |
20 | - // readOneOperationをすると、Serialから一行分の命令を読み込んで実行する。 | |
21 | - // 命令の区切り文字は\nのほかに;も可能 | |
22 | - class SerialReader { | |
23 | -public: | |
24 | - | |
25 | - int argumentsInt[ARGUMENTS_INT_MAX_LENGTH]; | |
26 | - int argumentsIntLength; | |
27 | - | |
28 | - double argumentsDouble[ARGUMENTS_DOUBLE_MAX_LENGTH]; | |
29 | - int argumentsDoubleLength; | |
30 | - | |
31 | - char argumentsString[ARGUMENTS_STRING_MAX_LENGTH][ARGUMENT_STRING_MAX_LENGTH]; | |
32 | - int argumentsStringLength; | |
33 | - | |
34 | - SerialReader(); | |
35 | - | |
36 | - void reset(); | |
37 | - | |
38 | - boolean readOneOperation(); | |
39 | - | |
40 | -private: | |
41 | - | |
42 | - int lastShownAcceptedChars; | |
43 | - | |
44 | - int acceptedChars; | |
45 | - | |
46 | - int read(); | |
47 | - | |
48 | - void showAcceptedChars(); | |
49 | - | |
50 | - boolean pushInt(int value); | |
51 | - | |
52 | - boolean pushDouble(double value); | |
53 | - | |
54 | - // 文字列長が長すぎる場合、失敗してfalseが返る。 | |
55 | - boolean pushString(char* value); | |
56 | - | |
57 | - // シリアルから読みだした文字のバッファ | |
58 | - char buffer[BUFFER_MAX_LENGTH]; | |
59 | - int bufferLength; | |
60 | - | |
61 | - // 指定キャラクタまで読み込んでbufferに入れる | |
62 | - // @return 正常終了してbufferが更新された場合にtrue | |
63 | - // @param containStopper 指定キャラクタをバッファに含めるかどうか | |
64 | - boolean readUntil(char stopper1, char stopper2, char escape); | |
65 | - | |
66 | - }; | |
67 | - | |
68 | - // メソッド名は最初の文字列引数。 | |
69 | - void invokeCommand(SerialReader* serialReader); | |
70 | - | |
71 | -} | |
72 | - | |
73 | -#endif | |
74 | - |
@@ -1,246 +0,0 @@ | ||
1 | -#include "tunnel_SerialReader.h" | |
2 | - | |
3 | -tunnel::SerialReader::SerialReader() | |
4 | -{ | |
5 | - reset(); | |
6 | -} | |
7 | - | |
8 | -void tunnel::SerialReader::reset() | |
9 | -{ | |
10 | - argumentsIntLength = 0; | |
11 | - argumentsDoubleLength = 0; | |
12 | - argumentsStringLength = 0; | |
13 | - bufferLength = 0; | |
14 | - lastShownAcceptedChars = 0; | |
15 | - acceptedChars = 0; | |
16 | -} | |
17 | - | |
18 | -int tunnel::SerialReader::read() | |
19 | -{ | |
20 | - if (!Serial.available()) { | |
21 | - showAcceptedChars(); | |
22 | - while (!Serial.available()); | |
23 | - } | |
24 | - | |
25 | - if (acceptedChars > lastShownAcceptedChars + 20) showAcceptedChars(); | |
26 | - | |
27 | - acceptedChars++; | |
28 | - return Serial.read(); | |
29 | -} | |
30 | - | |
31 | -void tunnel::SerialReader::showAcceptedChars() | |
32 | -{ | |
33 | - Serial.print("C:"); | |
34 | - Serial.println(acceptedChars); | |
35 | - lastShownAcceptedChars = acceptedChars; | |
36 | -} | |
37 | - | |
38 | -boolean tunnel::SerialReader::pushInt(int value) | |
39 | -{ | |
40 | - if (argumentsIntLength >= ARGUMENTS_INT_MAX_LENGTH) return false; | |
41 | - argumentsInt[argumentsIntLength] = value; | |
42 | - argumentsIntLength++; | |
43 | -} | |
44 | - | |
45 | -boolean tunnel::SerialReader::pushDouble(double value) | |
46 | -{ | |
47 | - if (argumentsDoubleLength >= ARGUMENTS_DOUBLE_MAX_LENGTH) return false; | |
48 | - argumentsDouble[argumentsDoubleLength] = value; | |
49 | - argumentsDoubleLength++; | |
50 | -} | |
51 | - | |
52 | -boolean tunnel::SerialReader::pushString(char* value) | |
53 | -{ | |
54 | - if (argumentsStringLength >= ARGUMENTS_STRING_MAX_LENGTH) return false; | |
55 | - if (strlen(value) >= ARGUMENT_STRING_MAX_LENGTH) return false; | |
56 | - strcpy(argumentsString[argumentsStringLength], value); | |
57 | - argumentsStringLength++; | |
58 | -} | |
59 | - | |
60 | -boolean tunnel::SerialReader::readUntil( | |
61 | -char stopper1, | |
62 | -char stopper2, | |
63 | -char escape) | |
64 | -{ | |
65 | - | |
66 | - // 既に受け取った'\0'を含めない文字列長=これから代入すべき添え字。 | |
67 | - // 実際のバッファサイズも超える。 | |
68 | - bufferLength = 0; | |
69 | - | |
70 | - // この文字はエスケープ済みである | |
71 | - boolean escaped = false; | |
72 | - | |
73 | - while (true) { | |
74 | - int c = read(); | |
75 | - | |
76 | - // 謎エラー | |
77 | - if (c == -1) { | |
78 | - Serial.println("Warning:readUntil -1"); | |
79 | - continue; | |
80 | - } | |
81 | - | |
82 | - // ストッパーやエスケープ文字が着たか否か | |
83 | - boolean isStopper = (c == stopper1) || (c == stopper2); | |
84 | - boolean isEscape = c == escape; | |
85 | - | |
86 | - // この文字が特殊文字として処理されないべきか否か | |
87 | - boolean appendable; | |
88 | - | |
89 | - // この文字自体がエスケープ済みなら、 | |
90 | - if (escaped) { | |
91 | - escaped = false; | |
92 | - | |
93 | - // 特殊文字ではない。 | |
94 | - appendable = true; | |
95 | - } | |
96 | - else { | |
97 | - // エスケープ済みではなくて、 | |
98 | - | |
99 | - // ストッパーやエスケープ文字なら、 | |
100 | - if (isStopper || isEscape) { | |
101 | - // 特殊文字として処理されるべき。 | |
102 | - appendable = false; | |
103 | - } | |
104 | - else { | |
105 | - // そうでなければ通常文字として処理されるべき。 | |
106 | - appendable = true; | |
107 | - } | |
108 | - } | |
109 | - | |
110 | - /////////////////////////////////////////// メイン処理 | |
111 | - | |
112 | - // この文字が通常文字として処理されるべきならば、 | |
113 | - if (appendable) { | |
114 | - | |
115 | - // バッファがあふれていなければ、 | |
116 | - if (bufferLength <= BUFFER_MAX_LENGTH - 1 - 1) { | |
117 | - // バッファに追加。 | |
118 | - buffer[bufferLength] = c; | |
119 | - } | |
120 | - | |
121 | - // どちらにしろ既に受け取った文字列長を増やす。 | |
122 | - bufferLength++; | |
123 | - continue; | |
124 | - } | |
125 | - | |
126 | - // エスケープ文字が来た場合、 | |
127 | - if (isEscape) { | |
128 | - | |
129 | - // 次の文字をエスケープ済みに指定 | |
130 | - escaped = true; | |
131 | - | |
132 | - continue; | |
133 | - } | |
134 | - | |
135 | - // 区切り文字が来た場合、 | |
136 | - if (isStopper) { | |
137 | - // バッファがあふれていなければ、 | |
138 | - if (bufferLength <= BUFFER_MAX_LENGTH - 1) { | |
139 | - // 終端文字を追加。 | |
140 | - buffer[bufferLength] = '\0'; | |
141 | - } | |
142 | - else { | |
143 | - // あふれていても追加。 | |
144 | - buffer[BUFFER_MAX_LENGTH - 1] = '\0'; | |
145 | - } | |
146 | - | |
147 | - break; | |
148 | - } | |
149 | - | |
150 | - } | |
151 | - | |
152 | - // bufferLength: 文字列長 | |
153 | - if (bufferLength <= BUFFER_MAX_LENGTH - 1) { | |
154 | - return true; | |
155 | - } | |
156 | - else { | |
157 | - Serial.print("Warning:line length over: "); | |
158 | - Serial.print(bufferLength); | |
159 | - Serial.println(""); | |
160 | - return false; | |
161 | - } | |
162 | -} | |
163 | - | |
164 | -boolean tunnel::SerialReader::readOneOperation() | |
165 | -{ | |
166 | - if (!Serial.available()) return false; | |
167 | - | |
168 | - int c = read(); | |
169 | - if (c == -1) { | |
170 | - Serial.println("Warning:readOneOperation -1"); | |
171 | - return false; | |
172 | - } | |
173 | - else if (c == 'I') { | |
174 | - if (readUntil('\n', ';', '\\')) { | |
175 | - int value = atoi(buffer); | |
176 | - pushInt(value); | |
177 | - Serial.print("Message:(int) "); | |
178 | - Serial.print(value); | |
179 | - Serial.println(""); | |
180 | - return true; | |
181 | - } else { | |
182 | - Serial.println("Warning:readUntil == false"); | |
183 | - } | |
184 | - } | |
185 | - else if (c == 'D') { | |
186 | - if (readUntil('\n', ';', '\\')) { | |
187 | - double value = atof(buffer); | |
188 | - pushDouble(value); | |
189 | - Serial.print("Message:(double) "); | |
190 | - Serial.print(value); | |
191 | - Serial.println(""); | |
192 | - return true; | |
193 | - } else { | |
194 | - Serial.println("Warning:readUntil == false"); | |
195 | - } | |
196 | - } | |
197 | - else if (c == 'S') { | |
198 | - if (readUntil('\n', ';', '\\')) { | |
199 | - pushString(buffer); | |
200 | - Serial.print("Message:(string) "); | |
201 | - Serial.print(buffer); | |
202 | - Serial.println(""); | |
203 | - return true; | |
204 | - } else { | |
205 | - Serial.println("Warning:readUntil == false"); | |
206 | - } | |
207 | - } | |
208 | - else if (c == 'M') { | |
209 | - readUntil('\n', ';', '\\'); | |
210 | - invokeCommand(this); | |
211 | - return true; | |
212 | - } | |
213 | - else if (c == 'C') { | |
214 | - readUntil('\n', ';', '\\'); | |
215 | - argumentsIntLength = 0; | |
216 | - argumentsDoubleLength = 0; | |
217 | - argumentsStringLength = 0; | |
218 | - Serial.println("Message:clear operator"); | |
219 | - return true; | |
220 | - } | |
221 | - else if (c == 'R') { | |
222 | - readUntil('\n', ';', '\\'); | |
223 | - reset(); | |
224 | - Serial.println("Message:reset SerialReader"); | |
225 | - return true; | |
226 | - } | |
227 | - else if (c == '\n') { | |
228 | - Serial.println("Message:blank operator"); | |
229 | - return true; | |
230 | - } | |
231 | - else if (c == ';') { | |
232 | - Serial.println("Message:blank operator"); | |
233 | - return true; | |
234 | - } | |
235 | - else { | |
236 | - readUntil('\n', ';', '\\'); | |
237 | - Serial.print("Warning:unknown operator: "); | |
238 | - Serial.print((char) c); | |
239 | - Serial.println(""); | |
240 | - return false; | |
241 | - } | |
242 | - | |
243 | - return false; | |
244 | -} | |
245 | - | |
246 | - |