Parsing data from serial

Hi.

I m using the code from Serial basics for parsing data.

 const byte numChars = 32;
char receivedChars[numChars];
char tempChars[numChars];       
      
char messageFromPC[numChars] = {0};
int a = 0;
int b = 0;
int c = 0;
int d = 0;

boolean newData = false; 
 


void loop() {
 

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

}  

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

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," ");     
    strcpy(messageFromPC, strtokIndx); 
 
  
    
    strtokIndx = strtok(NULL, " "); 
    a = atoi(strtokIndx);     

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


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

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

      
   
   
   trellis.setPixelColor(a,  rgbColor(b,c,d));

The thing is, Im no efficient with the transfer of data. Im sending an ¨a¨ at the beginning of the data

string because at parseData I cant change the first part of the string (messageFromPC) to an integer.

I try atoi in different places with no luck....

Anyone?

You are parsing a string and 4 integers with start (<) and end (>) markers delimited by spaces. What are you sending?

Your code will not compile. You are missing the setup() function. Where is trellis declared? Are you missing a library?

I modified your code a bit to show how it could work. See the parseData() function.

const byte numChars = 32;
char receivedChars[numChars];
char tempChars[numChars];

char messageFromPC[numChars] = {0};
int a = 0;
int b = 0;
int c = 0;
int d = 0;

boolean newData = false;

void setup()
{
   Serial.begin(115200);
   Serial.println("Arduino Ready");
   Serial.println("Enter data as <string int int int int>");
}

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

}

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

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, " ");
   strcpy(messageFromPC, strtokIndx);

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

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

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

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

   Serial.println(messageFromPC);
   Serial.println(a);
   Serial.println(b);
   Serial.println(c);
   Serial.println(d);

   //trellis.setPixelColor(a,  rgbColor(b, c, d));
}

And here is the input and output. Note that spaces separate values.

Thanks for the answer. Sorry for not posting the entire code.

It compiles

I am sending 4 integers, with maximum posible values are 512 (led matrix pos) and 255 255 255 (RGB)

I am sending to Serial <a 512 255 255 255>

I send that ¨a¨ because I dont know how to parse simply <512 255 255 255>, or even better, if its posible

512 255 255 255

#include "Adafruit_NeoTrellis.h"


#define Y_DIM 16 
#define X_DIM 32
#define INT_PIN 10



Adafruit_NeoTrellis t_array[Y_DIM/4][X_DIM/4] = { 

  
 { Adafruit_NeoTrellis(0x35), Adafruit_NeoTrellis(0x3A), Adafruit_NeoTrellis(0x4A), Adafruit_NeoTrellis(0x33),Adafruit_NeoTrellis(0x4B), Adafruit_NeoTrellis(0x45), Adafruit_NeoTrellis(0x4C), Adafruit_NeoTrellis(0x42) },
 
{ Adafruit_NeoTrellis(0x4D), Adafruit_NeoTrellis(0x3E) , Adafruit_NeoTrellis(0x40), Adafruit_NeoTrellis(0x38),Adafruit_NeoTrellis(0x31), Adafruit_NeoTrellis(0x3D), Adafruit_NeoTrellis(0x3B), Adafruit_NeoTrellis(0x49) },

{ Adafruit_NeoTrellis(0x2F), Adafruit_NeoTrellis(0x2E), Adafruit_NeoTrellis(0x3C), Adafruit_NeoTrellis(0x47),Adafruit_NeoTrellis(0x32), Adafruit_NeoTrellis(0x36), Adafruit_NeoTrellis(0x48), Adafruit_NeoTrellis(0x3F)  },

 { Adafruit_NeoTrellis(0x34), Adafruit_NeoTrellis(0x44), Adafruit_NeoTrellis(0x39), Adafruit_NeoTrellis(0x41), Adafruit_NeoTrellis(0x30), Adafruit_NeoTrellis(0x37), Adafruit_NeoTrellis(0x43), Adafruit_NeoTrellis(0x46) }
 
};


Adafruit_MultiTrellis trellis((Adafruit_NeoTrellis *)t_array, Y_DIM/4, X_DIM/4);


TrellisCallback blink(keyEvent evt){
  
  if(evt.bit.EDGE == SEESAW_KEYPAD_EDGE_RISING)
   
      Serial.println(evt.bit.NUM);

      
  else if(evt.bit.EDGE == SEESAW_KEYPAD_EDGE_FALLING)
     Serial.println(evt.bit.NUM);

    
 
  return 0;
}

inline uint32_t rgbColor(uint32_t r, uint32_t g, uint32_t b)
{
  return ((r << 16) | (g << 8) | b);
}
  
   
  const byte numChars = 32;
char receivedChars[numChars];
char tempChars[numChars];       
      
char messageFromPC[numChars] = {0};
int a = 0;
int b = 0;
int c = 0;
int d = 0;

boolean newData = false; 
   
   
    
   
   
   
   
   
   
   void setup() {
  Serial.begin(38400);
  


  

      pinMode(INT_PIN,INPUT);
  
  
  !trellis.begin();
  
   
  for(int y=0; y<Y_DIM; y++){
    for(int x=0; x<X_DIM; x++){
      
      trellis.activateKey(x, y, SEESAW_KEYPAD_EDGE_RISING, true);
      trellis.activateKey(x, y, SEESAW_KEYPAD_EDGE_FALLING, true);
      trellis.registerCallback(x, y, blink);
   
    }
  }
     



     

}

void loop() {
 

  if(!digitalRead(INT_PIN)){
    trellis.read();
  }
  


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

    
     


}

    





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

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," ");     
    strcpy(messageFromPC, strtokIndx); 
   
  
    
    strtokIndx = strtok(NULL, " "); 
    a = atoi(strtokIndx);     

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


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

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

      
   
   
   trellis.setPixelColor(a,  rgbColor(b,c,d));
    

  trellis.show();   
  
    
    
    
    
    

  
}

Sure it is possible.

change to this line in setup():

 Serial.println("Enter data as <int int int int>");

Replace the parseData() function with this:

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);

   Serial.println(a);
   Serial.println(b);
   Serial.println(c);
   Serial.println(d);

   //trellis.setPixelColor(a,  rgbColor(b, c, d));
}

Enter data as <120 140 160 180>

1 Like

Yes.

It worked!!!

Thank you very much.