A code structure problem

Go To Last Post
8 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Greetings -

I have an application that accepts a variety of serial input ASCII characters as "commands". For example, M,U,u,P,?,D,S. The list makes up much less than half of the ASCII character set (13 at latest count, might go slightly higher).

Each message begins with a '$' as a "framing" character, then one of the characters, above. I would like to test whether or not the received character is one of the 13 valid characters.

A chain of if(), else if(),.. would work but that seems awkward. A switch chain would also work but, again, its just big enough to seem awkward. There are too many to do if(MyChar == 'M")||(MyChar == 'U')|| ...

Unfortunately, the list is quasi-random with little in common between them beyond the fact that they are ASCII characters.

So, is there any way to simplify this process, somehow?

Thanks
Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

One vote for switch() here.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

A switch block is not that untidy:

    switch (c) {
    case 'M: case 'U': case 'u': 
        return TRUE;
    default:
        return FALSE;
    }

OTOH, just put all your valid characters in a string.
I would assume that NUL is not a valid command.

    char validchars[] = "MUuP?DS";
    for (char *p = validchars; *p != NUL; p++) {
        if (*p == c) return TRUE;
    }
    return FALSE;

You normally want to know which command:

    char validchars[] = "MUuP?DS";
    for (int i = 0; validchars[i] != NUL; i++) {
        if (validchars[i] == c) return i;
    }
    return -1;

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Oh, I had forgotten about multiple cases on a line!

I like that.

Thanks

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

then one of the characters, above.

You made it harder on yourself. :twisted:. If you'd restrict yourself to e.g. the alphabet and case-insensitive then you could make a bit mask and ...

But yes, these "little languages" seem to grow on their own.

{AFAICR] The lex/flex state machine approach is proven to be most efficient. That may well break down with your "little language". (I used that phrase purposefully as there is lots of literature on these.)

In practice, I generally use a state machine. It depends on the structure of the rest of your sentences. Sometimes I go character-by-character with a timeout if a complete sentence is not received in time (following the starting trigger). Other times, if e.g. the sentence ends with a carriage return I'll process in one sweep.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If you have 256 bytes of program-space left
simply use a table that maps the character to some
number you want.

myNewCode=theTable[theCharacter]

Setup the table at compiletime in pgmspace

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ka7ehk wrote:
Oh, I had forgotten about multiple cases on a line!

They don't have to be one line; eg,

switch( c )
{
   case 'a':
   case 'S':
   case 'd':
   case 'F': whatever();
             break;

   default:  other();
             break;
}

Which makes it very easy to create - just copy & paste as many blank 'case' lines as you need:

   case '':
   case '':
   case '':
   case '':

Then go through putting in the characters.

8)

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This is a bit of c that I don't remember ever learning about in the pre-1999 world.

Then, again, it may just be be the "fog of time". Glad that I know about it now. I like it.

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net