// from 
// https://forum.arduino.cc/t/commands-over-serial/1320091/37

// multiword command processing
//   using sscanf

char s [90];        // for sprintf()

// -----------------------------------------------------------------------------
// test command functions used to demonstrate processing
void led (int pin, bool b)
{
    sprintf (s, "        led: pin %d, %s", pin, b ? "On" : "Off");
    Serial.println (s);
}

void motor (int id, int pwm, int dir)
{
    sprintf (s, "        motor: id %d, pwn %3d, %s",
                            id, pwm, 0 < dir ? "forward" : "reverse");
    Serial.println (s);
}

void servo (int id, int ang)
{
    sprintf (s, "        servo: id %2d, ang %3d", id, ang);
    Serial.println (s);
}

// -------------------------------------
// tokenize command line and search for cmd, 1st token, in cmds []
void
processCmd (
    char *buf )
{
    sprintf (s, "\nprocessCmd: %s\n", buf);
    Serial.print (s);

    char  cmd [20];
    int   val1;
    int   val2;
    int   val3;

    int nFld = sscanf (buf, "%s %d %d %d\n", cmd, &val1, &val2, &val3);

    if (3 == nFld)  {
        if (! strcmp (cmd, "led"))
            led (val1, val2);
        else if (! strcmp (cmd, "servo"))
            servo (val1, val2);
    }
    else if (4 == nFld) {
        if (! strcmp (cmd, "motor"))
            motor (val1, val2, val3);
    }
}

// -----------------------------------------------------------------------------
// define test command lines
char *str [] = {
    (char *)"led 12 0",
    (char *)"led 12 1",

    (char *)"motor 0 0 1",
    (char *)"motor 1 0 1",
    (char *)"motor 0 255  1",
    (char *)"motor 1 255 -1",
    (char *)"motor 1 0 1",

    (char *)"servo 0 90",
    (char *)"servo 1 180",
};
const int Nstr = sizeof(str)/sizeof(char *);

void setup ()
{
    Serial.begin (9600);

    // process each test cmd line
    printf (" %d Nstr\n", Nstr);
    for (int n = 0; n < Nstr; n++)
        processCmd (str [n]);
}

void loop () { }