Hello Moteineers,
Attached is my library 'CMD_LINE'. It is something I have wanted since my second Arduino project.
We have all used something like:
void loop() {
cmd = Serial.read();
if (cmd != -1) //anything received?
{
if (cmd == 'w') //send ID info
{
Serial.println("ATU v.020307");
serInString[0] = -1;
}
if (cmd == 'g') //set tune cap, shunt inductor, and load cap
{
setAll(tuneGoto, indGoto, loadGoto);
serInString[0] = -1;
}
}
Have you ever wished you had a generic way to send a command with more than a single letter and maybe pass along some arguments? Well that's what this lib does. CMD_LINE does not rely on any other added libraries.
As an example, with CMD_LINE you can do the following:
By entering: r,1,"a,2,3,4,5",67,"b,8,9,0",100
CMD_LINE will parse it into:
arg[0] = r
arg[1] = 1
arg[3] = a,2,3,4,5
arg[4] = 67
arg[5] = b,8,9,0
arg[6] = 100
This allows you to use code like this in your Arduino sketches.
#include <CMD_LINE.h>
CMD_LINE my;
void setup()
{
Serial.begin(115200);
Serial.println("Enter A Command And It's Args [Ex. print all,100,"tOut,23,a",36,8,... ]");
}
void loop()
{
if (my.getSerialInput()) //check for an entry
{
Serial.print(" You Entered the Command: ");
Serial.println(my.arg[0]);
if (my.isCommand("test")){ // does arg[0] == "test" ?
int tst = atoi(my.arg[1]);
Serial.println(tst);
}
if (my.isCommand("print all"))
my.printArgs(argCnt);
if (my.isCommand("pi")){ // returns a float
float tst = atof(my.arg[1]);
Serial.println(tst,5);
}
if (my.isCommand("moStuff")){ // returns a float and an integer
float tst = atof(my.arg[1]);
int itst = atoi(my.arg[2]);
doStuff(tst, itst);
}
if (my.isNotCommand()){ // default
Serial.print(">>>>> ");
Serial.print(my.arg[0]);
Serial.println(" is Not Recognized");
}
}
}
I'm hoping you see the power in this, but you might be thinking "that's nice, but it would be nicer if it also processed rf rx Moteino commands". Well, friends, it slices, it dices...
I use it to process both serial and rx receive commands and it really makes life simple. You don't have to worry about sync'ing a sent command with a returned response.
One radio sends a command to another it decodes it and sends back its response whenever, then the first radio decodes that response using a simple 'if command' statement.
Example:
void loop() {
wdt_reset();
//=================== process any SERIAL input ==============================
if (my.getSerialInput()) //check for an entry
{
Serial.println(my.inStr);
if (my.isCommand('a')) //sl//
{
Serial.println("\nAFC Triggered");
AFC_on = true;
}
if(my.isCommand("getReg")) //gl// print radio reg contents
{
byte adr = strtol(my.arg[1], '\0', 0); //0 = inputs are dec(ie 21), hex(ie 0x0f)
byte data = radio.readReg(adr);
sprintf(cBuff, "0x%02X, 0x%02X", adr, data);
Serial.println(cBuff);
}
if(my.isCommand("setDCCOffset"))
{
dccOffsetFreq = strtol(my.arg[1], '\0', 10);
Serial.println(dccOffsetFreq);
}
if(my.isCommand("setEEPROM")) //sl// write to EEPROM
{
int adr = strtol(my.arg[1], '\0', 0); //0 = inputs are dec or hex
byte value = strtol(my.arg[2], '\0', 0);
EEPROM.write(adr, value);
}
}//end of serial commands
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//\/\/\/\/\/\/\/\/\/\/\/\/\/\ process any RADIO input /\/\/\/\/\/\/\/\/\/\/\/\/\/\
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
if(radio.rxDataAvailable())
{
toID = radio.SENDERID;
Serial.print('>'); // echo rx cmds to serial terminal
my.printBuffer((char*)radio.DATA, radio.DATALEN);
my.parse((char*)radio.DATA);
if(my.isCommand("resetMoteino"))
{
setup();
}
if(my.isCommand("getRadReg")) //grr// reply with radio reg data
{
byte adr = strtol(my.arg[1], '\0', 0);
byte data = radio.readReg(adr);
sprintf(cBuff, "rReg,0x%02X,0x%02X", adr, data);
radio.send(toID, cBuff, ACKNACK);
}
if (my.isCommand("op")) //sl// set Output PWR level
{
int pwr = atoi(my.arg[1]);
Serial.print("pwr set to: ");
Serial.println(my.arg[1]);
radio.setPowerLevel(atoi(my.arg[1]));
radio.printReg(REG_PALEVEL);
}
if(my.isCommand("NE")) // k12 = 0, k3 = 0 //srr//
{
digitalWrite(k12Pin, LOW);
digitalWrite(k3Pin, LOW);
radio.send(toID, "rPos,0", ACKNACK);
}
if(my.isNotCommand()) // default catch all
{
Serial.print(">>>> '");
Serial.print(my.arg[0]);
Serial.println("' cmd invalid");
// int cnt = strlen(my.arg[0]);
// Serial.println(cnt);
}
}//end of 'rxDataAvailable()'
I have built an 'rf macro' library of these "if(my.isCommand("xx"))" segments and just copy and paste the "rf macros" into my Moteino sketches to quickly add functionality.
Entering a keyboard serial command like tx, "power, 11" allows you to forward the serial command line arg[1] as the transmitted command power, 11 to a remote radio.
if (my.isCommand("tx"))
{
radio.send(toID, my.arg[1], ACKNACK); // sends 'power, 11'
Serial.println(my.arg[1]);
radio.blink(LED,3);
}
Then in the remote radio you have a segment like:
if(my.isCommand("power"))
{
... use arg[1] to set the power
}
Let me know what you think. I hope you can put it to good use!
john
I like the way you think. :o Thanks for sharing. This looks to do exactly what I want in my project in a nice easy way. Thanks, Mab
Cool. I had an application in mind that would need a library like this just this weekend.
Would it be possible to have the delimiter DEFINEable within the body of the main sketch? I want to replicate a legacy interface that used spaces rather than commas. Also, were you planning on putting this on github to make it more accessible than a link on a forum?
It should be pretty easy for you to modify the code to do that. The code simply searches for commas and replaces them with 0x00.
Yes, I have a bunch of stuff that will land out there.
I needed to share it here first because it is used in another sketch that has been requested.
Tks,
john
Quote from: DeKay on January 06, 2014, 10:54:08 PM
Cool. I had an application in mind that would need a library like this just this weekend.
Would it be possible to have the delimiter DEFINEable within the body of the main sketch? I want to replicate a legacy interface that used spaces rather than commas. Also, were you planning on putting this on github to make it more accessible than a link on a forum?
It is now on GitHub https://github.com/exothink/moteino/tree/master/libraries (https://github.com/exothink/moteino/tree/master/libraries).
john
Great idea and framework. Thanks for sharing.
Colin