How to send numeric variables between Particles? (part1: JSON)

Hi, fantastic community! :wave:

I already learnt soo much that Iā€™d like to give something back with this tutorial.
Itā€™s the result of several days of work together with some great members:
@Ric , @Moors7 , @ScruffR , @peekay123 (and probably I forget a few, sorry!)

Objective: How to get a series of variables (integers and floating point) from one Photon into a second one?

Probably many of you have wondered how to do this, right?
For many of you it is obvious, but then there are the less experienced ones like me: Iā€™m 61 and I have still soo much to learn :sweat_smile:


Currently you can not (yet) read a Particle.variable() from another Particle.
I heard through the grapevine that itā€™s on the backlog, but thereā€™s no specific timing known.

Meanwhile we can use a few techniques to do this. For example: JSON and SPRINTF.

basically, we will use Particle.publish() and Particle.subscribe() for this.
But, with this method, we can (only) publish ā€œstringsā€ of text.

With JSON or SPRINTF formatting however, we can assemble and send a string, containing many variables.

This string can then be received in another Photon with Particle.subscribe() and decoded/parsed again with JSON or SPRINTF

In this tutorial, we will use JSON on both sides.
A separate tutorial will cover the SPRINTF method. (You will find that both are complementary and each have their advantages and disadvantages)

Attention: For the JSON technique you will need the ā€œSparkJson.hā€ library.
Itā€™s also available in the particle WebIDE, thanks to @bblanchon and Menan Vadivel. :ok_hand:

You need 2 particles to test this:

Particle 1 runs the ā€œJSON Generator & Publish testā€ sketch.
It sends a message called ā€œStatusā€ with the variables in a JSON text string.

Particle 2 runs the sketch called ā€œJSON Parsing & Subscribe testā€.
It ā€˜catchesā€™ the JSON text string in the ā€œStatusā€ message and splits it up into the variables again.
These variables can then be output separately to your serial monitor.
You can also calculate with the numeric ones (INT, FLOATā€¦)

Please understand that I deserve no credit for the techniques used in these sketches, only for the final polishing to a useful set of tools.
I will be very interested to read your reactions and probably improvementsā€¦


Below you find both sketches: Just flash them to your 2 Particles and connect the receiver via USB to your serial monitor:

  1. This is the sketch for the sending Particle:

/* JSON Generator & Publish test

Written by @FiDel, it's the result of several days of work together with some great members:
@Ric , @Moors7 , @ScruffR , @peekay123 (and probably I forget a few, sorry!)

It will publish the changing variables as a long string with variable names like this:
{"Controller":"ECO system","T1":7,"T2":14,"T3":21,"T4":28,"T5":35,"T6":42,"T7":777,"Energy":7}
*/

#include "SparkJson/SparkJson.h"
// We initiate all variables we want to package in a JSON string:
char Controller[ ] = "ECO system";
int T1=0;
int T2=0;
int T3=0;
int T4=0;
int T5=0;
int T6=0;
int T7=0;
int Energy=0;

char jsonString[255];
StaticJsonBuffer<300> jsonBuffer;
JsonObject& root = jsonBuffer.createObject();


void setup()
{
 Serial.begin(9600);
}

void loop()
{
// Modify the variables each step:
 T1=T1+1;
 T2=T2+2;
 T3=T3+3;
 T4=T4+4;
 T5=T5+5;
 T6=T6+6;
 T7=T7+111;
 Energy=Energy*1.1234;
 
 // Put variables in JSON format:
 root["Controller"] = Controller;
 root["T1"] = T1;
 root["T2"] = T2;
 root["T3"] = T3;
 root["T4"] = T4;
 root["T5"] = T5;
 root["T6"] = T6;
 root["T7"] = T7;
 root["Energy"] = Energy;
 
 root.printTo(jsonString, sizeof(jsonString));

// Output variables as a JSON string:
 Serial.println(jsonString);
 Particle.publish("Status", jsonString,60,PRIVATE);
 delay(5000);
}
  1. This is the sketch for the receiving Particle:

/* JSON Parsing & Subscribe test
Written by @FiDel, it's the result of several days of work together with some great members:
@Ric , @Moors7 , @ScruffR , @peekay123 (and probably I forget a few, sorry!)

Purpose: Transmit numeric variables from one Particle to others.
For the test you need 2 particles:
Particle 1 runs the "JSON Generator & Publish" sketch, sending a message called "Status" with the variables in a JSON text string
Particle 2 (this one) runs this sketch.It will receive the published string like this:
{"Controller":"ECO system","T1":7,"T2":14,"T3":21,"T4":28,"T5":35,"T6":42,"T7":777,"Energy":7}
Then it splits it up into separate variables again. These variables can then be output separately on the serial monitor.
*/

#include "SparkJson/SparkJson.h"

void setup()
{
 Serial.begin(9600);
 Particle.subscribe("Status", myHandler, MY_DEVICES);
}


void loop()
{
}

void myHandler(const char *event, const char *data)
{
   StaticJsonBuffer<512> jsonBuffer;
   char jsonString[255];
   strncpy(jsonString, data, 255);
   Serial.println(jsonString);
   Serial.println();
   JsonObject& root = jsonBuffer.parseObject(jsonString);

   if (!root.success())
   {
    Serial.println("parseObject() failed");
    return;
   }

   const char* Controller = root["Controller"];
   int T1 = root["T1"];
   int T2 = root["T2"];
   int T3 = root["T3"];
   int T4 = root["T4"];
   int T5 = root["T5"];
   int T6 = root["T6"];
   int T7 = root["T7"];
   int Energy = root["Energy"];
   
   Serial.println(Controller);
   Serial.println(T1);
   Serial.println(T2);
   Serial.println(T3);
   Serial.println(T4);
   Serial.println(T5);
   Serial.println(T6);
   Serial.println(T7);
   Serial.println(Energy);
   Serial.println();
}

If you are interested in the other method, check out the Part2 tutorial.
Curious for your contributions!

3 Likes

Nice write-up :+1:

sprintf() would be used for putting the string together, for decoding/parsing you'd use strtok(), sscanf() or other approaches like "manually" traversing the string.

3 Likes