Skip to content

Commit 7482b7d

Browse files
author
Stef Geysels
committed
Initial Commit
1 parent df1707b commit 7482b7d

File tree

6 files changed

+637
-0
lines changed

6 files changed

+637
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -396,3 +396,5 @@ FodyWeavers.xsd
396396

397397
# JetBrains Rider
398398
*.sln.iml
399+
400+
/Build

SerialCommands.cpp

Lines changed: 366 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,366 @@
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

Comments
 (0)