MQTT and functions

I am working on a LAN project using the MQTT library and seem to have come across a minor issue. as far as reading values and posting them to the local server, all is good. however, events that i publish on the server, are unavailable to the photon. i can’t seem to find a way using subscription nor is there a MQTT.function call. any suggestions? to give an example of what i want, if i post 255 to the topic “red”, i want my rgb led to update the value of red to 255.

If you can show what you have tried and tell us how that didn't work we may be able to advise better.

This library example shows how you'd subscribe to a topic and act on and incoming event (i.e. void callback(char* topic, byte* payload, unsigned int length)) on that subscription.

Also what tool are you using to send/receive topics for testing?
I like MQTTBox for Chrome.

BTW, what exactly dows that mean

Do you mean the MQTT broker?
The broker commonly wouldn't publish events by itself. It's rather a "passive" relay station for events published by a client should me sent to all subscribing clients.

i primarily use MQTT.fx as a test client. the end application uses paho. yes, i was referring to messages i publish to the broker directly from a client. since there is not a mqtt.function command, there is no code to share for that one. i did try with mqtt.subscribe as follows.

setup:
connect and int of variables
int Bval;

loop:
mqtt.subscribe(‘bvalues’);
Bval=bvalues;

mqtt client:
bvalues 200

field not updated to 200. i didn’t try the callback you shared, perhaps that’s the missing link.

Exactly. Incoming messages (topics) are processed by the callback function. If that callback doesn't do anything with that message it will just vanish.

The example from the MQTT library works perfectly for both publish and subscribe - get this working first and then modify to suit what you want to achieve.

Here is a simplified version to get you going - create, name and save a new app, then add the MQTT library to this app. Then try this code

#include "MQTT.h"

void callback(char* topic, byte* payload, unsigned int length);

/**
 * if want to use IP address,
 * byte server[] = { XXX,XXX,XXX,XXX };
 * MQTT client(server, 1883, callback);
 * want to use domain name,
 * exp) iot.eclipse.org is Eclipse Open MQTT Broker: https://iot.eclipse.org/getting-started
 * MQTT client("iot.eclipse.org", 1883, callback);
 **/
MQTT client("server_name", 1883, callback);

// recieve message
void callback(char* topic, byte* payload, unsigned int length) {
    char p[length + 1];
    memcpy(p, payload, length);
    p[length] = NULL;

    Serial.print( "Got a message : " );
    Serial.print( P );

}


void setup() {
    // connect to the server
    client.connect("sparkclient");

    // publish/subscribe
    if (client.isConnected()) {
        Serial.print("\nConnected");
        client.publish("outTopic/message","hello world");
        client.subscribe("inTopic/message");
    }
}

void loop() {
    if (client.isConnected())
        client.loop();
}

Then subscribe MQTT.fx session to outTopic on your broker and then publish something to the inTopic…

2 Likes

ok, here is my sanitized code. i am currently having success with the function call, but since this requires internet, its not a viable final code. as you see, the values topic at the end, should see the value and update the brightness integer, which would be way shorter than 255 else statements. oh, and i had the callback all along, just forgot it was there.

You can use any MQTT server including a local one (e.g. RasPi)

You can always use atoi() to convert your string into an integer :wink:
For String objects (which we usually discurage using) you'd just write strip.setBrightness(command.toInt());).

You only subscribe once. Whenever an event arrives you previously had subscribed to the callback function will be called to process the data (which you don't anywhere - you just copy the payload and immediately discard that copy again).

As @shanevanj already said, you should go back to the example and investigate how and why that works.

Here mqtt_payload is not initialised, so when you

client.publish("Payload",mqtt_payload);

it publishes random values to the topic Payload.

In your function void GetAppVar() this assignment

brightness = client.subscribe(“values”);  

will become the return code of client.subscribe(“values”).

Your brightness value will be returned when a message is received from the broker and is found in the payload inside the call back function

void callback(char* topic, byte* payload, unsigned int length)

Your Loop() function does not call the MQTT functions as described in the example so you will NEVER get any messages anyway.

void loop() {
    if (client.isConnected())
        client.loop();
}

Did you get the example working? Please do this first and report back your results

1 Like

publishing works just fine, like i said, i sanitized the code, so there are some parts missing. i’ll add the client.loop, but i still need to set wwhat is received as the variable. should it be brightness=callback.payload? this is what i am having issues finding.

i got it, using the atoi(). itll take some work, but i need to find a way to sub to several topics later for another project. thanks for the help!

That'd work just the same with one callback where you distinguish which message you got by parsing and branching accoring to the topic parameter the callback gets handed.

Just for curiosity: What programming background do you have?
It might be easier to advise if we knew what language you are coming from - the questions asked above suggest it's not C/C++ :wink:

1 Like

Hi shanevanj, Is this possible with two photon devices? I want device to device communication, both devices being able to publish and subscribe to one another, and use subscribe handlers to acquire data.

I have gotten it to work with Particle Cloud - Particle.publish/subscribe, however it is not efficient enough for IOT Blynk applications. You can view my code here for the Particle Cloud application on both devices.

Hi, So devices cannot publish an subscribe to each other - you need to use an MQTT broker in the middle - so P1 & P2 could subscribe and publish to the same topic i.e. PhotonBroadcast and this will act like an all stations broadcast then your call back each device can process the messages - if you had more devices then perhaps you could add a relevance object to the message i.e. 0 is valid for all devices but is for a specific device.

I use mosquito as a broker for doing similar stuff and host it in a RaspberryPI - I have processed more than a thousand messages a second with no issues on this relatively cheap platform. Of course you could also write code on the PI (I used python) to subscribe/publish to the same topic as above and then send/relay the data onto another platform like blynk or ubidots etc

1 Like