Created
January 7, 2018 09:04
-
-
Save Gydo194/4e1b3c36654e9961486e0a633f12ea35 to your computer and use it in GitHub Desktop.
Arduino integrated command parser shell
This file contains hidden or 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
//enabling DEBUG will make handle() spit out the function name and argument to serial before calling it. | |
//total sketch size when compiled for arduino UNO: 7094 bytes | |
#define DEBUG false | |
#include <HashMap.h> | |
class ArgumentParser { | |
private: | |
String input = ""; | |
public: | |
void setInput(String i) { input = i; } | |
String getBuffer() { return input; } | |
void clearBuffer() { input = String(""); } | |
//get the next argument out of the buffer | |
String nextArgument() { | |
String ret = ""; | |
//check if there's comma's in the input buffer, if not -1 | |
int index = input.indexOf(','); | |
//if there are no commas, the last call will have returned -1. If so, clear the input buffer and return everything that was in there | |
if(index < 0) { | |
ret = input; //save initial input | |
input = ""; //clear global input var | |
return ret; //return initial input | |
} | |
//there are commas, so get the buffer until the first comma | |
ret = input.substring(0,index); | |
//cut off the beginning of the buffer, including the comma | |
input = input.substring(index + 1, input.length()); | |
//return the parsed argument | |
return ret; | |
} | |
//check whether there's more | |
bool hasNext() { | |
return input.length() > 0; | |
} | |
}; | |
class FunctionParser { | |
enum states { | |
FUNC,ARG | |
}; | |
private: | |
states state = FUNC; | |
void (*cb)(String,String); | |
String funcBuffer = ""; | |
String argBuffer = ""; | |
void clear_buffer() { | |
funcBuffer = ""; | |
argBuffer = ""; | |
} | |
void append(char i) { | |
switch(state) { | |
case FUNC: | |
funcBuffer.concat(i); | |
break; | |
case ARG: | |
argBuffer.concat(i); | |
break; | |
} | |
} | |
public: | |
void setCallBack(void(*c)(String,String)) { | |
cb = c; | |
} | |
String getFuncBuffer() { | |
return funcBuffer; | |
} | |
String getArgBuffer() { | |
return argBuffer; | |
} | |
//this function processes a char | |
void process(char in) { | |
switch(in) { | |
case '(': | |
state = ARG; | |
break; | |
case ')': | |
state = FUNC; | |
break; | |
case ';': | |
cb(funcBuffer,argBuffer); //call the CB/callback function | |
clear_buffer(); //cycle finished, clear buffer | |
break; | |
default: | |
append(in); | |
break; | |
} | |
} | |
}; | |
class Callable { | |
public: | |
void(*call)(String); | |
}; | |
//create hashmap and the parser | |
CreateHashMap(functions, String, Callable,4); //beware the fixed length | |
FunctionParser fp = FunctionParser(); | |
void handle(String func, String arg) { | |
#if DEBUG | |
Serial.print("handle(): func: '"); | |
Serial.print(func); | |
Serial.print("' arg: '"); | |
Serial.print(arg); | |
Serial.print("'.\n"); | |
#endif | |
//this function is callbacked by the Argument Parser. | |
//it will look the function name up in the HashMap, and call according functions | |
if(functions.contains(func)) functions[func].call(arg); | |
} | |
void registerFunction(String name, void c(String)) { | |
//beta | |
functions[name].call = c; | |
} | |
void setup() { | |
Serial.begin(9600); | |
fp.setCallBack(&handle); | |
//now bind functions | |
//functions["dump"].call = &dump; | |
registerFunction("dump",&dump); | |
registerFunction("test",&test); | |
registerFunction("aw",&aw); | |
Serial.println("Initialization Completed."); | |
} | |
void loop() { | |
while(Serial.available() > 0) { | |
fp.process(Serial.read()); | |
} | |
} | |
//user functions to bind | |
void dump(String arg) { | |
Serial.print("dump(): received '"); | |
Serial.print(arg); | |
Serial.print("'.\n"); | |
} | |
void test(String arg) { | |
ArgumentParser ap = ArgumentParser(); | |
ap.setInput(arg); | |
while(ap.hasNext()) { | |
Serial.print("test(): argument: '"); | |
Serial.print(ap.nextArgument()); | |
Serial.print("'.\n"); | |
} | |
} | |
void aw(String input) { | |
ArgumentParser ap = ArgumentParser(); | |
ap.setInput(input); | |
if(!ap.hasNext()) { | |
Serial.println("aw: analog write. Usage: aw(pin,value);"); | |
return; | |
} | |
int pin = atoi(ap.nextArgument().c_str()); | |
if(!ap.hasNext()) { | |
Serial.println("aw: analog write. Usage: aw(pin,value);"); | |
return; | |
} | |
int val = atoi(ap.nextArgument().c_str()); | |
analogWrite(pin,val); | |
Serial.print("aw(): setting pin '"); | |
Serial.print(pin); | |
Serial.print("' to val '"); | |
Serial.print(val); | |
Serial.print("'.\n"); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment