Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Non-verbose, floating point, list commands, force uppercase #7

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
60 changes: 39 additions & 21 deletions Cmd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 <avr/pgmspace.h>
Expand All @@ -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
Expand All @@ -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);
}

/**************************************************************************/
Expand All @@ -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;

Expand All @@ -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();
}
Expand All @@ -127,36 +129,41 @@ 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)
{
case '\r':
// 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;
}
Expand All @@ -170,7 +177,7 @@ void cmd_handler()
/**************************************************************************/
void cmdPoll()
{
while (Serial.available())
while (stream->available())
{
cmd_handler();
}
Expand All @@ -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));
Expand All @@ -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
Expand Down
8 changes: 5 additions & 3 deletions Cmd.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@

*******************************************************************/
/*!
\file
\file
\ingroup


Expand All @@ -43,6 +43,7 @@

#define MAX_MSG_SIZE 60
#include <stdint.h>
#include <Arduino.h>

// command line structure
typedef struct _cmd_t
Expand All @@ -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
12 changes: 0 additions & 12 deletions README

This file was deleted.

74 changes: 74 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -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.
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -34,5 +35,6 @@ void loop()
// That's it.
void hello(int arg_cnt, char **args)
{
Serial.println("Hello world.");
}
cmdGetStream()->println("Hello world.");
}

Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -49,11 +50,13 @@ void loop()
// Arg 9: yay
void arg_display(int arg_cnt, char **args)
{
Stream *s = cmdGetStream();

for (int i=0; i<arg_cnt; i++)
{
Serial.print("Arg ");
Serial.print(i);
Serial.print(": ");
Serial.println(args[i]);
s->print("Arg ");
s->print(i);
s->print(": ");
s->println(args[i]);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -82,4 +83,4 @@ void led_blink(int arg_cnt, char **args)
}
}


Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -66,4 +67,4 @@ void led_pwm(int arg_cnt, char **args)
// if no args, turn off the LED
analogWrite(pwm_pin, 0);
}
}
}
Loading