Need some help with Mesh.subscribe

Hi all,

I’m a little lost on how to get mesh.subscribe to do what I need, hoping someone can point me in the right direction.

I have a bunch of Xenons doing mesh.publish and I have an Argon which I want to use to gather the data and post it to an MQTT broker.

I don’t fully understand the syntax of the following:

void myHandler(const char *event, const char *data)
{
  Serial.printlnf("event=%s data=%s", event, data ? data : "NULL");
}

void setup()
{
  Serial.begin(9600);
  Mesh.subscribe("motion-sensor", myHandler);
}

How would I go about getting the value of the *data component that’s getting published by my Xenon devices, as a variable so I can use the Argon to process it accordingly? The Particle documentation doesn’t go into much detail about how this function is constructed.

Thanks!

Here’s an excerpt from my MarcoPolo heartbeat code which you can find in this thread. This code will subscribe to a Mesh.publish message called “Polo”. When it receives that publish, it runs the ProcessBeat() function which records the message in an array and the time when it reported.

//Before setup(), declare the variables.
#define MAX_MESH_NODES 10  //Maximum number of nodes expected on the mesh. Make small as possible to preserve memory space.

uint8_t reportingNodesCount = 0;
char reportingNodes[MAX_MESH_NODES][32];

void setup() {
    //Here we are subscribing to the event named "Polo".
    Mesh.subscribe("Polo", ProcessBeat);
}

void ProcessBeat(const char *name, const char *data) {
    //Record the device that is responding and exit fast. Don't do lengthy tasks here.

    //Here I'm just keeping track of the number of nodes that responded to this message so far.
    uint8_t count = reportingNodesCount++;

    //The sprintf command copies the contents of data into my repoortingNodes array.
    snprintf(reportingNodes[count], arraySize(reportingNodes[count])-1, data);

    //Here we record the time (in milliseconds since start) that the function ran.
    reportingNodesMillis[count] = millis();
}
2 Likes

I have a follow up question about particle.subscribe.

Is it feasible to subscribe to multiple topics from a Xenon? I’m trying to get that to work and my results seem to be intermittent.

The following code runs on my Argon:

#include <MQTT.h>


MQTT client("192.168.0.34", 1883, callback);
void callback(char* topic, byte* payload, unsigned int length) {
    char p[length + 1];
    memcpy(p, payload, length);
    p[length] = NULL;

    if (!strcmp(p, "RED"))
        RGB.color(255, 0, 0);
    else if (!strcmp(p, "GREEN"))
        RGB.color(0, 255, 0);
    else if (!strcmp(p, "BLUE"))
        RGB.color(0, 0, 255);
    else
        RGB.color(255, 255, 255);
    delay(1000);
}

void setup() {

client.connect("sparkclient");
Mesh.subscribe("Watertank/Voltage", myHandler);
Mesh.subscribe("Watertank/Volume", myHandler);

}

 
 void loop() {
 
 
}

//Event listener for event from Xenons
void myHandler(const char *event, const char *data)
{
if (client.isConnected()) {
        //Publish to MQTT
        client.publish(event, data);
        delay(2000);
        
//Publish to the cloud.
        Particle.publish(event, data);
 }

I don’t always see the Xenon report the same data. Of the three variables I’m pushing to the Argon, I sometimes get one, other times two and sometimes all three, but it’s not consistent. Or, maybe it’s the Argon failing to publish the data correctly, I’m not sure.

Any advice would be appreciated.

You should be able to Mesh.subscribe("Watertank/", myHandler") and catch both events with one handler

https://docs.particle.io/reference/device-os/firmware/xenon/#subscribe-

Mesh.publish() is done via UDP broadcast/multicast and hence delivery is not guaranteed.
You should also check your publishing rate to obey the limits.

A word of caution:
When using Particle.publish() inside a subscribe handler it's best to first copy the data.
Although here you are using a Mesh.subscribe() and a Particle.publish() that will probably not cross-talk but Particle.subscribe() and Particle.publish() definetly do and Mesh.xxx() may too.

1 Like

This is very helpful, thanks so much!

1 Like

I assume that it is supposed to be possible though - subscribing to many different topics ??

As many topics as you wish, as long they start with your chosen prefix :wink:

To be clear, can you make multiple calls to Mesh.Subscibe() each with a separate prefix?

Yes you can, but I think it behaves similar to Particle.subscribe() and the number of parallel subscriptions is limited (although that seems not yet documented, so I could be wrong - I’ll check).

But you should be able to check by catching the return value of Mesh.subscribe() which should return true for successful subscriptions.


Update:
There are up to 5 concurrent subscriptions possible with mesh and the documents are being updated right now.

2 Likes

If anyone is interested, here are my GitHub repositories for the Xenon publisher and Argon subscriber:


The Xenon reads the temperature from a Dallas DB18B20, and publishes it to the Mesh, where the Argon subscribes to the messages and pushes them onto my MQTT queue.
This works well with my home-built sensor network using NRF24L01+ hub-and-spoke configuration and pushing to an MQTT queue.
Works GREAT! Anything that can publish to MQTT eventually pushes to GroveStreams for analysis. Fit into my existing setup quite well!

1 Like