Go Down

Topic: A simple sketch to do I/O from commands on Arduino (Read 732 times) previous topic - next topic

polypagan

Oct 07, 2013, 04:29 pm Last Edit: Oct 07, 2013, 09:50 pm by polypagan Reason: 1
This is just a (two really) small sketch to translate serial commands into analog or digital input or output on Arduino.

Here's a link to my sketchbook on Dropbox https://www.dropbox.com/sh/ahsbcbtm3lp5fyu/LURmrpCYAG

There's an "ArduinoCommander1" and "ArduinoCommander2"  because I wrote it twice, using different methods.  Not much difference between the two.  I did it that way because it gave me a struggle.  The problem ultimately turned out to be that it takes a quite while (in Arduino time) to get all the characters (even in the short command strings) across the serial interface.  I wasn't seeing later arguments on the command line because they hadn't arrived yet!

I just threw in a delay() call.  I'm really not concerned with blocking in this sketch because there really isn't anything else going on to block.  I suppose (if you wanted to get fancy, the delay could be computed from the baudrate, but, again, no hurry).

I hope folks find this useful.  I've used it when I have a breadboard setup and just want to fiddle with inputs and outputs. The command format is detailed in the code and also in the usage printout.

Here's the part of the code I'm proudest of:

Code: [Select]
// return truth of "there's another (numeric) argument on this line"
int isArg() {
 char c;
 switch (c=Serial.peek()) {
   case ' ':
   case '\t': Serial.read();
              return isArg();  // recurse !
   case 0xd :
   case -1:   return 0;
   default: if(isdigit(c)) {
               return 1;
            } else { Serial << "isArg() saw " << _HEX(c) << endl; }  // for future improvements.
 }
}


If the argument sought weren't numeric, the code could be shortened by making the default: case simply return 1, since all the 'nothing there' cases have already been handled.

This is the first use of recursion I've found in years!

Comments, suggestions, questions are welcome.
There are 10 kinds of people in the world, those who understand binary, and those who don't.

int2str

I know you said you're proud of that piece of code, but I have a few concerns....

First off, I would avoid recursion on an embedded processor like the AVR as much as possible. With a limited stack and memory size, recursion can very quickly become a problem. This gets made even worse if you do recursion as a result of user input. Whenever a program takes external inputs, there is a risk of abuse. In this case, just passing a lot of spacces as an argument to a function would blow the stack.

Secondly, recursion is really not useful in this case. It looks to me like you're trying to skip past whitespace. I would just make a function that does just that using a loop, not recursion. Recursion is useful when a state is maintained and data has to be passed back (B-Tree searches, fibunachi sequences, etc.). Just to skip something, a simple while loop would do.

Maybe something like this would do:
Code: [Select]
int isArg()
{
    char c = Serial.peek();

    while (c == ' ' || c = '\t')
    {
        getch();
        c = Serial.peek();
    }

    return isDigit(c) ? 1 : 0;
}

polypagan

Excellent point, thanks!

Although I agree in theory, this little sketch is hardly mission-critical.  I'm just playing.  If it were to crash, reset would pull it out of the weeds with no harm done.

I wouldn't attempt recursion in the datalogger sketch I posted.  It's intended to run 24/7 unattended on my solar power system, and survive plugging and unplugging the USB cable.  I need for it to be pretty bulletproof.

And, after reading you remarks, I tried crashing it with lots of spaces.  Unless I maximize the little serial monitor window, there just isn't that much room on the command line to overflow the stack.

Yes, the RAM is quite limited, and this sketch uses very little of it.  (I'm not sure how much, honestly.  There's a way to determine this, but I forget what it is.)

Thanks again for your comments!
There are 10 kinds of people in the world, those who understand binary, and those who don't.

robtillaart

Quote
This is the first use of recursion I've found in years!

any loop can be rewritten recusively and vice versa.

The use of recursion is especially useful when either your algorithm-strategy or your data structure shows recursive patterns

famous recursive algorithms:
- faculty of a number, Fibonacci numbers (double recursive),  and of course quickSort()
- graphical alg. like hilbert curves.

famous recursive data structure
- list, tree, graphs, fractals, ...

Please read - http://natureofcode.com/book/chapter-8-fractals/ - very inspiring text about recursion (and fractals)
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

karlboll

#4
Oct 09, 2013, 01:45 pm Last Edit: Oct 09, 2013, 01:49 pm by karlboll Reason: 1
The only thing I'm worse at than coding is reading code (and gymnastics). How do I use this sketch?

Oh, nevermind. I thought those little snippets if code was the whole thing . I get it now.
First we ignore them, then we make fun of them, then we fight them and then they win so let's cut the crap and just expose them for the corrupt liars they are.

Go Up