Help to send integer via mqtt

Hi, I'm trying to send an int as the payload for a mqtt message.

I'm using the mqtt library on an Argon, and this publish statement works fine, but the value is static and text:

client.publish("Speed", "100");

I have declared a variable:

int rpm;

that I want to send - my first attempt at doing this, was -

client.publish("Speed", rpm);
(edited above line...)

and I receive this:

"message": "no instance of overloaded function \"MQTT::publish\" matches the argument list -- argument types are: (const char [6], int) -- object type is: MQTT",

How can I format the integer rpm so I can send it??

@jimbol ,

This may be a typo but, just to make sure. When you said:

You meant:

client.publish("Speed",rpm);

Would this work?

Chip

1 Like

Youā€™re right, typo! Thx.
Oops.

I think the second part of the argument canā€™t be an integer, but Iā€™m not sure how to make it into the right type of variable. Iā€™m editing the post above.

With MQTT you typically send ā€œanonymousā€ byte streams. So you can send whatever data you want, you just need to make sure that the receiving end has some means to decode that byte stream into something meaningful.

e.g. with int you need to make sure that both sides use the same endianness and also the same length (16bit vs. 32bit).

For such data youā€™d use this overload

    bool publish(const char *topic, const uint8_t *pyaload, unsigned int plength);

i.e.

  client.publish("Speed", &rpm, sizeof(rpm));
1 Like

maaaan, I had to search for that one! Endianness - Wikipedia
thank you for the tip

2 Likes

Hi @ScruffR, that helped, I got it to compile, and it sends an MQTT message. It does however still have an issue, if I use that code and send &rpm when it is equal to 99, when I see the message in an mqtt explorer, I get the output:

Speed = c

I suppose that is the Endianness you were talking about.

When I receive the data at the other end, I am just displaying it, not doing any calculations, so I think if I can figure out how to turn the integer 99 into an ascii 99 or a string, it will work. But I'm not sure how to do that. I definitely have a hole in my knowledge about how to use the different variable types, and how to cast them from one type to another.

How are you catching and interpreting the data?
Even if you may not consider this a calculation it's still treatment of the incoming bit stream.

Nope, that hasn't got anything to do with endianness, but with conflicting data types.
You are sending a binary number (int packed into 32 bits) and catch it as character[s].

99 is the decimal representation of the binary bit stream 0110 0011 (0x63) which is the ASCII value for the character 'c'.
So you are in fact already doing that, but this is obviously not what you want :wink:
When you want the ASCII/string representation of "99" then you'd need the ASCII value for the digit character of '9' (= decimal 57 or 0x39) twice.

When you send a binary number you need to catch and interpret it as exactly that.

OK, I just canā€™t get itā€¦

Iā€™ll look at it from the example code perspective:

Using very slight changes to the example code - I have added the broker info to reflect my local broker address, added the integer that I want to publish, and the publish command:

byte server[] = { 10,240,140,72 };
MQTT client(server, 1883, callback);

uint8_t rpm = 99;
client.publish("Speed", &rpm, sizeof(rpm));

If I run the example code (complete code below), I think I should be able to see the integer 99 - (Iā€™m using a third party MQTT explorer on my Mac to view this data, subscribed to everything.) Am I not declaring the variable correctly? Maybe the full code will be helpful so I can get pointed in the right direction to send/receive the integersā€¦ I have the same result when I view the data on a different type of device, and If I instruct that device to send the integer 99 via mqtt, it arrives as expected.

What can I do to see the integer? It seems like the particle code isnā€™t recognizing that Iā€™m sending an integer, even though it looks like the uint8_t data type should be expected by the library, it seems like it should be simple.

full 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("mqtt.eclipse.org", 1883, callback);
 **/

byte server[] = { 10,240,140,72 };
MQTT client(server, 1883, callback);
uint8_t rpm = 99;
// recieve message
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() {
    RGB.control(true);

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

    // publish/subscribe
    if (client.isConnected()) {
        client.publish("outTopic/message","hello world");
        client.publish("Speed", &rpm, sizeof(rpm));
        client.subscribe("inTopic/message");
    }
}

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

If this is the case then you seem to need to send the data in string format as your explorer only displays these correctly.

If you are only in control in one side of the communication, this is where you need to comply to the format the other side calls for.

Since it the receiving sides demands a string you need to send a string
e.g. like this

  char payload[16];
  snprintf(payload, sizeof(payload), "%u", rpm);
  client.publish("Speed", payload);

@ScruffR , thanks, I just gave that a try and it works! Since I just need to display the number, it works for my purpose. But I still think that there is something going wrong in the particle code,

Every method Iā€™ve used to view the MQTT data shows
Speed = c

Iā€™ve tried viewing this on several different Mqtt apps on mac and IOS, and have used code on an ESP32, all of these show ā€˜cā€™ when the Argon sends ā€˜99ā€™. If I use an ESP32 to send the number 99, it shows up as 99. My micropython is almost nonexistent, and Iā€™m using Blockly to program the ESP32, so I am not really sure how the variable holding the 99 is formatted, but it sure seems like an issue with the particle code.

Nope, the Particle code is not the issue. You are just not using the correct code on the ESP side.

If you post the code you use on the ESP we can point you to the issue and provide an alternative that will work.

The appearance of things may well fool you when you don't know the facts :wink:

1 Like

Thatā€™s why I left the room for doubt!! Itā€™s working currently as the String ( I only need to see the value), so probably wonā€™t bother working on making the integer work, unless I find the need to do some calculations after receiving the dataā€¦ thx