Understanding processing of functions called by Particle.Function

I am having a hard time understanding why a function called via a web call (setup via Particle.Function) only works under certain conditions. Here is the function:

int setAnimation(String command)
 {
   int animationNum;
   int speed;
   int numColors;
   char buff[COMMANDLEN];
   char *token;

   //string limit is 63 characters
   if (command.length()>COMMANDLEN)
     return -1;

   command.toCharArray(buff, COMMANDLEN);

   token = strtok(buff, ",");
   animationNum = String(token).toInt();

   token = strtok(NULL, ",");
   speed = String(token).toInt();

   token = strtok(NULL, ",");
   numColors = String(token).toInt();

   AlaColor colorPalette_[numColors];


   for (int i=0; i < numColors; i++)
   {
     token = strtok(NULL, ",");
     colorPalette_[i] = strtol(token, NULL, 0);
   }

   //ENABLING THIS CODE FIXES THE FUNCTION
   /*for (int i=0; i < numColors; i++)
   {
     Particle.publish("Color: ",String(i));
     Particle.publish("RGB: ",String(colorPalette_[i].r)+","+String(colorPalette_[i].g)+","+String(colorPalette_[i].b));
   }*/

   AlaPalette colorPalette = {numColors, colorPalette_};

   rgbLed.setAnimation(animationNum, speed, colorPalette);
   return 1;

 }

The first set of variables always get set correctly. It is the AlaColor array and/or the AlaPalette that do not get set correctly. Something exists in the AlaPalette object and is passed to the setAnimation function, it just isn’t what was in the args string. I put in a couple of Particle.Publish (currently commented out) to do some basic troubleshooting and just adding those .Publish statements fixed the problem. The other way I can fix the problem is set SYSTEM_THREAD(ENABLED). Interestingly, SINGLE_THREADED_BLOCK() doesn’t appear to fix it.

I understand that the system is running a RTOS in the background and jumping between different operations, but I am having a hard time understanding why the code wouldn’t run correctly without the fixes I mentioned.

Thanks,
Nick

To parse a string like that, you could try sscanf() for parsing.

But in order to debug this kind of issue, you should try to find where in code your values get “corrupted” by adding debug statements (e.g. Serial.print()).
This might give you a clue about the reason.
Don’t use Particle.publish() for debugging - it might introduce extra issues and is rate limited.

But most importantly, you are creating colorPalette and colorPalette_[] as automatic/local variables in the function and as such they are (likely) created on the stack. As soon the function leaves the respective stack portions will get repurposed for other calls. This might or might not be an issue, depending on the - for us unknown - implementation of your rgbLed object.

BTW, I’d rather use atoi() instead of frequently creating/destroying String objects just for the sake of calling toInt() on them.

3 Likes