Subscribe to two Spark Core boards and decided which one published data first

Unless you changed your code, you have another problem. You’re subtracting two char arrays, not two numbers when you do,

if (deviceEventMillis1-deviceEventMillis2<0)

That is comparing the two addresses of those arrays, not the value of the numbers represented by those strings. You need to convert the strings to numbers first.

2 Likes

No @Ric , I didn’t change the code. That’s mean this might be part of the issue that I’m facing.
How can I convert the char to number?
I found two ways to do it as shown below:

char c = ‘5’;
int x = c - ‘0’;

Or by using atoi function

int val;
char str[20];
strcpy(str, “98993489”);
val = atoi(str);

As @Ric suggested for:

and as @justinmy suggested for:

I came up with this modification:

int chartonum1;
int chartonum2;
void myHandler3(const char *event, const char *data)
{
  strcpy(recdata1,data);
  strcpy(deviceEventMillis1, strtok(recdata1 , "|"));
  strcpy(deviceEventData1, strtok(NULL, "|"));
  chartonum1=atoi(deviceEventMillis1); //convert the deviceEventMillis1 from char to numbers
  if  (deviceEventData2!=0){ // check if the other data exist 
  if  (chartonum1-chartonum2<0){
  strcat(deviceEventData1, deviceEventData2); //copy the other data to the existing data
  memset(deviceEventData2, 0, sizeof(deviceEventData2)); //zero out the other data
  Particle.publish("Pad3,Pad4",deviceEventData1);
}
}
}

void myHandler4(const char *event, const char *data)
{
  strcpy(recdata2,data);
  strcpy(deviceEventMillis2, strtok(recdata2 , "|"));
  strcpy(deviceEventData2, strtok(NULL, "|"));
  chartonum2=atoi(deviceEventMillis2); //convert the deviceEventMillis2 from char to numbers
  if  (deviceEventData1!=0){  // check if the other data exist 
  if  (chartonum2-chartonum1<0){
  strcat(deviceEventData2, deviceEventData1); //copy the other data to the existing data
  memset(deviceEventData1, 0, sizeof(deviceEventData1)); //zero out the other data
  Particle.publish("Pad4,Pad3",deviceEventData2);
}
}
}

Is this correct? @Ric @justinmy

The “i” in atoi stands for integer. Are you sending an integer? You might want to check out the functions atof and strtod. If your data part always starts with a letter, then can even use strtod instead of strtok.

1 Like

I also recommend zeroing out all items after publishing Pad4,Pad3. Your code will also be simpler if both the handlers set the data to the global variables and then call a function to see if the data is ready to be posted.

1 Like

@Ric
By using atoi, I'm trying to convert the char for the millis to numbers as you suggested!

You need to convert the string to the correct type of number; I didn’t say to convert it to an int. The value you’re sending needs to be a float or a double since you have decimals, right? Did you look at the other two methods I posted?

1 Like

@Ric Yes I tried atof without success. I still have the Spark2 publish data as a concatenated data without taking care of the data from Spark1.

while nothing happens when Spark1 publishes data first.

@Ric
Is this a correct way to use atof and strtod?

char *test = "12.11";
double temp = strtod(test,NULL);
float ftemp = atof(test);

My data always starts with letter. Do you mean in your post above that strod function will separate the data from the time then convert the time (millis) directly to float so I won't need to use two functions for separation and conversion?

@justinmy
Do you mean that I should do something like this inside each handler?

void myHandler3(const char *event, const char *data) //handler function for Spark3
{ //start of the function
  strcpy(recdata1,data); //convert the const *char (data) to char by copying the data to char
  strcpy(deviceEventMillis1, strtok(recdata1 , "|")); //seperate the millis from the sensor data (put the millis in deviceEventMillis1)
  strcpy(deviceEventData1, strtok(NULL, "|")); //seperate the millis from the sensor data (put the sensor data in deviceEventData1)
  chartonum1=strtod(deviceEventMillis1,NULL);
  //chartoflo1 = atof(deviceEventMillis1); //use it instead of the above line to convert millis char to float
if  (deviceEventData1!=0){  
if  (deviceEventMillis1-deviceEventMillis2<0){ //check if Spark4 came before Spark3
  strcat(deviceEventData1, deviceEventData2); //concatenate Spark3 data to Spark4 data
  Particle.publish("Pad3,Pad4",deviceEventData1); //publish the concatenated data Spark3Spark4
memset(deviceEventData2, 0, sizeof(deviceEventData2)); //zero out the content of Spark4 (the other data)
memset(deviceEventData1, 0, sizeof(deviceEventData1)); //zero out the content of Spark3 (the other data)
memset(deviceEventMillis2, 0, sizeof(deviceEventMillis2)); //zero out the millis part of Spark4 (the other data)
memset(deviceEventMillis1, 0, sizeof(deviceEventMillis1)); //zero out the millis part of Spark3 (the other data)
} //end of if  (deviceEventData2=0){
} //end of the function
}

Yes, something like that. But as stated above, I recommend the handlers parsing the data and then calling a function to compare and if needed publish and clear. That way both handlers will have the same flow and not accidental code differences.