Parsing data integer plus letter

Hi All.

I want to turn on leds on a grid receiving from serial a number (for the position of the led) and a letter to call a hex code.

I mean, to make faster the serial communication I want to send just a letter to call for example¨:

unsigned long s = 0x006600; Green
unsigned long f = 0x000000; Off

Reading Robins post about Serial Communication i was able to receive and parse integers but cant seem to be able to do what I want.

Here is the the relevant part of the code I used to parse integers

unsigned long  s = 0x006600;
unsigned long  f = 0x000000; 
   
const byte numChars = 32;
char receivedChars[numChars];
char tempChars[numChars];       
      
int a ;
int b ;
int c ;
int d ;

boolean newData = false; 

/////////////////////////////////////


void loop() {


  recvWithStartEndMarkers();
    if (newData == true) {
        strcpy(tempChars, receivedChars);
            
        parseData();
        
        newData = false;
    }

   delay (2);  

}
/////////////

void recvWithStartEndMarkers() {
    static boolean recvInProgress = false;
    static byte ndx = 0;
    char startMarker = '<';
    char endMarker = '>';
    char rc;

    while (Serial.available() > 0 && newData == false) {
        rc = Serial.read();

        if (recvInProgress == true) {
            if (rc != endMarker) {
                receivedChars[ndx] = rc;
                ndx++;
                if (ndx >= numChars) {
                    ndx = numChars - 1;
                }
            }
            else {
                receivedChars[ndx] = '\0';
                recvInProgress = false;
                ndx = 0;
                newData = true;
            }
        }

        else if (rc == startMarker) {
            recvInProgress = true;
        }
    }
}

///////////



void parseData() {

         
    char * strtokIndx; 

    strtokIndx = strtok(tempChars," ");     
     
    
   
    a = atoi(strtokIndx);     

    strtokIndx = strtok(NULL, " ");
    b = atoi(strtokIndx);     


    strtokIndx = strtok(NULL, " ");
    c = atoi(strtokIndx);    

    strtokIndx = strtok(NULL, " ");
    d = atoi(strtokIndx);    

      
   
  
   trellis.setPixelColor(a, b);     ////   Here I used b,c,d  integers for the rgb code, now I want to call 
                                                           the unsigned long s  or  f
   
  
}

I suspect im not using the right terminology when I say Call for the Hex color but i hope you understand what i mean.

Hello

Once the program is compiled, variables doesn't have names..

What you can do is a switch statement like this

switch( strtokIndx[0] )
{
  case 's' :
  {
    color = s;
    break;
  }
  
  default :
  {
    color = f;
    break;
  }
}

Or eventually use strcmp if you want to be able to use more than one letter:

if ( !strcmp( strtokIndx, "green" ) )
{
  color = s;
}

I dont think I understand.

I want to receive different letters and each one to call a different color.

So I can here use ¨a¨ for number and ¨color¨ for the hex code

trellis.setPixelColor (a, color);

Here arent you receving ¨green¨ ?

if ( !strcmp( strtokIndx, "green" ) )
{
  color = s;
}

For single letters, add more case as needed, in the switch.

My comment about strcmp is only useful if you want to be able to give meaningful names to colors to send commands like <10 green>, but apparently you don't want to do that so forget about it.

Thanks.

I will try that

I cant make it work...

Maybe something Im not taking into account. Im sending via serial "5 s" or "5 f".

Does data is transfered in ASCII ?

So, in Parse the number is coverted into an integer but wount the letter be coverted too?

Sorry for my lack of knoledge. Im not a programmer im trying to build a controller for a synth

Can you spot the mistake?

unsigned long  s = 0x006600;
unsigned long  f = 0x000000; 
char color;
int a ;

/////////



void parseData() {

      char * strtokIndx; 

      strtokIndx = strtok(tempChars," ");     
    
       a = atoi(strtokIndx);     

       
      strtokIndx = strtok(NULL, " ");
   
    
      switch( strtokIndx[1] )
      {
         case 's' :
      {
         color = s;
        break;
          }
        case 'f' :
      {
         color = f;
        break;
          }
        default :
      {
         color = f;
        break;
        }
      }
 
 trellis.setPixelColor(a, color);

I suggest doing something like this instead: BikuO4 - Online C++ Compiler & Debugging Tool - Ideone.com

Well you have to send start and end markers as well : "<5 s>". The 'parser' will keep what is between '<' and '>' and store it in your tempChars, so it will contain "5 s".

Why did you change strtokIndx[0] to strtokIndx[1] ? The first element of an array is at position 0, and you want the first character not the second.

you may be interested in pcRead() which i add and customize to almost every program to help test and debug.

it accepts single letter commands that are optionally preceded by a numeric value. multiple commands can be on a single line (terminated by '\n') where the early commands set variables to numeric input and the final command executes some sub-function using those variables

// pcRead - debugging using serial monitor

const char version [] = "PcRead 211009a";
int debug = 0;

// -----------------------------------------------------------------------------
// process single character commands from the PC
int  analogPin = 0;

void
pcRead (void)
{

    static int  val = 0;

    if (Serial.available()) {
        int c = Serial.read ();

        switch (c)  {
        case '0':
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
            val = c - '0' + (10 * val);
            break;

        case 'A':
            analogPin = val;
            Serial.print   ("analogPin = ");
            Serial.println (val);
            val = 0;
            break;

        case 'D':
            debug ^= 1;
            break;

        case 'I':
            pinMode (val, INPUT);
            Serial.print   ("pinMode ");
            Serial.print   (val);
            Serial.println (" INPUT");
            val = 0;
            break;

        case 'O':
            pinMode (val, OUTPUT);
            Serial.print   ("pinMode ");
            Serial.print   (val);
            Serial.println (" OUTPUT");
            val = 0;
            break;

        case 'P':
            pinMode (val, INPUT_PULLUP);
            Serial.print   ("pinMode ");
            Serial.print   (val);
            Serial.println (" INPUT_PULLUP");
            val = 0;
            break;


        case 'a':
            Serial.print   ("analogRead: ");
            Serial.println (analogRead (val));
            val = 0;
            break;

        case 'c':
            digitalWrite (val, LOW);
            Serial.print   ("digitalWrite: LOW  ");
            Serial.println (val);
            val = 0;
            break;

        case 'p':
#if !defined(ARDUINO_ARCH_ESP32)
            analogWrite (analogPin, val);
            Serial.print   ("analogWrite: pin ");
            Serial.print   (analogPin);
            Serial.print   (", ");
            Serial.println (val);
            val = 0;
#endif
            break;

        case 'r':
            Serial.print   ("digitalRead: pin ");
            Serial.print   (val);
            Serial.print   (", ");
            Serial.println (digitalRead (val));
            val = 0;
            break;

        case 's':
            digitalWrite (val, HIGH);
            Serial.print   ("digitalWrite: HIGH ");
            Serial.println (val);
            val = 0;
            break;

        case 't':
            Serial.print   ("pinToggle ");
            Serial.println (val);
            digitalWrite (val, ! digitalRead (val));
            val = 0;
            break;

        case 'v':
            Serial.print ("\nversion: ");
            Serial.println (version);
            break;

        case '\n':          // ignore
            break;

        case '?':
            Serial.println ("\npcRead:\n");
            Serial.println ("    [0-9] append to #");
            Serial.println ("    A # - set analog pin #");
            Serial.println ("    D # - set debug to #");
            Serial.println ("    I # - set pin # to INPUT");
            Serial.println ("    O # - set pin # to OUTPUT");
            Serial.println ("    P # - set pin # to INPUT_PULLUP");
            Serial.println ("    a # - analogRead (pin #)");
            Serial.println ("    c # - digitalWrite (pin #, LOW)");
            Serial.println ("    p # -- analogWrite (analogPin, #)");
            Serial.println ("    r # - digitalRead (pin #)");
            Serial.println ("    s   - digitalWrite (pin #, HIGH)");
            Serial.println ("    t   -- toggle pin # output");
            Serial.println ("    v   - print version");
            Serial.println ("    ?   - list of commands");
            break;

        default:
            Serial.print ("unknown char ");
            Serial.println (c,HEX);
            break;
        }
    }
}

// -----------------------------------------------------------------------------
void
loop (void)
{
    pcRead ();
}

// -----------------------------------------------------------------------------
void
setup (void)
{
    Serial.begin(115200);

    Serial.println (version);
#if defined(ARDUINO_ARCH_ESP32)
    Serial.println ("esp32");
#endif
}

I would use

switch( strtokIndx[0] )

like @guix already mentioned and explained.

Thank you