Skip to content

Commit 5fa1294

Browse files
committed
Readme.
1 parent 1acdd97 commit 5fa1294

File tree

1 file changed

+21
-298
lines changed

1 file changed

+21
-298
lines changed

README.md

Lines changed: 21 additions & 298 deletions
Original file line numberDiff line numberDiff line change
@@ -1,315 +1,38 @@
1-
# Commander API
2-
**Version V0.2A**
1+
@mainpage Commander-API library
2+
**Version V2.0.0**
33

4-
Commander-API is a simple to use interpreter library and you can easily use it to process character based commands and link them to a specified function. It is designed mainly to work with low memory capacity devices, for example, __small ARM or AVR devices or some embedded stuff__. The library shows an Arduino implementation and it can be found in the Arduino folder in the repository. The source files are located in the src folder.
4+
Commander-API is a simple to use parser library and you can easily use it to process character based commands and link them to a specified function. It is designed mainly to work with low memory capacity devices, for example, __small ARM or AVR processors__.
55

6-
# Doxygen documentation
6+
## Changes in V2
77

8-
The project has a Doxygen generated documentation. It can be found in Doc/html/index.html.
9-
The theme that used with the documentation can be found [here](https://jothepro.github.io/doxygen-awesome-css/)
8+
Version 2.X is a more refined version of the original Commander-API. The original was working well, but it was a bit flimsy when you had to work with a huge API list.
9+
It halso caused Hardfault when the API tree was not created correctly. Besides that if you wanted to add a new command, you had to change the header and the source
10+
file as well. The biggest problem was, that it was a C-API, so no overloading, no C++ magic.
1011

11-
# Arduino installation
12-
13-
__1.__
14-
15-
Download this library as a .zip, or clone it.
16-
17-
__2.__
18-
19-
Create a new sketch in Arduino IDE and open its folder.
20-
21-
__3.__
22-
23-
![](https://github.com/dani007200964/Commander-API/blob/master/Doc/images/arduino_install_lib_install.png)
24-
Now copy interpreter.c and interpreter.h files from src folder in this repository, to your sketch folder.
25-
26-
__4.__
27-
28-
Because Arduino uses C++ not C, you have to rename the interpreter.c file to interpreter.cpp,
29-
and the interpreter.h file to interpreter.hpp. My recommendation is to use a text editor for
30-
this step like [Atom](https://atom.io/) or [Notepad++](https://notepad-plus-plus.org/downloads/).
31-
32-
__5.__
33-
34-
If Arduino IDE is opened __save all your work,__ then restart Arduino IDE.
35-
36-
__6.__
37-
38-
![](https://github.com/dani007200964/Commander-API/blob/master/Doc/images/arduino_install_success.png)
39-
Now you should see the interpreter.cpp and interpreter.hpp files on the top bar.
40-
Than you just include interpreter.hpp as usual.
41-
42-
Congratulations you successfully added the library to your sketch.
43-
44-
# Usage with Arduino
45-
46-
**Basic example**
47-
48-
__1.__
49-
50-
The first thing you have to do is to add the library files to your project.
51-
It is discussed in the Arduino installation page how to do.
52-
53-
__2.__
54-
55-
The next thing you have to do is to include the library at the beginning of your program.
56-
57-
Code:
58-
```
59-
#include "interpreter.hpp"
60-
```
61-
62-
__3.__
63-
64-
Now, you have to create at leas 3 commands, and add them to the interpreter. To do that, first you have to open
65-
the interpreter.cpp file. Locate the next comment:
66-
67-
```
68-
// +---- Create instruction data for the API ----+
69-
// | |
70-
// | This is where you have to add |
71-
// | your commands! |
72-
// | |
73-
// +-----------------------------------------------+
74-
```
75-
76-
By default in the code, there are 4 commands created as an example, below this comment.
77-
78-
```
79-
create_command_data(stop, "This command can be used to stop something.\r\nargs:\td - generic number\r\n\tc - someting else");
80-
create_command_data(start, "This command can be used to start something.\r\nargs:\td - generic number\r\n\tc - someting else");
81-
create_command_data(left, "This command can be used to make someting turn left.\r\nargs:\td - generic number\r\n\tc - someting else");
82-
create_command_data(right, "This command can be used to make someting turn right.\r\nargs:\td - generic number\r\n\tc - someting else");
83-
```
84-
85-
You can modify these of course. How you can create a new one is shown in the next step.
86-
87-
__4.__
88-
89-
If you want to create a new command, firstly you have to create its data. To do that you have to use create_command_data macro.
90-
The syntax is:
91-
92-
```
93-
create_command_data( name_of_the_command, description_of_this_command );
94-
```
95-
96-
Example:
97-
```
98-
create_command_data( reset, "description of reset command" );
99-
```
100-
101-
__Note that the name of the command should not have " characters before and after like a regular string!__
102-
The name also can't start with a number, and you can't use any special characters in it like: ?!,:-...etc..
103-
104-
__5.__
105-
106-
In step 3, and 4 you only created the data for the commands. In this step you have to add these data to the interpreter.
107-
To do that you have to find the following text int the implementation of init_interpreter function:
108-
109-
```
110-
// +---- Match instruction to it's function ----+
111-
// | |
112-
// | This is where you have to match |
113-
// | every instruction name to it's |
114-
// | function. |
115-
// | |
116-
// +-----------------------------------------------+
117-
```
118-
119-
By default in the code, there are 4 commands added as an example, below this comment.
120-
121-
```
122-
add_command(stop, stop_func);
123-
add_command(start, start_func);
124-
add_command(left, left_func);
125-
add_command(right, right_func);
126-
```
127-
128-
You can modify these of course. How you can create a new one is shown in the next step.
129-
130-
__6.__
131-
132-
To add the created data to the interpreter you have to use add_command macro.
133-
The syntax is:
134-
```
135-
add_command( name_of_the_command, function_for_this_command );
136-
```
137-
138-
Example:
139-
```
140-
add_command( reset, reset_func );
141-
```
142-
143-
__Not that the name of the command has to match exactly with the name in step 3 and 4!__
144-
145-
__7.__
146-
147-
Now you have to create the function that will be executed when the command arrives to the interpreter.
148-
The name of this function has to be exactly the same as the function name( 2nd argument ) in step 5, and 6.
149-
150-
Example:
151-
```
152-
// This is an example function for the reset command
153-
void reset_func(char *args, int(*resp_fn)(const char*, ...))
154-
{
155-
156-
int test_arg1;
157-
int test_arg2;
158-
int arg_read_result;
159-
160-
Serial.println( "Reset function called" );
161-
162-
// Do the actual code somewhere here.
163-
164-
// If you want to use the response channel,
165-
// This is how to do it correctly.
166-
// Always check the response function channel!
167-
// If it's a NULL pointer you can't use it,
168-
// because it will crash your porgram!
169-
if( resp_fn != NULL ){
170-
171-
resp_fn( "Wow! Magic!!!!\r\n" );
172-
173-
}
174-
175-
// If you have arguments you have to process it like a sscanf
176-
arg_read_result = sscanf( args, "%d %d", test_arg1, test_arg2 );
177-
178-
// You should check that if the argument read was successfully
179-
// sscanf should return exactly the same number as how many arguments
180-
// you have added.
181-
if( arg_read_result == 2 ){
182-
183-
// Arguments processed, no error.
184-
185-
}
186-
187-
else{
188-
189-
// Some of the arguments has an error.
190-
// Maybe a Type-O.
191-
192-
}
193-
194-
}
195-
```
196-
197-
The example above is quite complex, but it shows all of the futures that a command function has.
198-
You don't have to use all of it if you doesn't need that specific function.
199-
The only restriction is that the function type has to be the same.
200-
201-
You can write these functions driectly in interpreter.cpp file, or you can create a header and
202-
an implementation file for your command functions and include that in interpreter.hpp.
203-
204-
Example:
205-
```
206-
void name_of_the_function(char *args, int(*resp_fn)(const char*, ...));
207-
```
208-
209-
I know that it is not pretty, but in practice you just copy and rename it.
210-
211-
__8.__
212-
213-
The next thing is to count how many commands you have. __This number has to be exact!__
214-
You have to open interpreter.hpp file, then search for the NUM_OF_API_FUNCS definition.
215-
Give this macro the correct number of commands.
216-
217-
__9.__
218-
219-
The library has an option called ARDUINO_PLATFORM in interpreter.hpp. If you use
220-
Arduino IDE you have to uncomment this define.
221-
222-
__10.__
223-
224-
Now the basic configuration of the library is finished, so you just have to use it in your code.
225-
The interpreter has to be initialized. To initialise the interpreter the safest practise is,
226-
to initialise it as soon as possible. The reason for this is because the library uses some recursive
227-
functions to build a binary tree from the commands. It needs a relatively high amount of stack
228-
compared a simple initialisation function. After the initialisation this stack memory will be
229-
freed up. In Arduino environment basically you have to init Serial first, then,
230-
init the interpreter in the beginning of the setup function.
231-
232-
Code:
233-
```
234-
init_interpreter();
235-
```
236-
237-
__10.__
238-
239-
Now you just have to use the execute function every time you want to execute a command.
240-
The 3 examples in the Arduino folder in the repository shows 3 detailed example to use
241-
and understand this library.
242-
243-
__Congratulations, you have made your first project with Commander API :)__
244-
245-
# The importance of response function
246-
247-
![](https://github.com/dani007200964/Commander-API/blob/master/Doc/images/response_function_explained_01.png)
248-
249-
Imagine a system that has a various number of channels to communicate with.
250-
For example a Linux system, which has its shell redirected to SSH, Serial, GUI...
251-
If a command arrives in one of the supported channels, you want to generate
252-
the response to that channel. For example if a command arrives from Serial,
253-
you want to generate the answer and the messages from the command to Serial as well,
254-
not to any other channels. This is why response function is used.
255-
The Commander API handles everything you just have to create a valid response
256-
function to it. The advanced demo shows how to add a response function correctly.
257-
If you don't use a response function, please use NULL as argument. In this case the
258-
error messages will be redirected to INTERPRETER_PRINTF definition.
259-
260-
# Print the description
261-
262-
![](https://github.com/dani007200964/Commander-API/blob/master/Doc/images/description_example.png)
263-
264-
To print the description you just have to add a question mark to the end of the command.
265-
266-
# When and how to use a buffer?
267-
268-
Commander API designed to work mainly on embedded devices. In these devices usually you work
269-
from RAM. If you work from RAM you have an option to modify the contant of the command that
270-
has given to the execute function. There are two cases when you __MUST__ have to use a buffer:
271-
272-
__1.__ When you want to use the execute function with constant data. In this case the Commander
273-
API will try to overwrite this data, while executing the command. Why is it work like this is
274-
explained in the source file. In this case it will cause Hard Fault, because the software will
275-
try to modify the content of the FLASH( or program ) memory. This is restricted.
276-
277-
__2.__ When you don't want to modify the data. In my opinion it is very rare. In most cases
278-
you just collect the command string until a terminator character and pass it to the interpreter.
279-
If you need the command string after the execute function use a buffer.
280-
281-
How to setup buffered mode:
282-
283-
__1.__
284-
285-
Open interpreter.hpp and find INTERPRETER_BUFFER_SIZE definition.
286-
287-
__2.__
288-
289-
If it is commented, uncomment it.
290-
You have to decide how large buffer you need. If it is too large than you will waste RAM.
291-
If it is too short, than you can't interpret large commands correctly.
292-
293-
If you __does not need a buffer__, than you __MUST uncomment__ INTERPRETER_BUFFER_SIZE!
294-
295-
# Arduino printf function
296-
297-
The arduino_printf function is implemented by compatibility reasons. Commander API requires
298-
a printf like function as a communication channel. This function acts like a printf function,
299-
but it is redirected to serial. If you need more channels like TCP
300-
or bluetooth you have to implement a printf like functions for those channels as well.
12+
The new version is designed from ground up and the main motivation was to make it as reliable as the original, but make it much simpler to use.
30113

14+
__Key changes:__
15+
* Full C++ API
16+
* Arduino compatible without any modifications
17+
* Platform-IO compatibility( still in progress )
18+
* Simpler usage
19+
* Better example
20+
* Low memory consumption to make it compatible with lower end devices like Arduino UNO, Nano...
21+
* Response function overload. Thanks to C++ the response function can be anything like Serial, WiFiClient...
30222

30323
## Contributing
30424
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
30525

30626
Please make sure to update tests as appropriate.
30727

30828
## Donation
309-
If this project help you reduce time to develop, you can give me a cup of coffee :)
29+
If this project help you reduce time to develop, you can give me a cup of coffee :coffee: :coffee: :coffee:
31030

31131
[![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.com/donate?hosted_button_id=YFGZD78H6K2CS)
31232

31333
## License & copyright
31434
© Daniel Hajnal
315-
Licensed under the MIT License
35+
36+
37+
38+
Licensed under the MIT License

0 commit comments

Comments
 (0)