-
Notifications
You must be signed in to change notification settings - Fork 99
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit bd993d4
Showing
5 changed files
with
369 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
An Arduino library to tokenize and parse commands received over a serial port. | ||
|
||
Initially documented here: http://awtfy.com/2011/05/23/a-minimal-arduino-library-for-processing-serial-commands/ | ||
|
||
An alternate version of this library is available as https://github.com/kroimon/Arduino-SerialCommand | ||
|
||
This version is the one on Github. | ||
|
||
|
||
/******************************************************************************* | ||
SerialCommand - An Arduino library to tokenize and parse commands received over | ||
a serial port. | ||
Copyright (C) 2011 Steven Cogswell <[email protected]> | ||
http://husks.wordpress.com | ||
|
||
Version 20110523B. | ||
|
||
Version History: | ||
May 11 2011 - Initial version | ||
May 13 2011 - Prevent overwriting bounds of SerialCommandCallback[] array in addCommand() | ||
defaultHandler() for non-matching commands | ||
Mar 2012 - Some const char * changes to make compiler happier about deprecated warnings. | ||
Arduino 1.0 compatibility (Arduino.h header) | ||
|
||
This library is free software; you can redistribute it and/or | ||
modify it under the terms of the GNU Lesser General Public | ||
License as published by the Free Software Foundation; either | ||
version 2.1 of the License, or (at your option) any later version. | ||
|
||
This library is distributed in the hope that it will be useful, | ||
but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
Lesser General Public License for more details. | ||
|
||
You should have received a copy of the GNU Lesser General Public | ||
License along with this library; if not, write to the Free Software | ||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
***********************************************************************************/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
/******************************************************************************* | ||
SerialCommand - An Arduino library to tokenize and parse commands received over | ||
a serial port. | ||
Copyright (C) 2011 Steven Cogswell <[email protected]> | ||
http://husks.wordpress.com | ||
Version 20110523B. | ||
See SerialCommand.h for version history. | ||
This library is free software; you can redistribute it and/or | ||
modify it under the terms of the GNU Lesser General Public | ||
License as published by the Free Software Foundation; either | ||
version 2.1 of the License, or (at your option) any later version. | ||
This library is distributed in the hope that it will be useful, | ||
but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
Lesser General Public License for more details. | ||
You should have received a copy of the GNU Lesser General Public | ||
License along with this library; if not, write to the Free Software | ||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
***********************************************************************************/ | ||
|
||
#if defined(ARDUINO) && ARDUINO >= 100 | ||
#include "Arduino.h" | ||
#else | ||
#include "WProgram.h" | ||
#endif | ||
|
||
#include <string.h> | ||
#include "SerialCommand.h" | ||
|
||
// Constructor makes sure some things are set. | ||
SerialCommand::SerialCommand() | ||
{ | ||
strncpy(delim," ",MAXDELIMETER); // strtok_r needs a null-terminated string | ||
term='\r'; // return character, default terminator for commands | ||
numCommand=0; // Number of callback handlers installed | ||
clearBuffer(); | ||
} | ||
|
||
// | ||
// Initialize the command buffer being processed to all null characters | ||
// | ||
void SerialCommand::clearBuffer() | ||
{ | ||
for (int i=0; i<SERIALCOMMANDBUFFER; i++) | ||
{ | ||
buffer[i]='\0'; | ||
} | ||
bufPos=0; | ||
} | ||
|
||
// Retrieve the next token ("word" or "argument") from the Command buffer. | ||
// returns a NULL if no more tokens exist. | ||
char *SerialCommand::next() | ||
{ | ||
char *nextToken; | ||
nextToken = strtok_r(NULL, delim, &last); | ||
return nextToken; | ||
} | ||
|
||
// This checks the Serial stream for characters, and assembles them into a buffer. | ||
// When the terminator character (default '\r') is seen, it starts parsing the | ||
// buffer for a prefix command, and calls handlers setup by addCommand() member | ||
void SerialCommand::readSerial() | ||
{ | ||
while (Serial.available() > 0) | ||
{ | ||
int i; | ||
boolean matched; | ||
inChar=Serial.read(); // Read single available character, there may be more waiting | ||
#ifdef SERIALCOMMANDDEBUG | ||
Serial.print(inChar); // Echo back to serial stream | ||
#endif | ||
if (inChar==term) { // Check for the terminator (default '\r') meaning end of command | ||
#ifdef SERIALCOMMANDDEBUG | ||
Serial.print("Received: "); | ||
Serial.println(buffer); | ||
#endif | ||
bufPos=0; // Reset to start of buffer | ||
token = strtok_r(buffer,delim,&last); // Search for command at start of buffer | ||
if (token == NULL) return; | ||
matched=false; | ||
for (i=0; i<numCommand; i++) { | ||
#ifdef SERIALCOMMANDDEBUG | ||
Serial.print("Comparing ["); | ||
Serial.print(token); | ||
Serial.print("] to ["); | ||
Serial.print(CommandList[i].command); | ||
Serial.println("]"); | ||
#endif | ||
// Compare the found command against the list of known commands for a match | ||
if (strncmp(token,CommandList[i].command,SERIALCOMMANDBUFFER) == 0) | ||
{ | ||
#ifdef SERIALCOMMANDDEBUG | ||
Serial.print("Matched Command: "); | ||
Serial.println(token); | ||
#endif | ||
// Execute the stored handler function for the command | ||
(*CommandList[i].function)(); | ||
clearBuffer(); | ||
matched=true; | ||
break; | ||
} | ||
} | ||
if (matched==false) { | ||
(*defaultHandler)(); | ||
clearBuffer(); | ||
} | ||
|
||
} | ||
if (isprint(inChar)) // Only printable characters into the buffer | ||
{ | ||
buffer[bufPos++]=inChar; // Put character into buffer | ||
buffer[bufPos]='\0'; // Null terminate | ||
if (bufPos > SERIALCOMMANDBUFFER-1) bufPos=0; // wrap buffer around if full | ||
} | ||
} | ||
} | ||
|
||
// Adds a "command" and a handler function to the list of available commands. | ||
// This is used for matching a found token in the buffer, and gives the pointer | ||
// to the handler function to deal with it. | ||
void SerialCommand::addCommand(const char *command, void (*function)()) | ||
{ | ||
if (numCommand < MAXSERIALCOMMANDS) { | ||
#ifdef SERIALCOMMANDDEBUG | ||
Serial.print(numCommand); | ||
Serial.print("-"); | ||
Serial.print("Adding command for "); | ||
Serial.println(command); | ||
#endif | ||
|
||
strncpy(CommandList[numCommand].command,command,SERIALCOMMANDBUFFER); | ||
CommandList[numCommand].function = function; | ||
numCommand++; | ||
} else { | ||
// In this case, you tried to push more commands into the buffer than it is compiled to hold. | ||
// Not much we can do since there is no real visible error assertion, we just ignore adding | ||
// the command | ||
#ifdef SERIALCOMMANDDEBUG | ||
Serial.println("Too many handlers - recompile changing MAXSERIALCOMMANDS"); | ||
#endif | ||
} | ||
} | ||
|
||
// This sets up a handler to be called in the event that the receveived command string | ||
// isn't in the list of things with handlers. | ||
void SerialCommand::addDefaultHandler(void (*function)()) | ||
{ | ||
defaultHandler = function; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
/******************************************************************************* | ||
SerialCommand - An Arduino library to tokenize and parse commands received over | ||
a serial port. | ||
Copyright (C) 2011 Steven Cogswell <[email protected]> | ||
http://husks.wordpress.com | ||
Version 20110523B. | ||
Version History: | ||
May 11 2011 - Initial version | ||
May 13 2011 - Prevent overwriting bounds of SerialCommandCallback[] array in addCommand() | ||
defaultHandler() for non-matching commands | ||
Mar 2012 - Some const char * changes to make compiler happier about deprecated warnings. | ||
Arduino 1.0 compatibility (Arduino.h header) | ||
This library is free software; you can redistribute it and/or | ||
modify it under the terms of the GNU Lesser General Public | ||
License as published by the Free Software Foundation; either | ||
version 2.1 of the License, or (at your option) any later version. | ||
This library is distributed in the hope that it will be useful, | ||
but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
Lesser General Public License for more details. | ||
You should have received a copy of the GNU Lesser General Public | ||
License along with this library; if not, write to the Free Software | ||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
***********************************************************************************/ | ||
#ifndef SerialCommand_h | ||
#define SerialCommand_h | ||
|
||
#if defined(ARDUINO) && ARDUINO >= 100 | ||
#include "Arduino.h" | ||
#else | ||
#include "WProgram.h" | ||
#endif | ||
|
||
#include <string.h> | ||
|
||
#define SERIALCOMMANDBUFFER 16 | ||
#define MAXSERIALCOMMANDS 10 | ||
#define MAXDELIMETER 2 | ||
|
||
#define SERIALCOMMANDDEBUG 1 | ||
#undef SERIALCOMMANDDEBUG // Comment this out to run the library in debug mode (verbose messages) | ||
|
||
class SerialCommand | ||
{ | ||
public: | ||
SerialCommand(); // Constructor | ||
void clearBuffer(); // Sets the command buffer to all '\0' (nulls) | ||
char *next(); // returns pointer to next token found in command buffer (for getting arguments to commands) | ||
void readSerial(); // Main entry point. | ||
void addCommand(const char *, void(*)()); // Add commands to processing dictionary | ||
void addDefaultHandler(void (*function)()); // A handler to call when no valid command received. | ||
|
||
private: | ||
char inChar; // A character read from the serial stream | ||
char buffer[SERIALCOMMANDBUFFER]; // Buffer of stored characters while waiting for terminator character | ||
int bufPos; // Current position in the buffer | ||
char delim[MAXDELIMETER]; // null-terminated list of character to be used as delimeters for tokenizing (default " ") | ||
char term; // Character that signals end of command (default '\r') | ||
char *token; // Returned token from the command buffer as returned by strtok_r | ||
char *last; // State variable used by strtok_r during processing | ||
typedef struct _callback { | ||
char command[SERIALCOMMANDBUFFER]; | ||
void (*function)(); | ||
} SerialCommandCallback; // Data structure to hold Command/Handler function key-value pairs | ||
int numCommand; | ||
SerialCommandCallback CommandList[MAXSERIALCOMMANDS]; // Actual definition for command/handler array | ||
void (*defaultHandler)(); // Pointer to the default handler function | ||
}; | ||
|
||
#endif //SerialCommand_h |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
// Demo Code for SerialCommand Library | ||
// Steven Cogswell | ||
// May 2011 | ||
|
||
#include <SerialCommand.h> | ||
|
||
#define arduinoLED 13 // Arduino LED on board | ||
|
||
SerialCommand SCmd; // The demo SerialCommand object | ||
|
||
void setup() | ||
{ | ||
pinMode(arduinoLED,OUTPUT); // Configure the onboard LED for output | ||
digitalWrite(arduinoLED,LOW); // default to LED off | ||
|
||
Serial.begin(9600); | ||
|
||
// Setup callbacks for SerialCommand commands | ||
SCmd.addCommand("ON",LED_on); // Turns LED on | ||
SCmd.addCommand("OFF",LED_off); // Turns LED off | ||
SCmd.addCommand("HELLO",SayHello); // Echos the string argument back | ||
SCmd.addCommand("P",process_command); // Converts two arguments to integers and echos them back | ||
SCmd.addDefaultHandler(unrecognized); // Handler for command that isn't matched (says "What?") | ||
Serial.println("Ready"); | ||
|
||
} | ||
|
||
void loop() | ||
{ | ||
SCmd.readSerial(); // We don't do much, just process serial commands | ||
} | ||
|
||
|
||
void LED_on() | ||
{ | ||
Serial.println("LED on"); | ||
digitalWrite(arduinoLED,HIGH); | ||
} | ||
|
||
void LED_off() | ||
{ | ||
Serial.println("LED off"); | ||
digitalWrite(arduinoLED,LOW); | ||
} | ||
|
||
void SayHello() | ||
{ | ||
char *arg; | ||
arg = SCmd.next(); // Get the next argument from the SerialCommand object buffer | ||
if (arg != NULL) // As long as it existed, take it | ||
{ | ||
Serial.print("Hello "); | ||
Serial.println(arg); | ||
} | ||
else { | ||
Serial.println("Hello, whoever you are"); | ||
} | ||
} | ||
|
||
|
||
void process_command() | ||
{ | ||
int aNumber; | ||
char *arg; | ||
|
||
Serial.println("We're in process_command"); | ||
arg = SCmd.next(); | ||
if (arg != NULL) | ||
{ | ||
aNumber=atoi(arg); // Converts a char string to an integer | ||
Serial.print("First argument was: "); | ||
Serial.println(aNumber); | ||
} | ||
else { | ||
Serial.println("No arguments"); | ||
} | ||
|
||
arg = SCmd.next(); | ||
if (arg != NULL) | ||
{ | ||
aNumber=atol(arg); | ||
Serial.print("Second argument was: "); | ||
Serial.println(aNumber); | ||
} | ||
else { | ||
Serial.println("No second argument"); | ||
} | ||
|
||
} | ||
|
||
// This gets set as the default handler, and gets called when no other command matches. | ||
void unrecognized() | ||
{ | ||
Serial.println("What?"); | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
SerialCommand KEYWORD1 | ||
clearBuffer KEYWORD2 | ||
next KEYWORD2 | ||
readSerial KEYWORD2 | ||
addCommand KEYWORd2 |