before doing File I/O, i decided to see about sending text commands to the Uno. The code is supposed to start counting at 'start', stop counting at 'stop', and reset the counter at 'zero'. If already stopped, and you tell it to stop, it will send you a message saying "already stopped". However, if i type in "st", it will start counting. If i type in stop, hit will say "starting...", reset, then stop. It never sends "Already stopped". I then changed 'start' to 'begin'. It now does "already stopped" and no longer displays "starting...", but still resets when stop is typed.
What am i doing wrong to make it behave this way? Thanks in advance...
char inst;
int stat = 0;
int counter = 0;
void setup()
{
Serial.begin(9600);
Serial.println("Initializing");
}
void loop()
{
if (stat == 1)
{
Serial.print(counter);
Serial.println("...");
counter++;
delay(100);
}
if (Serial.available() )
{
inst = Serial.read();
}
switch (inst) {
case 'begin':
Serial.println("starting..");
stat = 1;
inst = ' ';
break;
case 'stop':
if (stat == 0)
{
Serial.println("Already stopped");
inst = ' ';
}
else
{
Serial.println("stopping...");
stat = 0;
inst = ' ';
}
break;
case 'zero':
Serial.println("resetting...");
counter = 0;
inst = ' ';
break;
default:
stat = stat;
}
}
A single char is never going to have the value 'begin'(or start or stop or zero), which is five chars.
What happens if there isn't a character available?
so should i do string? I found it interesting that it wouldn't start on "s", but would start on "st".
While nothing is there, it either keeps counting or stops counting depending on the value of stat (see first if statement). each case resets inst. If i didn't reset inst, it would keep the last value and run that condition.
AWOL:
Unless you're going to expand the command set hugely, I'd stick to single letters.
I second that. I've seen quite a few posts with OP trying to receive strings as commands where a single character is sufficient. Strings are for more complicated situations. Should it arise, you can come ask again. This situation could arise when you want to accomplish something like "start counting but not from zero and from 65535 and count down instead of count up". I'd be happy to share some of my code for such situations. For now, let's stick with single character commands and switch-case.
Ok, i'll stick to single letter commands. I was probably going to have about 10-20 commands, but i suppose i can map them. I just wanted to try a little "big boy programming" is all :). I am interested in the code :). Thanks again
26 char in lower and uppercase make 52
10 digits
32 other signs like `~!@#$%^&*()_+-={}|[]:";'<>?,./
total of 94...
If you really want to use strings there are a few ways: (be sure to first build up the string!)
if then else ladder => simple and robust, slow, most used commands should be at top of the ladder of course
if (strcmp(s, "begin")==0)
{
}
else if (strcmp(s, "next command")==0)
{
}
else if ....
perfect hash function followed by a switch => fast, but not trivial to find.
int cmd= phash(s);
switch(cmd)
{
case 1: ..
case 2: ..
etc
}
A perfect hash is a hash function that (in this case) for every expected string of a set of commands generates an unique number by manipulating the string. It COULD look like the following:
int phash(char *s)
{
return (s[0]-'a')*26 + (s[1]-'a');
}
This hash function assumes that the first two chars of a command string together form an unique number [and lowercase]. It will generate a number between 0 and 625.
A perfect hash function will generate a consecutive(?) number sequence { 1,2,3,4,5,...n } for a set of commands. This makes a perfect hash quite difficult to find. One advantage of a perfect hash is that the number can be used as the index for an array of functions. ==> funcphash(commandstring);
Instead of the first 2 chars one can also take the first and the last, or 3,4,5 chars or the string length, the number of vowels etc.
Drawback of hash functions is that if you add a new command your hashfunction might need a redesign, so it is often good to elaborate the completeness of the commandset first.
My multi-character command code looks like Nick's code. There has to be a special character to indicate the end of the command, often end of line or something you don't use inside your command, such as a back slash or '#' etc. I chose mine to be '~' since it is the firmware for serial LCDs. The '~' is the last character on the ASCII table that can be typed from a keyboard and is not used in messages. You create a buffer (char array) to store all characters until you get to the end of command character, then interpret the command with a set of syntax. Say your command always comes with
26 char in lower and uppercase make 52
10 digits
32 other signs like `~!@#$%^&*()_+-={}|[]:";'<>?,./
total of 94...
If you really want to use strings there are a few ways: (be sure to first build up the string!)
if then else ladder => simple and robust, slow, most used commands should be at top of the ladder of course
if (strcmp(s, "begin")==0)
{
}
else if (strcmp(s, "next command")==0)
{
}
else if ....
perfect hash function followed by a switch => fast, but not trivial to find.
int cmd= phash(s);
switch(cmd)
{
case 1: ..
case 2: ..
etc
}
A perfect hash is a hash function that (in this case) for every expected string of a set of commands generates an unique number by manipulating the string. It COULD look like the following:
int phash(char *s)
{
return (s[0]-'a')*26 + (s[1]-'a');
}
This hash function assumes that the first two chars of a command string together form an unique number [and lowercase]. It will generate a number between 0 and 625.
A perfect hash function will generate a consecutive(?) number sequence { 1,2,3,4,5,...n } for a set of commands. This makes a perfect hash quite difficult to find. One advantage of a perfect hash is that the number can be used as the index for an array of functions. ==> funcphash(commandstring);
Instead of the first 2 chars one can also take the first and the last, or 3,4,5 chars or the string length, the number of vowels etc.
Drawback of hash functions is that if you add a new command your hashfunction might need a redesign, so it is often good to elaborate the completeness of the commandset first.
From the C Language Standard, ISO/IEC 9899:1999(E) 6.8.4.2:
The controlling expression of a switch statement shall have integer type.
The expression of each case label shall be an integer constant expression and no two of the case constant expressions in the same switch statement shall have the same value after conversion.