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