Using Spark.publish() with Simple JSON Data

Hi @Ali

I am not an angular.js user so maybe @Moors7 or someone else could help more.

Here is how you register for the events and do the initial JSON parsing:

eventSource.addEventListener('EventNameHere', function(e) {
            var rawData = JSON.parse(e.data);
            var parsedData = JSON.parse(rawData.data);
           ...
        }, false);

Where I put ... you need to add code to find your table (I would name it and use getElementById) and then add data to it (I would use the insertRow method of the table).

Thank you for your reply. I will continue try using the example.

@Moors7 can you help out?

I figured out how his works. Angular has a filter option that can be used to call up specific events.

ex:

<tr ng-repeat="event in events[device.id] | filter: 'yourEventName'  ">
1 Like

Hello,

Nice and usefull tuto.

I can't manage to read those data with Particle.subscribe() on another particle.

Data is received, but no way to translate the data (char) in different integer to pass data from one device to another.

Any idea ?

Hi @sylvaing

In Javascript, lots of functions take strings and automatically convert them to integers. See this page for details:

In this case it seems like the Javascript like this is what you want:

  var myInt = parseInt( parsedData.myJSONField );
1 Like

thx for your answer, but i want to receive and compute those data in my photon, ie not in javascript. I’m strugling with sscan() finction without any results for the moment.
like that:

scanf(data,"%u,%u,%u,%u",&buddyLightValue,&buddyLightValue,&buddySoundValue,&buddyMoveValue,&buddyPushValue);

If you provide the actual input string and the exact code you use, we might be able to help.

It’s sscanf() you want, and you should have same amount of receiving variables as you have place holders in the format string and you’d need to check the return value of sscanf() to know how many of your variables could be filled successfully.

yes sorry, i did use sscanf() without any good result.

Here is my code:

int led = D0;
int boardLed = D7;
int lightsensor = A0;
int soundsensor = A1;
int movesensor = A2;
int pushsensor = A3;
int power = A5;
int sensorValue = 0;
int needUpdate = 1;
int lightValue = 0;
int soundValue = 0;
int moveValue = 0;
int pushValue = 0;
int buddyLightValue = 0;
int buddySoundValue = 0;
int buddyMoveValue = 0;
int buddyPushValue = 0;

char message[40];
char receivedMessage[40];

char myName[12] = "lehio_3";
char buddyName[12] = "lehio_3";

void setup() {
    pinMode(led,OUTPUT); // Our LED pin is output (lighting up the LED)
    pinMode(boardLed,OUTPUT); // Our on-board LED is output as well
    pinMode(power,OUTPUT); // Our on-board LED is output as well
    Particle.subscribe(buddyName, myHandler);
    analogWrite(power,4095); // max 4095
}


void loop() {

    delay(5000); // 1000 = 1s - So scan every 5 sec
    // light data analysis
    sensorValue = analogRead(lightsensor)/16; // from 0-255
    analogWrite(led,sensorValue);
    if (sensorValue != lightValue) {
        needUpdate = 1;
        lightValue = sensorValue;
    }
// Here other data analysisi... (deleted)

    // send datas only if required
    if (needUpdate == 1) {
        sprintf(message,"%d,%d,%d,%d",lightValue,soundValue,moveValue,pushValue);
        sprintf(message,"%d",lightValue);
        Particle.publish(myName,message);
        needUpdate = 0;
    }
}

void myHandler(const char *event, const char *data)
{
    Particle.publish("debug1",data); // Here I have the requires data          
    sscanf(data,"%u,%u,%u,%u",&buddyLightValue,&buddyLightValue,&buddySoundValue,&buddyMoveValue,&buddyPushValue);
    sprintf(message,"%d",buddyLightValue);
    Particle.publish("debug2",message); // HERE IT DON'T WORK...
  }
}

Hi @sylvaing

Here some things that are wrong in your code:

  • Are you really using JSON structure in your publish? A JSON is a structure text representation that uses field names in double-quotes, followed by a colon, followed by the data. Your sscanf parameter string does not follow this format at all.

  • As @ScruffR pointed out above, you have four %u’s in your string but are passing five integer addresses.

  • The first integer address is repeated. I cannot imagine that this gives good, repeatable results.

1 Like

After reformatting your code it seems as if there is an error with your curly braces in the last function too.

You are using "%u" but have signed int as receiving variables. Is this intentional?

analogWrite() on a non DAC pin like your power (A5) supports max 255 and not 4095 as you use in this

 analogWrite(power,4095);

What's the point of the first printf() in this?

    if (needUpdate == 1) {
        sprintf(message,"%d,%d,%d,%d",lightValue,soundValue,moveValue,pushValue);
        sprintf(message,"%d",lightValue);
        Particle.publish(myName,message);
        needUpdate = 0;
    }

What exactly "don't work"?`

    Particle.publish("debug2",message); // HERE IT DON'T WORK...

I can't see this in your post.
What does the string you actually receive look like?
What do you see published as debug1 and debug2?
We can guess what it should look like from reading the code and we could flash your code to our own devices and try, but since you already got that data, just post it.
Also with a description what you'd expect it to look like.

1 Like

Hello and thank’s for this help. Sorry i had so many changes in this code that it took me some time (and a broken internet access…). Thank’s for your patience.

The aim: each device have 4 sensors, and should send it’s data (int) to the other. As @bko wrote it, I’m not currently using a JSON structure but would be ok to do it, but i’m currently not able to translate the data (one char) from the cloud in multiple integer.

I’m using also particle.publish() to debug, here is what I currently get (after your corrections @ScruffR):

lehio_3 - 0,60,71,94 // as expected
debug1 - 0,60,71,94 // as expected
debug2 - 536871772,536871760,536871748,536871780 // UNEXPECTED

Here is the full & corrected code:

int led = D0;
int boardLed = D7;
int lightsensor = A0;
int soundsensor = A1;
int movesensor = A2;
int pushsensor = A3;

int power = A5;

int sensorValue = 0;
int needUpdate = 1;

int lightValue = 0;
int soundValue = 0;
int moveValue = 0;
int pushValue = 0;

int buddyLightValue = 0;
int buddySoundValue = 0;
int buddyMoveValue = 0;
int buddyPushValue = 0;

char message[40];
char receivedMessage[40];

char myName[12] = "lehio_3";
char buddyName[12] = "lehio_3";

// SETUP
void setup() {
    pinMode(led,OUTPUT); // Our LED pin is output (lighting up the LED)
    pinMode(boardLed,OUTPUT); // Our on-board LED is output as well
    pinMode(power,OUTPUT); // Our on-board LED is output as well

  // Register to buddy
  Particle.subscribe(buddyName, myHandler);
  analogWrite(power,255); // max 4095
}


void loop() {

    delay(5000); // 1000 = 1s - So scan every 5 sec

    // light data analysis
    sensorValue = analogRead(lightsensor)/16; // from 0-255
    analogWrite(led,sensorValue);
    if (sensorValue != lightValue) {
        needUpdate = 1;
        lightValue = sensorValue;
    }

    // sound data analysis
    sensorValue = analogRead(soundsensor)/16; // from 0-255
    if (sensorValue != soundValue) {
        needUpdate = 1;
        soundValue = sensorValue;
    }

    // move data analysis
    sensorValue = analogRead(movesensor)/16; // from 0-255
    if (sensorValue != moveValue) {
        needUpdate = 1;
        moveValue = sensorValue;
    }

    // push data analysis
    sensorValue = analogRead(pushsensor)/16; // from 0-255
    if (sensorValue != pushValue) {
        needUpdate = 1;
        pushValue = sensorValue;
    }

    // send datas only if required
    if (needUpdate == 1) {
        sprintf(message,"%d,%d,%d,%d",lightValue,soundValue,moveValue,pushValue);
        Particle.publish(myName,message); // sendind data to the cloud eg:
        needUpdate = 0;
    }
}

void myHandler(const char *event, const char *data)
{
    Particle.publish("debug1",data);
    sscanf(data,"%d,%d,%d,%d",&buddyLightValue,&buddySoundValue,&buddyMoveValue,&buddyPushValue);
    sprintf(message,"%d,%d,%d,%d",&buddyLightValue,&buddySoundValue,&buddyMoveValue,&buddyPushValue); // just to verify the data
    Particle.publish("debug2",message);
}

Thank’s for this help!

On that point that was a test, the example below is using %d which is required as I understood.

Thx

Hi @sylvaing

I think you are very close–the problem is that you are using the address operator & with sprintf where it is not needed. This means that you are printing the addresses of your variables and not their contents. You do need the &'s for sscanf.

    sprintf(message,"%d,%d,%d,%d",buddyLightValue,buddySoundValue,buddyMoveValue,buddyPushValue); 
1 Like

I agree with @bko.
You had that right in your initial code and even in the current code in loop()

...
void loop() {
    ...
    // send datas only if required
    if (needUpdate == 1) {
        sprintf(message,"%d,%d,%d,%d",lightValue,soundValue,moveValue,pushValue);
        Particle.publish(myName,message); // sendind data to the cloud eg:
        needUpdate = 0;
    }
}

Once you correct this, you should be done - otherwise just post the results that you get then.

Pff I was ready to open the champain and to thank you @ScruffR and @bko , but no:

The result of debug2 is 0,0,0,0 or 9,0,0,0 or 5,0,0,0, with no real reason for this change…

This is starting to be weird, but I’m sure it’s a stupid thing…

I guess I’ve got to run that on my own device after all.

that would be very helpfull :wink:

And I think I’ve got the problem already - shame on me that I didn’t think of it earlier, since it’s a known problem.

Particle.publish() and Particle.subscribe() do use the same internal buffer, hence your first publish inside the handler will already start overwriting your input data before your subscribe handler can process that data.
If you remove that publish, your sscanf() will succeede (at least it does for me).

If you need to publish inside the handler make sure to process or copy the data before that.

3 Likes

Guess what? You are right! Many many thank’s, I’ll pay you a beer next time you come in France. I will publish the full project once it’s finished. And thank’s also @bko !

2 Likes

Thanks again. I’m going to start updating my serial output to stream variables in results data JSON format just as particle does. This way if I’m not online I can use a serial input program to get the same result as being online.