Hey Folks
I have two Spark Core boards publishing data on the cloud and I’m using the third Spark to subscribe to them. I would like to know how can I decide which one of the two Spark Core publish data first? Depending on that, I will concatenate the data of the first Spark first followed by the second Spark. I started my code for the subscriber and I want to see your suggestions please.
#include "Particle.h"
char Text1[64]; //Buffer for the data of Spark 1
char Text2[64]; //Buffer for the data of Spark 2
uint32_t ms1; //Time storage for Spark 1 publishing
uint32_t ms2; //Time storage for Spark 2 publishing
void myHandler1(const char *event, const char *data) //Handler for Spark1
{
strcpy(Text1, data); //Put the Spark1 data inside a global buffer so we can use it anywhere in the code
Particle.publish("Spark1",Text1); // Make sure that Spark3 can receive data from Spark1 correctly
ms1 = millis(); //put the time of the initial publishing of Spark1 in ms1
}
void myHandler2(const char *event, const char *data) //Handler for Spark2
{
strcpy(Text2, data); //Put the Spark2 data inside a global buffer so we can use it anywhere in the code
Particle.publish("Spark2",Text2); // Make sure that Spark3 can receive data from Spark2 correctly
ms2 = millis(); //put the time of the initial publishing of Spark2 in ms2
}
void setup()
{
Serial.begin(4800); //start the serial port
Particle.subscribe("Spark1", myHandler1); //subscribe for Spark1
Particle.subscribe("Spark2", myHandler2); //subscribe for Spark2
if (Text1!=0 && Text2!=0) // make sure that both of the sparks have data
{
if (ms1-ms2 > 0) //Check if Spark1 publish the data first
{
snprintf(Text1,sizeof(Text1),Text2,sizeof(Text2)); //concatenate data of Spark1 to data of Spark2 in a form of (data1data2) and place the result in Text1
//strcat(Text1, Text2); //another way to concatenate the data
//sprintf(Text1, "Pad's 1 data is %d, Pad's 2 data is %d, Pad's 3 data is %d", Text1,Text2); //another way to concatenate the data
Particle.publish("Spark1,Spark2",Text1); // publish the concatenated data to the cloud
Particle.publish("The sequence of data","Spark 1 publish before Spark2");
}
else // Spark2 publish data before Spark1
snprintf(Text2,sizeof(Text2),Text1,sizeof(Text1)); //concatenate data of Spark2 to data of Spark1 in a form of (data2data1) and place the result in Text2
Particle.publish("Spark2,Spark1",Text2); // publish the concatenated data to the cloud
Particle.publish("The sequence of data","Spark 2 publish before Spark1");
}
}
void loop(){}
Can I use the millis function two times to decide which Spark publish first? Or is there any other way to do it? @bko@Moors7@ScruffR
Thanks in advance.
Ahmed.
I would assume that due to network latency, there is no way to know. If you want to make sure you have them in the right order, I suggest adding the event time to the data the devices publish and then using that.
Thanks for your suggestion but I didn’t deal with Json before. Where I should put this line inside my code? Do I need this line inside each handler?
Thanks in advance.
String data = "SAXE"; // however you get your data
unsigned long now = millis();
String publishData = String(now) + "|" + data; // e.g. 692865|SAXE
Particle.publish("EVENT_NAME", publishData);
And then on the receiving side:
int separator = receivedData.indexOf("|");
unsigned long deviceEventMillis = receivedData.substring(0, separator).toInt();
String deviceEventData = recievedData.substring(separator + 1);
I am making the assumption that your two events could happen within the same second and that you need the accuracy. So the other thing I would do is that when the device start, they would publish their start time and millis so you can do the math to get the actual time.
For the first code that you posted, I understood that I need to add it for each publisher Spark (Spark1 and Spark2) to count their publish time and decide which one was activated first.
For the receiver side, I couldn’t understand how I will extract the time from the publishdata and compare between the two Sparks time?
Other question that I have are:
1- Is the receivedData is the publishData from the sender?
2- Do I need to compare between the deviceEventMillis1 (published time for Spark1) and deviceEventMillis2 (published time for Spark2)?
3- Is it easier to use different line to publish the Spark publish time in the sender side, compare between the two publish time for the two Sparks in the receiver side, and concatenate the two Sparks data then send it again to the cloud?
Monitor Device receives sensor event
a. subtracts startup_mills from the sensor_event_mills
b. converts above value to decimal seconds and adds it to startup_time for true event_time
If second event is sent in close proximity, the two event_times are compared
I tried to add your suggestion’s code to the sender and receiver but I got the following errors:
error: request for member 'indexOf' in 'Text1', which is of non-class type 'char [64]'
error: request for member 'substring' in 'Text1', which is of non-class type 'char [64]'
You’re getting these errors because you’re mixing String code (from justinmy’s code suggestions) with c-string code (i.e. the char arrays Text1 and Text2). You need to use one or the other. I would suggest that since the data passed in is a char*, that you stick with c-strings, and use the strtok function to separate the two parts of your data.
@ScruffR I did that and I looked in google for how the strtok function works, but I couldn’t get rid of the errors. I tried to change the type of the deviceEventData1[64]; to be:
String deviceEventData1[64];
char deviceEventData1[64];
or char *deviceEventData1[64];