diff --git a/Cmd.cpp b/Cmd.cpp index 4d4500e..6a97855 100755 --- a/Cmd.cpp +++ b/Cmd.cpp @@ -35,7 +35,7 @@ \file Cmd.c This implements a simple command line interface for the Arduino so that - its possible to execute individual functions within the sketch. + its possible to execute individual functions within the sketch. */ /**************************************************************************/ #include @@ -59,6 +59,8 @@ const char cmd_banner[] PROGMEM = "*************** CMD *******************"; const char cmd_prompt[] PROGMEM = "CMD >> "; const char cmd_unrecog[] PROGMEM = "CMD: Command not recognized."; +static Stream* stream; + /**************************************************************************/ /*! Generate the main command prompt @@ -68,13 +70,13 @@ void cmd_display() { char buf[50]; - Serial.println(); + stream->println(); strcpy_P(buf, cmd_banner); - Serial.println(buf); + stream->println(buf); strcpy_P(buf, cmd_prompt); - Serial.print(buf); + stream->print(buf); } /**************************************************************************/ @@ -100,7 +102,7 @@ void cmd_parse(char *cmd) { argv[++i] = strtok(NULL, " "); } while ((i < 30) && (argv[i] != NULL)); - + // save off the number of arguments for the particular command. argc = i; @@ -118,7 +120,7 @@ void cmd_parse(char *cmd) // command not recognized. print message and re-generate prompt. strcpy_P(buf, cmd_unrecog); - Serial.println(buf); + stream->println(buf); cmd_display(); } @@ -127,12 +129,12 @@ void cmd_parse(char *cmd) /*! This function processes the individual characters typed into the command prompt. It saves them off into the message buffer unless its a "backspace" - or "enter" key. + or "enter" key. */ /**************************************************************************/ void cmd_handler() { - char c = Serial.read(); + char c = stream->read(); switch (c) { @@ -140,23 +142,28 @@ void cmd_handler() // terminate the msg and reset the msg ptr. then send // it to the handler for processing. *msg_ptr = '\0'; - Serial.print("\r\n"); + stream->print("\r\n"); cmd_parse((char *)msg); msg_ptr = msg; break; - + + case '\n': + // ignore newline characters. they usually come in pairs + // with the \r characters we use for newline detection. + break; + case '\b': - // backspace - Serial.print(c); + // backspace + stream->print(c); if (msg_ptr > msg) { msg_ptr--; } break; - + default: // normal character entered. add it to the buffer - Serial.print(c); + stream->print(c); *msg_ptr++ = c; break; } @@ -170,7 +177,7 @@ void cmd_handler() /**************************************************************************/ void cmdPoll() { - while (Serial.available()) + while (stream->available()) { cmd_handler(); } @@ -179,28 +186,27 @@ void cmdPoll() /**************************************************************************/ /*! Initialize the command line interface. This sets the terminal speed and - and initializes things. + and initializes things. */ /**************************************************************************/ -void cmdInit(uint32_t speed) +void cmdInit(Stream *str) { + stream = str; // init the msg ptr msg_ptr = msg; // init the command table cmd_tbl_list = NULL; - // set the serial speed - Serial.begin(speed); } /**************************************************************************/ /*! Add a command to the command table. The commands should be added in - at the setup() portion of the sketch. + at the setup() portion of the sketch. */ /**************************************************************************/ -void cmdAdd(char *name, void (*func)(int argc, char **argv)) +void cmdAdd(const char *name, void (*func)(int argc, char **argv)) { // alloc memory for command struct cmd_tbl = (cmd_t *)malloc(sizeof(cmd_t)); @@ -221,6 +227,18 @@ void cmdAdd(char *name, void (*func)(int argc, char **argv)) cmd_tbl_list = cmd_tbl; } +/**************************************************************************/ +/*! + Get a pointer to the stream used by the interpreter. This allows + commands to use the same communication channel as the interpreter + without tracking it in the main program. +*/ +/**************************************************************************/ +Stream* cmdGetStream(void) +{ + return stream; +} + /**************************************************************************/ /*! Convert a string to a number. The base must be specified, ie: "32" is a diff --git a/Cmd.h b/Cmd.h index db509d9..296f28a 100755 --- a/Cmd.h +++ b/Cmd.h @@ -32,7 +32,7 @@ *******************************************************************/ /*! - \file + \file \ingroup @@ -43,6 +43,7 @@ #define MAX_MSG_SIZE 60 #include +#include // command line structure typedef struct _cmd_t @@ -52,9 +53,10 @@ typedef struct _cmd_t struct _cmd_t *next; } cmd_t; -void cmdInit(uint32_t speed); +void cmdInit(Stream *); void cmdPoll(); -void cmdAdd(char *name, void (*func)(int argc, char **argv)); +void cmdAdd(const char *name, void (*func)(int argc, char **argv)); +Stream* cmdGetStream(void); uint32_t cmdStr2Num(char *str, uint8_t base); #endif //CMD_H diff --git a/README b/README deleted file mode 100644 index 2e2a83c..0000000 --- a/README +++ /dev/null @@ -1,12 +0,0 @@ -## CmdArduino - -by Akiba at Freaklabs.org - -The Arduino Command Line Interface, aka CmdArduino, is a simple shell that can -be run on an Arduino. It's nothing fancy and its main purpose is to allow users -to easily call their functions on a running Arduino via a simple serial -terminal. It also allows users to pass in arguments from the command line into -the functions they wrote so they can easily toggle pins, set blinking speed, -set pwm duty cycles, or whatever else might need command line user input. Using -it is fairly simple and just requires unzipping the files into the -"Arduino/libraries" sub-directory in the Arduino program folder. diff --git a/README.md b/README.md new file mode 100644 index 0000000..fee5fb5 --- /dev/null +++ b/README.md @@ -0,0 +1,74 @@ +== CmdArduino + + +CmdArduino is a small library to parse commands from the Serial port +or anything else which implements the Stream API. It is based on the +original by Akiba at Freaklabs.org + +To use it create your command functions, then wire them up in your setup function. +All command functions must take `int arg_cnt, char ** args` as it's parameters +and return `void`. +Here's an example from a simple robot: + +``` +void left(int arg_cnt, char **args) { + LeftMotor->run(FORWARD); + delay(200); + LeftMotor->run(RELEASE); +} + +void right(int arg_cnt, char **args) { + RightMotor->run(FORWARD); + delay(200); + RightMotor->run(RELEASE); +} + +void setup() { + Serial.begin(9600); + cmdInit(&Serial); + cmdAdd('left',left); + cmdAdd('right',right); +} +``` + +Call `cmdInit` with a pointer to the stream you are using. Call `cmdAdd` +to attach a string command to the command function. Now you can type `left` +or `right` into your serial port to command the robot. The serial port +will be parsed using newline, `\n`, as the delimiter. The command name should +be the first item and any arguments after that. For example, to tell the robot +to turn left for three seconds, type in: + +``` +left 3000\n +``` + +Then the left function becomes + +``` +void left(int arg_cnt, char **args) { + int time = 200; + if(arg_cnt > 0) { + time = parseNum(args[0]); + } + LeftMotor->run(FORWARD); + delay(time); + LeftMotor->run(RELEASE); +} +``` + + + + + + + +== original readme + +The Arduino Command Line Interface, aka CmdArduino, is a simple shell that can +be run on an Arduino. It's nothing fancy and its main purpose is to allow users +to easily call their functions on a running Arduino via a simple serial +terminal. It also allows users to pass in arguments from the command line into +the functions they wrote so they can easily toggle pins, set blinking speed, +set pwm duty cycles, or whatever else might need command line user input. Using +it is fairly simple and just requires unzipping the files into the +"Arduino/libraries" sub-directory in the Arduino program folder. diff --git a/examples/cmd_line_ex1_hello/cmd_line_ex1_hello.pde b/examples/cmd_line_ex1_hello/cmd_line_ex1_hello.ino old mode 100755 new mode 100644 similarity index 91% rename from examples/cmd_line_ex1_hello/cmd_line_ex1_hello.pde rename to examples/cmd_line_ex1_hello/cmd_line_ex1_hello.ino index abae6b5..1f8c95e --- a/examples/cmd_line_ex1_hello/cmd_line_ex1_hello.pde +++ b/examples/cmd_line_ex1_hello/cmd_line_ex1_hello.ino @@ -9,7 +9,8 @@ to them. void setup() { // init the command line and set it for a speed of 57600 - cmdInit(57600); + Serial.begin(57600); + cmdInit(&Serial); // add the commands to the command table. These functions must // already exist in the sketch. See the functions below. @@ -34,5 +35,6 @@ void loop() // That's it. void hello(int arg_cnt, char **args) { - Serial.println("Hello world."); -} + cmdGetStream()->println("Hello world."); +} + diff --git a/examples/cmd_line_ex2_args/cmd_line_ex2_args.pde b/examples/cmd_line_ex2_args/cmd_line_ex2_args.ino old mode 100755 new mode 100644 similarity index 90% rename from examples/cmd_line_ex2_args/cmd_line_ex2_args.pde rename to examples/cmd_line_ex2_args/cmd_line_ex2_args.ino index d837348..f405b91 --- a/examples/cmd_line_ex2_args/cmd_line_ex2_args.pde +++ b/examples/cmd_line_ex2_args/cmd_line_ex2_args.ino @@ -9,7 +9,8 @@ to them. void setup() { // init the command line and set it for a speed of 57600 - cmdInit(57600); + Serial.begin(57600); + cmdInit(&Serial); // add the commands to the command table. These functions must // already exist in the sketch. See the functions below. @@ -49,11 +50,13 @@ void loop() // Arg 9: yay void arg_display(int arg_cnt, char **args) { + Stream *s = cmdGetStream(); + for (int i=0; iprint("Arg "); + s->print(i); + s->print(": "); + s->println(args[i]); } -} +} diff --git a/examples/cmd_line_ex3_led_blink/cmd_line_ex3_led_blink.pde b/examples/cmd_line_ex3_led_blink/cmd_line_ex3_led_blink.ino old mode 100755 new mode 100644 similarity index 98% rename from examples/cmd_line_ex3_led_blink/cmd_line_ex3_led_blink.pde rename to examples/cmd_line_ex3_led_blink/cmd_line_ex3_led_blink.ino index 38ec070..b341869 --- a/examples/cmd_line_ex3_led_blink/cmd_line_ex3_led_blink.pde +++ b/examples/cmd_line_ex3_led_blink/cmd_line_ex3_led_blink.ino @@ -16,7 +16,8 @@ void setup() pinMode(led_pin, OUTPUT); // init the command line and set it for a speed of 57600 - cmdInit(57600); + Serial.begin(57600); + cmdInit(&Serial); // add the commands to the command table. These functions must // already exist in the sketch. See the functions below. @@ -82,4 +83,4 @@ void led_blink(int arg_cnt, char **args) } } - + diff --git a/examples/cmd_line_ex4_pwm/cmd_line_ex4_pwm.pde b/examples/cmd_line_ex4_pwm/cmd_line_ex4_pwm.ino old mode 100755 new mode 100644 similarity index 95% rename from examples/cmd_line_ex4_pwm/cmd_line_ex4_pwm.pde rename to examples/cmd_line_ex4_pwm/cmd_line_ex4_pwm.ino index 1b09cb8..b988dd9 --- a/examples/cmd_line_ex4_pwm/cmd_line_ex4_pwm.pde +++ b/examples/cmd_line_ex4_pwm/cmd_line_ex4_pwm.ino @@ -10,11 +10,12 @@ int pwm_pin = 10; void setup() { - // set the led pin as an output. its part of the demo. + // set the PWM pin as an output. its part of the demo. pinMode(pwm_pin, OUTPUT); // init the command line and set it for a speed of 57600 - cmdInit(57600); + Serial.begin(57600); + cmdInit(&Serial); // add the commands to the command table. These functions must // already exist in the sketch. See the functions below. @@ -66,4 +67,4 @@ void led_pwm(int arg_cnt, char **args) // if no args, turn off the LED analogWrite(pwm_pin, 0); } -} +} diff --git a/examples/cmd_line_ex5_multi_functions/cmd_line_ex5_multi_functions.pde b/examples/cmd_line_ex5_multi_functions/cmd_line_ex5_multi_functions.ino old mode 100755 new mode 100644 similarity index 93% rename from examples/cmd_line_ex5_multi_functions/cmd_line_ex5_multi_functions.pde rename to examples/cmd_line_ex5_multi_functions/cmd_line_ex5_multi_functions.ino index 9dedf17..4eedd2a --- a/examples/cmd_line_ex5_multi_functions/cmd_line_ex5_multi_functions.pde +++ b/examples/cmd_line_ex5_multi_functions/cmd_line_ex5_multi_functions.ino @@ -18,7 +18,8 @@ void setup() pinMode(pwm_pin, OUTPUT); // init the command line and set it for a speed of 57600 - cmdInit(57600); + Serial.begin(57600); + cmdInit(&Serial); // add the commands to the command table. These functions must // already exist in the sketch. See the functions below. @@ -54,7 +55,7 @@ void loop() // hello void hello(int arg_cnt, char **args) { - Serial.println("Hello world."); + cmdGetStream()->println("Hello world."); } // Display the contents of the args string array. @@ -73,12 +74,13 @@ void hello(int arg_cnt, char **args) // Arg 6: baby void arg_display(int arg_cnt, char **args) { + Stream *s = cmdGetStream(); for (int i=0; iprint("Arg "); + s->print(i); + s->print(": "); + s->println(args[i]); } } @@ -133,4 +135,4 @@ void led_pwm(int arg_cnt, char **args) // if no args, turn off the LED analogWrite(pwm_pin, 0); } -} +}