1
+ #include " SerialCommands.h"
2
+
3
+ Stream *SerialCommands::_serial;
4
+
5
+ SerialCommands::SerialCommands () : SerialCommands(&Serial) {}
6
+
7
+ SerialCommands::SerialCommands (Stream *stream)
8
+ {
9
+ _buffer = new uint8_t [_bufferSize];
10
+ init (stream);
11
+ addInternalCommand (0 , &SerialCommands::setAddressLength);
12
+ addInternalCommand (1 , &SerialCommands::setAddressFactor);
13
+ addInternalCommand (2 , &SerialCommands::internalCommand2);
14
+ addInternalCommand (3 , &SerialCommands::internalCommand3);
15
+ addInternalCommand (4 , &SerialCommands::internalCommand4);
16
+ addInternalCommand (5 , &SerialCommands::internalCommand5);
17
+ addInternalCommand (6 , &SerialCommands::internalCommand6);
18
+ addInternalCommand (7 , &SerialCommands::internalCommand7);
19
+ addInternalCommand (8 , &SerialCommands::setLog);
20
+ addInternalCommand (9 , &SerialCommands::getStatus);
21
+ }
22
+
23
+ void SerialCommands::init (Stream *serial)
24
+ {
25
+ _serial = serial;
26
+ }
27
+
28
+ void SerialCommands::begin (unsigned long baudrate)
29
+ {
30
+ Serial.begin (baudrate);
31
+ }
32
+
33
+ void SerialCommands::setCommand (CommandRecieved command)
34
+ {
35
+ _command = command;
36
+ }
37
+
38
+ void SerialCommands::addCommand (int commandAddress, CommandRecieved func)
39
+ {
40
+ if (commandAddress >= _numberOfCommands)
41
+ {
42
+ int newSize = commandAddress + 5 ;
43
+ CommandRecieved *newCommands = new CommandRecieved[newSize];
44
+
45
+ // Fill everything with nullptr
46
+ for (int i=0 ;i<newSize;i++)
47
+ {
48
+ newCommands[i]=nullptr ;
49
+ }
50
+
51
+ for (int i = 0 ; i < _numberOfCommands; i++)
52
+ {
53
+ if (_commands[i] != nullptr )
54
+ {
55
+ // Serial.println("cmd "+String(i)+" = "+String( _commands[i]!=nullptr));
56
+ newCommands[i] = _commands[i];
57
+ }
58
+ }
59
+ delete[] _commands;
60
+ _commands = newCommands;
61
+ _numberOfCommands = newSize;
62
+ }
63
+ _commands[commandAddress] = func;
64
+ }
65
+
66
+ void SerialCommands::onError (OnErrorHandler handler)
67
+ {
68
+ _onErrorPointer=handler;
69
+ }
70
+
71
+ void SerialCommands::readOne ()
72
+ {
73
+ int c;
74
+ if (_serial and _serial->available () and _serial->peek () >= 0 )
75
+ {
76
+ c = _serial->read ();
77
+ log (String ( c));
78
+
79
+ if (c == _startBit)
80
+ {
81
+ log (" Clearing buffer" );
82
+ clearBuffer ();
83
+ }
84
+ else if (c == _stopBit)
85
+ {
86
+ log (" Stopbit received" );
87
+ if (_messageSize == _bufferIndex)
88
+ {
89
+ processCommand (_buffer);
90
+ }
91
+ else
92
+ {
93
+ raiseError (" Message size \" " + String (_messageSize) + " \" is not equal to the buffersize: " + String (_bufferIndex), 0 , NULL , 0 );
94
+ }
95
+ }
96
+ else
97
+ {
98
+ if (_messageSize == 0 )
99
+ {
100
+ log (" Message size: " +String (c));
101
+ _messageSize = c;
102
+ }
103
+ else
104
+ {
105
+ addToBuffer (c);
106
+ }
107
+ }
108
+ }
109
+ }
110
+
111
+ void SerialCommands::write (int commandAddress, uint8_t *data, int size)
112
+ {
113
+ log (" Writing command " +String (commandAddress));
114
+
115
+ int messageLength = _addressLength + size;
116
+ int totalMessageLength = messageLength + 3 ; // start byte, length byte & stop byte
117
+ uint8_t message[totalMessageLength];
118
+
119
+ int index = 0 ;
120
+ message[index++] = _startBit;
121
+ message[index++] = messageLength;
122
+
123
+ int internalAddress = commandAddress;
124
+ int addressIndex = _addressLength + index - 1 ;
125
+ for (int i = 0 ; i < _addressLength; i++)
126
+ {
127
+ log (String (addressIndex) + " : " + String (internalAddress % _addressFactor));
128
+ message[addressIndex--] = internalAddress % _addressFactor;
129
+ internalAddress /= _addressFactor;
130
+ index++;
131
+ }
132
+
133
+ for (int i = 0 ; i < size; i++)
134
+ {
135
+ message[index++] = data[i];
136
+ }
137
+
138
+ message[index++] = _stopBit;
139
+
140
+ log (toHexString (message, index, " " ));
141
+ _serial->write (message, index);
142
+ }
143
+
144
+ void SerialCommands::setLog (bool log)
145
+ {
146
+ _log = log;
147
+ }
148
+
149
+ // / @brief The default address length is 1. This supports adresses up to 200.
150
+ // / @brief For higher addresses, the overflow will go to a second address byte.
151
+ // / @brief For example 314, for this the address to be used, the address lenght must be at least 2
152
+ // / @brief and the address bytes will be -> 1 (x 200) + 114
153
+ // / @param value
154
+ void SerialCommands::setAddressLenght (int value)
155
+ {
156
+ _addressLength = value;
157
+ }
158
+
159
+ void SerialCommands::processCommand (uint8_t *data)
160
+ {
161
+ log (" Processing command" );
162
+
163
+ int address = 0 ;
164
+ log (" AddressLenght: " + String (_addressLength));
165
+ for (int i = 0 ; i < _addressLength; i++)
166
+ {
167
+ address += data[i] * pow (_addressFactor, _addressLength - 1 - i);
168
+ }
169
+
170
+ log (" Address: " + String (address));
171
+
172
+ int messageSize = _messageSize - _addressLength;
173
+ uint8_t *newBuffer = new uint8_t [messageSize];
174
+
175
+ log (" Message buffer size: " + String (messageSize));
176
+
177
+ for (int i = 0 ; i < messageSize; i++)
178
+ {
179
+ newBuffer[i] = data[i + _addressLength];
180
+ }
181
+
182
+ if (_command != NULL )
183
+ {
184
+ log (" Calling command." );
185
+ _command (address, newBuffer, messageSize);
186
+ log (" Command called." );
187
+ }
188
+
189
+ if (address < _numberOfCommands and _commands[address] != NULL )
190
+ {
191
+ log (" Calling command " + String (address) + " ." );
192
+ _commands[address](address, newBuffer, messageSize);
193
+ log (" Command " + String (address) + " called." );
194
+ }
195
+ else if (address < _numberOfInternalCommands and _internalCommands[address] != NULL )
196
+ {
197
+ log (" Calling internal command " + String (address) + " ." );
198
+ (this ->*_internalCommands[address])(address, newBuffer, messageSize);
199
+ log (" Internal command " + String (address) + " called." );
200
+ }
201
+
202
+ delete[] newBuffer;
203
+
204
+ clearBuffer ();
205
+ }
206
+
207
+ void SerialCommands::addToBuffer (int c)
208
+ {
209
+ log (" Add to buffer index " + String (_bufferIndex) + " : " + String (c));
210
+
211
+ if (_bufferIndex >= _bufferSize - 1 )
212
+ {
213
+ int newSize = _bufferSize * 2 ;
214
+ uint8_t *newBuffer = new uint8_t [newSize];
215
+ for (int i = 0 ; i < _bufferSize; i++)
216
+ {
217
+ newBuffer[i] = _buffer[i];
218
+ }
219
+ delete[] _buffer;
220
+ _buffer = newBuffer;
221
+ _bufferSize = newSize;
222
+ }
223
+
224
+ _buffer[_bufferIndex] = c;
225
+ _bufferIndex++;
226
+ }
227
+
228
+ void SerialCommands::clearBuffer ()
229
+ {
230
+ for (int i = 0 ; i < sizeof (_buffer); i++)
231
+ {
232
+ _buffer[i] = 0 ;
233
+ }
234
+ _messageSize = 0 ;
235
+ _bufferIndex = 0 ;
236
+ }
237
+
238
+ void SerialCommands::log (String str)
239
+ {
240
+ if (_log)
241
+ {
242
+ Serial.println (str);
243
+ }
244
+ }
245
+
246
+ String SerialCommands::toHexString (uint8_t byte)
247
+ {
248
+ return _hexChars[byte / 16 ] + _hexChars[byte % 16 ];
249
+ }
250
+
251
+ String SerialCommands::toHexString (uint8_t *data, int size, String delimitter)
252
+ {
253
+ String result = " " ;
254
+ for (int i = 0 ; i < size; i++)
255
+ {
256
+ result += toHexString (data[i]);
257
+ if (i < size - 1 )
258
+ {
259
+ result += delimitter;
260
+ }
261
+ }
262
+
263
+ return result;
264
+ }
265
+
266
+ int SerialCommands::pow (int value, unsigned int power)
267
+ {
268
+ if (power == 0 )
269
+ {
270
+ return 1 ;
271
+ }
272
+ for (int i = 1 ; i < power; i++)
273
+ {
274
+ value *= value;
275
+ }
276
+ return value;
277
+ }
278
+
279
+ void SerialCommands::raiseError (String message, int commandAddress, byte *data, int messageLenght)
280
+ {
281
+ log (message);
282
+ if (_onErrorPointer != NULL )
283
+ {
284
+ _onErrorPointer (message, commandAddress, data, messageLenght);
285
+ }
286
+ }
287
+
288
+ void SerialCommands::addInternalCommand (int commandAddress, void (SerialCommands::*func)(int , byte *, int ))
289
+ {
290
+ _internalCommands[commandAddress] = func;
291
+ _numberOfInternalCommands++;
292
+ }
293
+
294
+ void SerialCommands::setAddressLength (int commandAddress, byte *data, int messageLength)
295
+ {
296
+ if (messageLength > 0 )
297
+ {
298
+ int lenght = data[0 ];
299
+ if (lenght <= 0 )
300
+ {
301
+ lenght = 1 ;
302
+ }
303
+ _addressLength = lenght;
304
+ }
305
+ log (" AddressLength is now: " + String (_addressLength));
306
+ }
307
+
308
+ void SerialCommands::setLog (int commandAddress, byte *data, int messageLength)
309
+ {
310
+ _log = (messageLength > 0 and (data[0 ] == 0x01 ));
311
+ log (" Log is ON" );
312
+ }
313
+
314
+ void SerialCommands::setAddressFactor (int commandAddress, byte *data, int messageLength)
315
+ {
316
+ if (messageLength > 0 )
317
+ {
318
+ _addressFactor = data[0 ];
319
+ }
320
+ log (" Address factor is: " + String (_addressFactor));
321
+ }
322
+
323
+ void SerialCommands::internalCommand2 (int commandAddress, byte *data, int messageLength)
324
+ {
325
+ }
326
+
327
+ void SerialCommands::internalCommand3 (int commandAddress, byte *data, int messageLength)
328
+ {
329
+ }
330
+
331
+ void SerialCommands::internalCommand4 (int commandAddress, byte *data, int messageLength)
332
+ {
333
+ }
334
+
335
+ void SerialCommands::internalCommand5 (int commandAddress, byte *data, int messageLength)
336
+ {
337
+ }
338
+
339
+ void SerialCommands::internalCommand6 (int commandAddress, byte *data, int messageLength)
340
+ {
341
+ }
342
+
343
+ void SerialCommands::internalCommand7 (int commandAddress, byte *data, int messageLength)
344
+ {
345
+ }
346
+
347
+ // / @brief Get the status of all the internal parameters. The parts are separated by '|' (0x7C) and the fist byte is the address of the parameter.
348
+ // / @param commandAddress
349
+ // / @param data
350
+ // / @param messageLength
351
+ void SerialCommands::getStatus (int commandAddress, byte *data, int messageLength)
352
+ {
353
+ // 0x7C -> |
354
+ uint8_t statusData[] = {
355
+ 0x00 , _addressLength, 0x7C ,
356
+ 0x01 , _addressFactor, 0x7C ,
357
+ 0x01 , _log, 0x7C };
358
+
359
+ int statusMessageLenght = sizeof (statusData) / sizeof (statusData[0 ]);
360
+
361
+ log (" Status lenght: " + String (statusMessageLenght));
362
+
363
+ write (commandAddress, statusData, statusMessageLenght);
364
+ }
365
+
366
+ SerialCommands Cmd;
0 commit comments