Tunnel(Serial To IEEE1888)
修订版 | a06af98257bfa1296172d3c7bd762fcbaa74f161 (tree) |
---|---|
时间 | 2015-07-10 20:23:36 |
作者 | MirrgieRiana Kurilab |
Commiter | MirrgieRiana Kurilab |
TunnelSerialToIEEE1888.inoをライブラリAcsSerialFrameworkに移植
各種名称の大幅変更
core.inoを廃止してメインのinoファイルにその内容が来るように
@@ -1,73 +0,0 @@ | ||
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 | - |
@@ -1,246 +0,0 @@ | ||
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 | - |
@@ -12,9 +12,9 @@ | ||
12 | 12 | byte second; // 0~59 |
13 | 13 | }; |
14 | 14 | |
15 | -#define FiapPacketBuffer_ELEMENTS_MAX_LENGTH 15 | |
16 | -#define FiapPacketBuffer_CID_MAX_LENGTH 40 | |
17 | -#define FiapPacketBuffer_VALUE_MAX_LENGTH 40 | |
15 | +#define FIAP_PACKET_BUFFER_ELEMENTS_MAX_LENGTH 15 | |
16 | +#define FIAP_PACKET_BUFFER_CID_MAX_LENGTH 40 | |
17 | +#define FIAP_PACKET_BUFFER_VALUE_MAX_LENGTH 40 | |
18 | 18 | |
19 | 19 | // acceptElementをひたすら呼び出すだけで送信される。 |
20 | 20 | // 内部でバッファリングされる。一連の追加が終わったらflushすると、送信される。 |
@@ -38,19 +38,21 @@ | ||
38 | 38 | |
39 | 39 | private: |
40 | 40 | |
41 | - struct fiap_element fiapElements[FiapPacketBuffer_ELEMENTS_MAX_LENGTH]; | |
41 | + struct fiap_element fiapElements[FIAP_PACKET_BUFFER_ELEMENTS_MAX_LENGTH]; | |
42 | 42 | |
43 | 43 | char fiapElement_cids |
44 | - [FiapPacketBuffer_ELEMENTS_MAX_LENGTH] | |
45 | - [FiapPacketBuffer_CID_MAX_LENGTH]; | |
44 | + [FIAP_PACKET_BUFFER_ELEMENTS_MAX_LENGTH] | |
45 | + [FIAP_PACKET_BUFFER_CID_MAX_LENGTH]; | |
46 | 46 | |
47 | 47 | char fiapElement_values |
48 | - [FiapPacketBuffer_ELEMENTS_MAX_LENGTH] | |
49 | - [FiapPacketBuffer_VALUE_MAX_LENGTH]; | |
48 | + [FIAP_PACKET_BUFFER_ELEMENTS_MAX_LENGTH] | |
49 | + [FIAP_PACKET_BUFFER_VALUE_MAX_LENGTH]; | |
50 | 50 | |
51 | 51 | int fiapElementLength; |
52 | 52 | |
53 | 53 | }; |
54 | 54 | |
55 | +FIAPUploadAgent* FIAP_PACKET_BUFFER_getFIAPUploadAgent(); | |
56 | + | |
55 | 57 | #endif |
56 | 58 |
@@ -1,3 +1,4 @@ | ||
1 | +#include <SPI.h> | |
1 | 2 | #include "FiapPacketBuffer.h" |
2 | 3 | |
3 | 4 | FiapPacketBuffer::FiapPacketBuffer() |
@@ -12,7 +13,7 @@ | ||
12 | 13 | |
13 | 14 | void FiapPacketBuffer::acceptElement(char* cid, char* value, DateTime dateTime) |
14 | 15 | { |
15 | - if (fiapElementLength >= FiapPacketBuffer_ELEMENTS_MAX_LENGTH) { | |
16 | + if (fiapElementLength >= FIAP_PACKET_BUFFER_ELEMENTS_MAX_LENGTH) { | |
16 | 17 | flush(); |
17 | 18 | } |
18 | 19 |
@@ -33,7 +34,7 @@ | ||
33 | 34 | fiapElements[fiapElementLength] = tmp; |
34 | 35 | |
35 | 36 | fiapElementLength++; |
36 | - if (fiapElementLength >= FiapPacketBuffer_ELEMENTS_MAX_LENGTH) { | |
37 | + if (fiapElementLength >= FIAP_PACKET_BUFFER_ELEMENTS_MAX_LENGTH) { | |
37 | 38 | flush(); |
38 | 39 | } |
39 | 40 | } |
@@ -41,17 +42,18 @@ | ||
41 | 42 | void FiapPacketBuffer::flush() |
42 | 43 | { |
43 | 44 | if (fiapElementLength > 0) { |
44 | - int res = fiapUploadAgent.post(fiapElements, fiapElementLength); | |
45 | + FIAPUploadAgent* fiap = FiapPacketBuffer_getFIAPUploadAgent(); | |
46 | + int res = fiap->post(fiapElements, fiapElementLength); | |
45 | 47 | clear(); |
46 | - | |
48 | + | |
47 | 49 | if (res == 5) { |
48 | 50 | Serial.println("Warning:HTTP timeout"); |
49 | - } else if (res != 0) { | |
51 | + } | |
52 | + else if (res != 0) { | |
50 | 53 | Serial.print("Warning:HTTP error: "); |
51 | 54 | Serial.print(res); |
52 | 55 | Serial.println(""); |
53 | 56 | } |
54 | 57 | } |
55 | 58 | } |
56 | - | |
57 | 59 |
@@ -1,39 +0,0 @@ | ||
1 | -#ifndef INCLUDED_TunnelSerialToIEEE1888_H | |
2 | -#define INCLUDED_TunnelSerialToIEEE1888_H | |
3 | - | |
4 | -#include <FIAPUploadAgent.h> | |
5 | -#include "AcsSerialReader.h" | |
6 | - | |
7 | -// ------------------------- グローバル変数 ------------------------- | |
8 | - | |
9 | -// PointSet ID(PointIDのPrefix) | |
10 | -extern char fiap_id_prefix[200]; | |
11 | - | |
12 | -// ------------------------- loop関連 ------------------------- | |
13 | - | |
14 | -// loopの間隔。 | |
15 | -extern int waitMs; | |
16 | - | |
17 | -// ------------------------- シリアル通信からの引数関連 ------------------------- | |
18 | - | |
19 | -extern AcsSerialReader acsSerialReader; | |
20 | - | |
21 | -// ------------------------- メッセージ関連 ------------------------- | |
22 | - | |
23 | -// 1行のエラーメッセージを送信し、tickの呼び出しを無効にする。 | |
24 | -// @param message 改行不可。 | |
25 | -void error(char* message); | |
26 | - | |
27 | -// 1行のメッセージを送信する。 | |
28 | -void sendMessage(char* message); | |
29 | - | |
30 | -// 複数行メッセージ送信モードにする。 | |
31 | -// sendMessageEndを行うまでにSerial.printlnなどを利用可能。 | |
32 | -void sendMessageBegin(); | |
33 | - | |
34 | -// sendMessageBeginでの複数行メッセージ送信モードを終了し、 | |
35 | -// 通常の制御構文を通信可能にする。 | |
36 | -void sendMessageEnd(); | |
37 | - | |
38 | -#endif | |
39 | - |
@@ -1,17 +1,16 @@ | ||
1 | -// MiconBoard-Type: Arduino Mega 2560 or Mega ADK | |
2 | -// Library-Required: 'Ethernet' | |
3 | -// Library-Required: 'SPI' | |
4 | -// Library-Required: 'FIAPUploadAgent' | |
1 | +// @MiconBoardType 'Arduino Mega 2560 or Mega ADK' | |
2 | +// @LibraryRequired 'SPI' | |
3 | +// @LibraryRequired 'Ethernet' | |
4 | +// @LibraryRequired 'FIAPUploadAgent' | |
5 | +// @LibraryRequired 'AcsSerialFramework' | |
5 | 6 | |
6 | -#include <Ethernet.h> | |
7 | 7 | #include <SPI.h> |
8 | +#include <Ethernet.h> | |
8 | 9 | #include <FIAPUploadAgent.h> |
10 | +#include <AcsSerialFramework.h> | |
11 | +#include "FiapPacketBuffer.h" | |
9 | 12 | |
10 | -#include "TunnelSerialToIEEE1888.h" | |
11 | -#include "core.h" | |
12 | -#include "AcsSerialReader.h" | |
13 | - | |
14 | -///////////////////////// 初期化定数 ///////////////////////// | |
13 | +///////////////////////////////////////////////////////////// | |
15 | 14 | |
16 | 15 | // ---------------------- 固有設定 ---------------------- |
17 | 16 | byte MAC_ADDRESS_LOCAL[] = { |
@@ -23,18 +22,13 @@ | ||
23 | 22 | const char* SERVER_PATH = "/axis2/services/FIAPStorage"; |
24 | 23 | const int SERVER_PORT = 80; |
25 | 24 | |
26 | -// ---------------------- Point設定 ---------------------- | |
25 | +// ---------------------- Fiap/PointId関連 ---------------------- | |
27 | 26 | char fiap_id_prefix[200]; |
28 | - | |
29 | -///////////////////////// MainRoutine ///////////////////////// | |
30 | - | |
31 | 27 | FIAPUploadAgent fiapUploadAgent; |
32 | 28 | |
33 | 29 | void setup() |
34 | 30 | { |
35 | - | |
36 | - // USBシリアルポートの初期化 | |
37 | - Serial.begin(9600); | |
31 | + AcsSerialFramework::setup(); | |
38 | 32 | |
39 | 33 | // イーサネット関連の初期化 |
40 | 34 | if (Ethernet.begin(MAC_ADDRESS_LOCAL) == 0) { |
@@ -43,74 +37,123 @@ | ||
43 | 37 | } |
44 | 38 | |
45 | 39 | // FIAPライブラリの初期化 |
40 | + // fiap_id_prefixは遅延して初期化や上書きしても反映される。 | |
46 | 41 | fiapUploadAgent.begin(SERVER_HOST, SERVER_PATH, SERVER_PORT, fiap_id_prefix); |
47 | 42 | |
48 | - // コアルーチン初期化 | |
49 | - initCore(); | |
50 | - | |
51 | -} | |
43 | + // FiapIdPrefixの初期値 | |
44 | + strcpy(fiap_id_prefix, "http://j.kisarazu.ac.jp/Arduino/ANTS/0301/"); | |
52 | 45 | |
53 | -boolean isRunnable = true; // 初期化が正常終了した場合にtrue | |
54 | -int waitMs = 500; | |
55 | - | |
56 | -AcsSerialReader acsSerialReader; | |
57 | - | |
58 | -boolean delayCanceled = false; | |
46 | + sendMessage(">>>>> initialized"); | |
47 | +} | |
59 | 48 | |
60 | 49 | void loop() |
61 | 50 | { |
62 | - if (delayCanceled) { | |
63 | - delayCanceled = false; | |
64 | - } | |
65 | - else { | |
66 | - delay(waitMs); | |
67 | - } | |
51 | + AcsSerialFramework::loop(); | |
52 | +} | |
68 | 53 | |
69 | - if (!isRunnable) { | |
70 | - waitMs = 5000; | |
71 | - error("initializing error!"); | |
54 | +///////////////////////////////////////////////////////////// | |
55 | + | |
56 | +void tick() | |
57 | +{ | |
58 | + delay(100); | |
59 | +} | |
60 | + | |
61 | +void onUnknownCommand(AcsSerialReader* acsSerialReader) | |
62 | +{ | |
63 | + | |
64 | ||
65 | + sendMessageBlockBegin(); | |
66 | + Serial.print("Unknown Command: "); | |
67 | + Serial.println(acsSerialReader->argumentsString[0]); | |
68 | + for (int i = 0; i < acsSerialReader->argumentsIntLength; i++) { | |
69 | + Serial.print(" Int: "); | |
70 | + Serial.println(acsSerialReader->argumentsInt[i]); | |
72 | 71 | } |
73 | - else { | |
74 | - if (acsSerialReader.readOneOperation()) { | |
75 | - delayCanceled = true; | |
76 | - } | |
77 | - tick(); | |
72 | + for (int i = 0; i < acsSerialReader->argumentsDoubleLength; i++) { | |
73 | + Serial.print(" Double: "); | |
74 | + Serial.println(acsSerialReader->argumentsDouble[i]); | |
78 | 75 | } |
76 | + for (int i = 0; i < acsSerialReader->argumentsStringLength; i++) { | |
77 | + Serial.print(" String: "); | |
78 | + Serial.println(acsSerialReader->argumentsString[i]); | |
79 | + } | |
80 | + sendMessageBlockEnd(); | |
79 | 81 | |
80 | 82 | } |
81 | 83 | |
82 | -////////////////////////////// | |
84 | +///////////////////////////////////////////////////////////// | |
83 | 85 | |
84 | -void sendImpl(char* command, char* message) | |
86 | +FiapPacketBuffer fiapPacketBuffer; | |
87 | + | |
88 | +FIAPUploadAgent* FiapPacketBuffer_getFIAPUploadAgent() | |
85 | 89 | { |
86 | - Serial.print(command); | |
87 | - Serial.print(":"); | |
88 | - Serial.println(message); | |
89 | -} | |
90 | - | |
91 | -void error(char* message) | |
92 | -{ | |
93 | - isRunnable = false; | |
94 | - sendImpl("Error", message); | |
90 | + return &fiapUploadAgent; | |
95 | 91 | } |
96 | 92 | |
97 | -void sendMessage(char* message) | |
98 | -{ | |
99 | - sendImpl("Message", message); | |
100 | -} | |
101 | - | |
102 | -char* messageBlockSentinel = "========f43789th6c43789t6"; | |
103 | - | |
104 | -void sendMessageBegin() | |
93 | +void AcsSerialReader_invokeCommand(AcsSerialReader* acsSerialReader) | |
105 | 94 | { |
106 | - sendImpl("MessageBlock", messageBlockSentinel); | |
107 | -} | |
95 | + if (strcmp(acsSerialReader->argumentsString[0], "SetIdPrefix") == 0) { | |
108 | 96 | |
109 | -void sendMessageEnd() | |
110 | -{ | |
111 | - Serial.println(messageBlockSentinel); | |
97 | + // 操作 | |
98 | + strcpy(fiap_id_prefix, acsSerialReader->argumentsString[1]); | |
99 | + | |
100 | ||
101 | + sendMessageBlockBegin(); | |
102 | + Serial.print("Set Id Prefix: "); | |
103 | + Serial.println(fiap_id_prefix); | |
104 | + sendMessageBlockEnd(); | |
105 | + | |
106 | + return; | |
107 | + } | |
108 | + if (strcmp(acsSerialReader->argumentsString[0], "FlushFiapPacket") == 0) { | |
109 | + | |
110 | + // 操作 | |
111 | + fiapPacketBuffer.flush(); | |
112 | + | |
113 | + // ptint | |
114 | + Serial.println("Message:flush"); | |
115 | + | |
116 | + return; | |
117 | + } | |
118 | + if (strcmp(acsSerialReader->argumentsString[0], "PushFiapPacket") == 0) { | |
119 | + | |
120 | + // 操作 | |
121 | + { | |
122 | + DateTime dateTime; | |
123 | + dateTime.year = acsSerialReader->argumentsInt[0]; | |
124 | + dateTime.month = acsSerialReader->argumentsInt[1]; | |
125 | + dateTime.day = acsSerialReader->argumentsInt[2]; | |
126 | + dateTime.hour = acsSerialReader->argumentsInt[3]; | |
127 | + dateTime.minute = acsSerialReader->argumentsInt[4]; | |
128 | + dateTime.second = acsSerialReader->argumentsInt[5]; | |
129 | + | |
130 | + fiapPacketBuffer.acceptElement( | |
131 | + acsSerialReader->argumentsString[1], | |
132 | + acsSerialReader->argumentsString[2], | |
133 | + dateTime); | |
134 | + } | |
135 | + | |
136 | ||
137 | + sendMessageBlockBegin(); | |
138 | + Serial.println("Push Fiap Packet"); | |
139 | + Serial.println(acsSerialReader->argumentsString[1]); | |
140 | + Serial.println(acsSerialReader->argumentsString[2]); | |
141 | + { | |
142 | + char buf[50]; | |
143 | + sprintf(buf, "%02d/%02d/%02d %02d:%02d:%2d", | |
144 | + acsSerialReader->argumentsInt[0], | |
145 | + acsSerialReader->argumentsInt[1], | |
146 | + acsSerialReader->argumentsInt[2], | |
147 | + acsSerialReader->argumentsInt[3], | |
148 | + acsSerialReader->argumentsInt[4], | |
149 | + acsSerialReader->argumentsInt[5]); | |
150 | + Serial.println(buf); | |
151 | + } | |
152 | + sendMessageBlockEnd(); | |
153 | + | |
154 | + return; | |
155 | + } | |
156 | + | |
157 | + onUnknownCommand(acsSerialReader); | |
112 | 158 | } |
113 | - | |
114 | - | |
115 | - | |
116 | 159 |
@@ -1,18 +0,0 @@ | ||
1 | -#ifndef INCLUDED_core_H | |
2 | -#define INCLUDED_core_H | |
3 | - | |
4 | -#include "AcsSerialReader.h" | |
5 | - | |
6 | -////////////////////// core.inoに書くべき関数群 ////////////////////// | |
7 | - | |
8 | -// setupの最後で呼び出される。 | |
9 | -void initCore(); | |
10 | - | |
11 | -// 初期化が正常終了している場合、tickPeriodごとに呼び出される。 | |
12 | -void tick(); | |
13 | - | |
14 | -// シリアルからのコマンド受付 | |
15 | -void AcsSerialReader_invokeCommand(AcsSerialReader* acsSerialReader); | |
16 | - | |
17 | -#endif | |
18 | - |
@@ -1,138 +0,0 @@ | ||
1 | -#include "TunnelSerialToIEEE1888.h" | |
2 | -#include "core.h" | |
3 | - | |
4 | -#include "FiapPacketBuffer.h" | |
5 | - | |
6 | -void initCore() | |
7 | -{ | |
8 | - sendMessageBegin(); | |
9 | - Serial.println(">>>>> initialized"); | |
10 | - sendMessageEnd(); | |
11 | - | |
12 | - strcpy(fiap_id_prefix, "http://j.kisarazu.ac.jp/Arduino/ANTS/0301/"); | |
13 | -} | |
14 | - | |
15 | -void tick() | |
16 | -{ | |
17 | - //sendMessageBegin(); | |
18 | - //Serial.print(">>>>> "); | |
19 | - //Serial.println(tickPeriod); | |
20 | - //sendMessageEnd(); | |
21 | - | |
22 | - waitMs = 200; | |
23 | -} | |
24 | - | |
25 | -FiapPacketBuffer fiapPacketBuffer; | |
26 | - | |
27 | -void AcsSerialReader_invokeCommand(AcsSerialReader* acsSerialReader) | |
28 | -{ | |
29 | - if (strcmp(acsSerialReader->argumentsString[0], "ShowTime") == 0) { | |
30 | - | |
31 | - // 操作 | |
32 | - | |
33 | ||
34 | - sendMessageBegin(); | |
35 | - { | |
36 | - char buf[50]; | |
37 | - sprintf(buf, "%02d/%02d/%02d %02d:%02d:%2d", | |
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 | - Serial.println(buf); | |
45 | - } | |
46 | - sendMessageEnd(); | |
47 | - | |
48 | - return; | |
49 | - } | |
50 | - if (strcmp(acsSerialReader->argumentsString[0], "SetIdPrefix") == 0) { | |
51 | - | |
52 | - // 操作 | |
53 | - strcpy(fiap_id_prefix, acsSerialReader->argumentsString[1]); | |
54 | - | |
55 | ||
56 | - sendMessageBegin(); | |
57 | - Serial.print("Set Id Prefix: "); | |
58 | - Serial.println(fiap_id_prefix); | |
59 | - sendMessageEnd(); | |
60 | - | |
61 | - return; | |
62 | - } | |
63 | - if (strcmp(acsSerialReader->argumentsString[0], "FlushFiapPacket") == 0) { | |
64 | - | |
65 | - // 操作 | |
66 | - fiapPacketBuffer.flush(); | |
67 | - | |
68 | - // ptint | |
69 | - Serial.println("Message:flush"); | |
70 | - | |
71 | - return; | |
72 | - } | |
73 | - if (strcmp(acsSerialReader->argumentsString[0], "PushFiapPacket") == 0) { | |
74 | - | |
75 | - // 操作 | |
76 | - { | |
77 | - DateTime dateTime; | |
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 | - | |
85 | - fiapPacketBuffer.acceptElement( | |
86 | - acsSerialReader->argumentsString[1], | |
87 | - acsSerialReader->argumentsString[2], | |
88 | - dateTime); | |
89 | - } | |
90 | - | |
91 | ||
92 | - sendMessageBegin(); | |
93 | - Serial.println("Push Fiap Packet"); | |
94 | - Serial.println(acsSerialReader->argumentsString[1]); | |
95 | - Serial.println(acsSerialReader->argumentsString[2]); | |
96 | - { | |
97 | - char buf[50]; | |
98 | - sprintf(buf, "%02d/%02d/%02d %02d:%02d:%2d", | |
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 | - Serial.println(buf); | |
106 | - } | |
107 | - sendMessageEnd(); | |
108 | - | |
109 | - return; | |
110 | - } | |
111 | - | |
112 | ||
113 | - sendMessageBegin(); | |
114 | - Serial.print("Command: "); | |
115 | - Serial.println(acsSerialReader->argumentsString[0]); | |
116 | - for (int i = 0; i < acsSerialReader->argumentsIntLength; i++) { | |
117 | - Serial.print("Int: "); | |
118 | - Serial.println(acsSerialReader->argumentsInt[i]); | |
119 | - } | |
120 | - for (int i = 0; i < acsSerialReader->argumentsDoubleLength; i++) { | |
121 | - Serial.print("Double: "); | |
122 | - Serial.println(acsSerialReader->argumentsDouble[i]); | |
123 | - } | |
124 | - for (int i = 0; i < acsSerialReader->argumentsStringLength; i++) { | |
125 | - Serial.print("String: "); | |
126 | - Serial.println(acsSerialReader->argumentsString[i]); | |
127 | - } | |
128 | - sendMessageEnd(); | |
129 | - | |
130 | -} | |
131 | - | |
132 | - | |
133 | - | |
134 | - | |
135 | - | |
136 | - | |
137 | - | |
138 | - |
@@ -20,27 +20,6 @@ | ||
20 | 20 | S801.3; |
21 | 21 | M; |
22 | 22 | |
23 | - | |
24 | -■命令 | |
25 | - | |
26 | -命令は英大文字で始まって区切り文字で終わる。 | |
27 | - | |
28 | -命令区切り文字: ';', '\n' | |
29 | -命令種類: | |
30 | - 'R': シリアルリーダーコンポーネントの内部変数の初期化 | |
31 | - 通信の確立時に行う。 | |
32 | - 'C': 与えた全引数の削除 | |
33 | - 'I': 整数型引数のpush 最大100個 | |
34 | - 'D': 浮動小数型引数のpush 最大10個 | |
35 | - 'S': 文字列型引数のpush(区切り文字は含められない) | |
36 | - '\\'ですべての文字はエスケープ可能。 | |
37 | - 最大4個、99文字 | |
38 | - 'M': コマンドの実行(引数は維持) | |
39 | - | |
40 | -※コマンド実行命令'M'のコマンド名は最初に与えた文字列型引数 | |
41 | -※区切り文字は連続して挿入すると無視される | |
42 | -※Arduinoの都合上の問題で、一度に受信バッファに64バイトまでしか格納しておけない。 | |
43 | - | |
44 | 23 | ■コマンド一覧 |
45 | 24 | |
46 | 25 | コマンド名: SetFiapIdPrefix |
@@ -0,0 +1,61 @@ | ||
1 | +#include <SPI.h> | |
2 | +#include "AcsSerialFramework.h" | |
3 | + | |
4 | +// シリアルから命令を読み取って | |
5 | +// メインのinoファイルにあるハンドラを呼び出す。 | |
6 | + | |
7 | +////////////////////// setup, loopから呼び出す関数群 ////////////////////// | |
8 | + | |
9 | +void AcsSerialFramework::setup() | |
10 | +{ | |
11 | + // USBシリアルポートの初期化 | |
12 | + Serial.begin(9600); | |
13 | +} | |
14 | + | |
15 | +boolean isRunnable = true; // 初期化が正常終了した場合にtrue | |
16 | +AcsSerialReader acsSerialReader; | |
17 | + | |
18 | +void AcsSerialFramework::loop() | |
19 | +{ | |
20 | + if (!isRunnable) { | |
21 | + delay(5000); | |
22 | + error("error occured!"); | |
23 | + } | |
24 | + else { | |
25 | + while (acsSerialReader.readOneOperation()) { | |
26 | + } | |
27 | + tick(); | |
28 | + } | |
29 | +} | |
30 | + | |
31 | +////////////////////// メッセージ関連 ////////////////////// | |
32 | + | |
33 | +void sendImpl(char* command, char* message) | |
34 | +{ | |
35 | + Serial.print(command); | |
36 | + Serial.print(":"); | |
37 | + Serial.println(message); | |
38 | +} | |
39 | + | |
40 | +void error(char* message) | |
41 | +{ | |
42 | + isRunnable = false; | |
43 | + sendImpl("Error", message); | |
44 | +} | |
45 | + | |
46 | +void sendMessage(char* message) | |
47 | +{ | |
48 | + sendImpl("Message", message); | |
49 | +} | |
50 | + | |
51 | +char* messageBlockSentinel = "========f43789th6c43789t6"; | |
52 | + | |
53 | +void sendMessageBlockBegin() | |
54 | +{ | |
55 | + sendImpl("MessageBlock", messageBlockSentinel); | |
56 | +} | |
57 | + | |
58 | +void sendMessageBlockEnd() | |
59 | +{ | |
60 | + Serial.println(messageBlockSentinel); | |
61 | +} |
@@ -0,0 +1,44 @@ | ||
1 | +#ifndef INCLUDE_AcsSerialFramework_h | |
2 | +#define INCLUDE_AcsSerialFramework_h | |
3 | + | |
4 | +#include "AcsSerialReader.h" | |
5 | + | |
6 | +////////////////////// setup, loopから呼び出す関数群 ////////////////////// | |
7 | + | |
8 | +namespace AcsSerialFramework | |
9 | +{ | |
10 | + | |
11 | + void setup(); | |
12 | + | |
13 | + void loop(); | |
14 | + | |
15 | +} | |
16 | + | |
17 | +////////////////////// メッセージ関連 ////////////////////// | |
18 | + | |
19 | +// 1行のエラーメッセージを送信し、tickの呼び出しを無効にする。 | |
20 | +// @param message 改行不可。 | |
21 | +void error(char* message); | |
22 | + | |
23 | +// 1行のメッセージを送信する。 | |
24 | +// @param message 改行不可。 | |
25 | +void sendMessage(char* message); | |
26 | + | |
27 | +// 複数行メッセージ送信モードにする。 | |
28 | +// sendMessageEndを行うまでにSerial.printlnなどを利用可能。 | |
29 | +// 最後はprintlnにしないと、複数行メッセージの終了信号が正常に送られない。 | |
30 | +void sendMessageBlockBegin(); | |
31 | + | |
32 | +// sendMessageBeginでの複数行メッセージ送信モードを終了し、 | |
33 | +// 通常の制御構文を通信可能にする。 | |
34 | +void sendMessageBlockEnd(); | |
35 | + | |
36 | +////////////////////// メインinoに書くべき関数群 ////////////////////// | |
37 | + | |
38 | +// 初期化が正常終了している場合、loopごとに呼び出される。 | |
39 | +void tick(); | |
40 | + | |
41 | +// シリアルからのコマンド受付 | |
42 | +void AcsSerialReader_invokeCommand(AcsSerialReader* acsSerialReader); | |
43 | + | |
44 | +#endif |
@@ -0,0 +1,248 @@ | ||
1 | +#include <SPI.h> | |
2 | +#include "AcsSerialReader.h" | |
3 | + | |
4 | +AcsSerialReader::AcsSerialReader() | |
5 | +{ | |
6 | + reset(); | |
7 | +} | |
8 | + | |
9 | +void AcsSerialReader::reset() | |
10 | +{ | |
11 | + argumentsIntLength = 0; | |
12 | + argumentsDoubleLength = 0; | |
13 | + argumentsStringLength = 0; | |
14 | + bufferLength = 0; | |
15 | + lastShownAcceptedChars = 0; | |
16 | + acceptedChars = 0; | |
17 | +} | |
18 | + | |
19 | +int AcsSerialReader::read() | |
20 | +{ | |
21 | + if (!Serial.available()) { | |
22 | + showAcceptedChars(); | |
23 | + while (!Serial.available()); | |
24 | + } | |
25 | + | |
26 | + if (acceptedChars > lastShownAcceptedChars + 20) showAcceptedChars(); | |
27 | + | |
28 | + acceptedChars++; | |
29 | + return Serial.read(); | |
30 | +} | |
31 | + | |
32 | +void AcsSerialReader::showAcceptedChars() | |
33 | +{ | |
34 | + Serial.print("C:"); | |
35 | + Serial.println(acceptedChars); | |
36 | + lastShownAcceptedChars = acceptedChars; | |
37 | +} | |
38 | + | |
39 | +boolean AcsSerialReader::pushInt(int value) | |
40 | +{ | |
41 | + if (argumentsIntLength >= ACS_SERIAL_READER_ARGUMENTS_INT_MAX_LENGTH) return false; | |
42 | + argumentsInt[argumentsIntLength] = value; | |
43 | + argumentsIntLength++; | |
44 | +} | |
45 | + | |
46 | +boolean AcsSerialReader::pushDouble(double value) | |
47 | +{ | |
48 | + if (argumentsDoubleLength >= ACS_SERIAL_READER_ARGUMENTS_DOUBLE_MAX_LENGTH) return false; | |
49 | + argumentsDouble[argumentsDoubleLength] = value; | |
50 | + argumentsDoubleLength++; | |
51 | +} | |
52 | + | |
53 | +boolean AcsSerialReader::pushString(char* value) | |
54 | +{ | |
55 | + if (argumentsStringLength >= ACS_SERIAL_READER_ARGUMENTS_STRING_MAX_LENGTH) return false; | |
56 | + if (strlen(value) >= ACS_SERIAL_READER_ARGUMENT_STRING_MAX_LENGTH) return false; | |
57 | + strcpy(argumentsString[argumentsStringLength], value); | |
58 | + argumentsStringLength++; | |
59 | +} | |
60 | + | |
61 | +boolean AcsSerialReader::readUntil( | |
62 | +char stopper1, | |
63 | +char stopper2, | |
64 | +char escape) | |
65 | +{ | |
66 | + | |
67 | + // 既に受け取った'\0'を含めない文字列長=これから代入すべき添え字。 | |
68 | + // 実際のバッファサイズも超える。 | |
69 | + bufferLength = 0; | |
70 | + | |
71 | + // この文字はエスケープ済みである | |
72 | + boolean escaped = false; | |
73 | + | |
74 | + while (true) { | |
75 | + int c = read(); | |
76 | + | |
77 | + // 謎エラー | |
78 | + if (c == -1) { | |
79 | + Serial.println("Warning:readUntil -1"); | |
80 | + continue; | |
81 | + } | |
82 | + | |
83 | + // ストッパーやエスケープ文字が着たか否か | |
84 | + boolean isStopper = (c == stopper1) || (c == stopper2); | |
85 | + boolean isEscape = c == escape; | |
86 | + | |
87 | + // この文字が特殊文字として処理されないべきか否か | |
88 | + boolean appendable; | |
89 | + | |
90 | + // この文字自体がエスケープ済みなら、 | |
91 | + if (escaped) { | |
92 | + escaped = false; | |
93 | + | |
94 | + // 特殊文字ではない。 | |
95 | + appendable = true; | |
96 | + } | |
97 | + else { | |
98 | + // エスケープ済みではなくて、 | |
99 | + | |
100 | + // ストッパーやエスケープ文字なら、 | |
101 | + if (isStopper || isEscape) { | |
102 | + // 特殊文字として処理されるべき。 | |
103 | + appendable = false; | |
104 | + } | |
105 | + else { | |
106 | + // そうでなければ通常文字として処理されるべき。 | |
107 | + appendable = true; | |
108 | + } | |
109 | + } | |
110 | + | |
111 | + /////////////////////////////////////////// メイン処理 | |
112 | + | |
113 | + // この文字が通常文字として処理されるべきならば、 | |
114 | + if (appendable) { | |
115 | + | |
116 | + // バッファがあふれていなければ、 | |
117 | + if (bufferLength <= ACS_SERIAL_READER_BUFFER_MAX_LENGTH - 1 - 1) { | |
118 | + // バッファに追加。 | |
119 | + buffer[bufferLength] = c; | |
120 | + } | |
121 | + | |
122 | + // どちらにしろ既に受け取った文字列長を増やす。 | |
123 | + bufferLength++; | |
124 | + continue; | |
125 | + } | |
126 | + | |
127 | + // エスケープ文字が来た場合、 | |
128 | + if (isEscape) { | |
129 | + | |
130 | + // 次の文字をエスケープ済みに指定 | |
131 | + escaped = true; | |
132 | + | |
133 | + continue; | |
134 | + } | |
135 | + | |
136 | + // 区切り文字が来た場合、 | |
137 | + if (isStopper) { | |
138 | + // バッファがあふれていなければ、 | |
139 | + if (bufferLength <= ACS_SERIAL_READER_BUFFER_MAX_LENGTH - 1) { | |
140 | + // 終端文字を追加。 | |
141 | + buffer[bufferLength] = '\0'; | |
142 | + } | |
143 | + else { | |
144 | + // あふれていても追加。 | |
145 | + buffer[ACS_SERIAL_READER_BUFFER_MAX_LENGTH - 1] = '\0'; | |
146 | + } | |
147 | + | |
148 | + break; | |
149 | + } | |
150 | + | |
151 | + } | |
152 | + | |
153 | + // bufferLength: 文字列長 | |
154 | + if (bufferLength <= ACS_SERIAL_READER_BUFFER_MAX_LENGTH - 1) { | |
155 | + return true; | |
156 | + } | |
157 | + else { | |
158 | + Serial.print("Warning:line length over: "); | |
159 | + Serial.print(bufferLength); | |
160 | + Serial.println(""); | |
161 | + return false; | |
162 | + } | |
163 | +} | |
164 | + | |
165 | +boolean AcsSerialReader::readOneOperation() | |
166 | +{ | |
167 | + if (!Serial.available()) return false; | |
168 | + | |
169 | + int c = read(); | |
170 | + if (c == -1) { | |
171 | + Serial.println("Warning:readOneOperation -1"); | |
172 | + return false; | |
173 | + } | |
174 | + else if (c == 'I') { | |
175 | + if (readUntil('\n', ';', '\\')) { | |
176 | + int value = atoi(buffer); | |
177 | + pushInt(value); | |
178 | + Serial.print("Message:(int) "); | |
179 | + Serial.print(value); | |
180 | + Serial.println(""); | |
181 | + return true; | |
182 | + } | |
183 | + else { | |
184 | + Serial.println("Warning:readUntil == false"); | |
185 | + } | |
186 | + } | |
187 | + else if (c == 'D') { | |
188 | + if (readUntil('\n', ';', '\\')) { | |
189 | + double value = atof(buffer); | |
190 | + pushDouble(value); | |
191 | + Serial.print("Message:(double) "); | |
192 | + Serial.print(value); | |
193 | + Serial.println(""); | |
194 | + return true; | |
195 | + } | |
196 | + else { | |
197 | + Serial.println("Warning:readUntil == false"); | |
198 | + } | |
199 | + } | |
200 | + else if (c == 'S') { | |
201 | + if (readUntil('\n', ';', '\\')) { | |
202 | + pushString(buffer); | |
203 | + Serial.print("Message:(string) "); | |
204 | + Serial.print(buffer); | |
205 | + Serial.println(""); | |
206 | + return true; | |
207 | + } | |
208 | + else { | |
209 | + Serial.println("Warning:readUntil == false"); | |
210 | + } | |
211 | + } | |
212 | + else if (c == 'M') { | |
213 | + readUntil('\n', ';', '\\'); | |
214 | + AcsSerialReader_invokeCommand(this); | |
215 | + return true; | |
216 | + } | |
217 | + else if (c == 'C') { | |
218 | + readUntil('\n', ';', '\\'); | |
219 | + argumentsIntLength = 0; | |
220 | + argumentsDoubleLength = 0; | |
221 | + argumentsStringLength = 0; | |
222 | + Serial.println("Message:clear operator"); | |
223 | + return true; | |
224 | + } | |
225 | + else if (c == 'R') { | |
226 | + readUntil('\n', ';', '\\'); | |
227 | + reset(); | |
228 | + Serial.println("Message:reset SerialReader"); | |
229 | + return true; | |
230 | + } | |
231 | + else if (c == '\n') { | |
232 | + Serial.println("Message:blank operator"); | |
233 | + return true; | |
234 | + } | |
235 | + else if (c == ';') { | |
236 | + Serial.println("Message:blank operator"); | |
237 | + return true; | |
238 | + } | |
239 | + else { | |
240 | + readUntil('\n', ';', '\\'); | |
241 | + Serial.print("Warning:unknown operator: "); | |
242 | + Serial.print((char) c); | |
243 | + Serial.println(""); | |
244 | + return false; | |
245 | + } | |
246 | + | |
247 | + return false; | |
248 | +} |
@@ -0,0 +1,71 @@ | ||
1 | +#ifndef INCLUDE_AcsSerialReader_h | |
2 | +#define INCLUDE_AcsSerialReader_h | |
3 | + | |
4 | +#define ACS_SERIAL_READER_ARGUMENTS_INT_MAX_LENGTH 100 | |
5 | +#define ACS_SERIAL_READER_ARGUMENTS_DOUBLE_MAX_LENGTH 10 | |
6 | +#define ACS_SERIAL_READER_ARGUMENTS_STRING_MAX_LENGTH 4 | |
7 | +#define ACS_SERIAL_READER_ARGUMENT_STRING_MAX_LENGTH 100 | |
8 | +#define 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 | +// "R\n" シリアルから受け取った文字数の初期化 | |
16 | +// "M\n" コマンドの実行(コマンド名のために通常文字列引数が1個必要) | |
17 | +// | |
18 | +// readOneOperationをすると、Serialから一行分の命令を読み込んで実行する。 | |
19 | +// 命令の区切り文字は\nのほかに;も可能 | |
20 | +class AcsSerialReader { | |
21 | +public: | |
22 | + | |
23 | + int argumentsInt[ACS_SERIAL_READER_ARGUMENTS_INT_MAX_LENGTH]; | |
24 | + int argumentsIntLength; | |
25 | + | |
26 | + double argumentsDouble[ACS_SERIAL_READER_ARGUMENTS_DOUBLE_MAX_LENGTH]; | |
27 | + int argumentsDoubleLength; | |
28 | + | |
29 | + char argumentsString | |
30 | + [ACS_SERIAL_READER_ARGUMENTS_STRING_MAX_LENGTH] | |
31 | + [ACS_SERIAL_READER_ARGUMENT_STRING_MAX_LENGTH]; | |
32 | + int argumentsStringLength; | |
33 | + | |
34 | + AcsSerialReader(); | |
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[ACS_SERIAL_READER_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 AcsSerialReader_invokeCommand(AcsSerialReader* acsSerialReader); | |
70 | + | |
71 | +#endif |
@@ -0,0 +1,80 @@ | ||
1 | +// @MiconBoardType 'Arduino Mega 2560 or Mega ADK' | |
2 | +// @LibraryRequired 'SPI' | |
3 | +// @LibraryRequired 'AcsSerialFramework' | |
4 | + | |
5 | +#include <SPI.h> | |
6 | +#include <AcsSerialFramework.h> | |
7 | + | |
8 | +void setup() | |
9 | +{ | |
10 | + AcsSerialFramework::setup(); | |
11 | + | |
12 | + sendMessage(">>>>> initialized"); | |
13 | +} | |
14 | + | |
15 | +void loop() | |
16 | +{ | |
17 | + AcsSerialFramework::loop(); | |
18 | +} | |
19 | + | |
20 | +///////////////////////////////////////////////////////////// | |
21 | + | |
22 | +void tick() | |
23 | +{ | |
24 | + delay(100); | |
25 | +} | |
26 | + | |
27 | +void onUnknownCommand(AcsSerialReader* acsSerialReader) | |
28 | +{ | |
29 | + | |
30 | ||
31 | + sendMessageBlockBegin(); | |
32 | + Serial.print("Unknown Command: "); | |
33 | + Serial.println(acsSerialReader->argumentsString[0]); | |
34 | + for (int i = 0; i < acsSerialReader->argumentsIntLength; i++) { | |
35 | + Serial.print(" Int: "); | |
36 | + Serial.println(acsSerialReader->argumentsInt[i]); | |
37 | + } | |
38 | + for (int i = 0; i < acsSerialReader->argumentsDoubleLength; i++) { | |
39 | + Serial.print(" Double: "); | |
40 | + Serial.println(acsSerialReader->argumentsDouble[i]); | |
41 | + } | |
42 | + for (int i = 0; i < acsSerialReader->argumentsStringLength; i++) { | |
43 | + Serial.print(" String: "); | |
44 | + Serial.println(acsSerialReader->argumentsString[i]); | |
45 | + } | |
46 | + sendMessageBlockEnd(); | |
47 | + | |
48 | +} | |
49 | + | |
50 | +int sampleValue; | |
51 | + | |
52 | +void AcsSerialReader_invokeCommand(AcsSerialReader* acsSerialReader) | |
53 | +{ | |
54 | + if (strcmp(acsSerialReader->argumentsString[0], "SetSampleValue") == 0) { | |
55 | + | |
56 | + // 操作 | |
57 | + sampleValue = acsSerialReader->argumentsInt[0]; | |
58 | + | |
59 | ||
60 | + sendMessageBlockBegin(); | |
61 | + Serial.println("Set Sample Value"); | |
62 | + sendMessageBlockEnd(); | |
63 | + | |
64 | + return; | |
65 | + } | |
66 | + if (strcmp(acsSerialReader->argumentsString[0], "GetSampleValue") == 0) { | |
67 | + | |
68 | + // 操作 | |
69 | + | |
70 | ||
71 | + sendMessageBlockBegin(); | |
72 | + Serial.println(sampleValue); | |
73 | + sendMessageBlockEnd(); | |
74 | + | |
75 | + return; | |
76 | + } | |
77 | + | |
78 | + onUnknownCommand(acsSerialReader); | |
79 | +} | |
80 | + |
@@ -0,0 +1,30 @@ | ||
1 | +■サンプルコマンド文 | |
2 | + | |
3 | +R; | |
4 | +C;SGetSampleValue;M; | |
5 | +C;SSetSampleValue;I400;M; | |
6 | +C;SGetSampleValue;M; | |
7 | + | |
8 | +■命令 | |
9 | + | |
10 | +命令は種類をあらわす1文字で始まって区切り文字で終わる。 | |
11 | + | |
12 | +命令区切り文字: ';', '\n' | |
13 | +命令種類: | |
14 | + 'R': シリアルリーダーコンポーネントの内部変数の初期化 | |
15 | + 通信の確立時に行う。 | |
16 | + 'C': 与えた引数の初期化 | |
17 | + 'I': 整数型引数のpush 最大100個 | |
18 | + 'D': 浮動小数型引数のpush 最大10個 | |
19 | + 'S': 文字列型引数のpush(区切り文字を含めるには、エスケープが必要) | |
20 | + '\\'ですべての文字はエスケープ可能。 | |
21 | + 最大4個、99文字 | |
22 | + 'M': コマンドの実行(引数は自動で'C'されない) | |
23 | + | |
24 | +※このコンポーネントではコマンド実行命令'M'のコマンド名は | |
25 | + 考慮されないので、最初に与えた文字列型引数をコマンド名とするのがよい。 | |
26 | +※区切り文字は連続して挿入すると無視される。 | |
27 | +※Arduinoの都合上の問題で、一度に受信バッファに64バイトまでしか格納しておけない。 | |
28 | + そのために、シリアルで20文字受け取るごとに'R'命令を受けてからこれまでに | |
29 | + 受け取った文字の総数を送るので、それを受け取ってからバッファを越えないように | |
30 | + 送信する必要がある。 |