Black Lives Matter - Action and Equality.
0

MQTT data types for .publish
Moderators: adafruit_support_bill, adafruit

Forum rules
If you're posting code, please make sure your code does not include your Adafruit IO Active Key or WiFi network credentials.
Please be positive and constructive with your questions and comments.

MQTT data types for .publish

by Systembolaget on Sun Apr 19, 2020 4:57 pm

I have two problems with Adafruit's MQTT .publish function. I tested publishing the data types below and found that apparently only three are accepted. Is that so and why is that so? I could not find that explained in the Adafruit MQTT learning guides.

Code: Select all | TOGGLE FULL SIZE
void loop()
{
  MQTT_connect();

  // bool x = TRUE; // = call of overloaded 'publish(bool&)' is ambiguous
  // byte x = 255; // = call of overloaded 'publish(byte&)' is ambiguous
  // int x = -32768; // = call of overloaded 'publish(int&)' is ambiguous
  // long x = -2147483648; // okay
  // float x = 21.43; // okay
 
  // uint8_t x = 255; // = call of overloaded 'publish(uint8_t&)' is ambiguous
  // int16_t x = -32768; // = call of overloaded 'publish(int16_t&)' is ambiguous
  uint32_t x = 4294967295; // okay

  sometopic.publish(x);

  delay(5000);
}
Then I also discovered that one cannot directly .publish a struct member

Code: Select all | TOGGLE FULL SIZE
struct structname
{
  long structmember;
  float anotherstructmember;
  uint32_t yetanotherstructmember;
} structvariable;

void loop()
{
  MQTT_connect();

  sometopic.publish(structvariable.structmember);

  delay(5000);
}
because that also results in the call of overloaded 'publish(structvariable.structmember&)' is ambiguous error, so one has to go via an intermediate variable that has a struct's member assigned prior to .publish. Is that so, or is there a better way, particularly when wanting to publish each struct member at its own interval with millis().

Systembolaget
 
Posts: 227
Joined: Wed Mar 08, 2017 1:01 pm

Re: MQTT data types for .publish

by Systembolaget on Mon Apr 20, 2020 2:00 am

So, no need to go through an intermediate variable.

A bool, byte and int data type variable, whether as struct member or not, must be cast explicitly into one of the three accepted data types in the .publish() function, and then it works. This is the case even when struct members are already defined with one of the three accepted data types like long, float and uint32_t.

Code: Select all | TOGGLE FULL SIZE
sometopic.publish((cast into accepted data type)structvariable.structmember);
Would have been good if that were in the beginner documentation.

Systembolaget
 
Posts: 227
Joined: Wed Mar 08, 2017 1:01 pm

Re: MQTT data types for .publish

by Systembolaget on Thu Apr 23, 2020 5:08 pm

One can thus arrive at a generic publishData function for many feeds to publish themselves at different intervals.

Code: Select all | TOGGLE FULL SIZE
struct structname // A struct that contains various variables (struct members); a struct is not per se necessary
{
  byte feed1structmember;
  bool feed2structmember;
  int feed3structmember;
  long feed4structmember;
} structvariable;

const int intervalFeed1 = 20000; // The feed 1 shall be published every 20 seconds
unsigned long nowFeed1 = 0; // Timestamp for feed 1
// Other feed timing variables go here

Adafruit_MQTT_Publish feed1 = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/feed1"); // Instanced object for feed 1
// Other feed objects go here

void setup()
{
  // Stuff
}

void loop()
{
  publishData(nowFeed1, intervalFeed1, feed1, (long) structvariable.feed1); // Publish data to feed 1 and cast the struct variable into a long, which is an allowed data type; that way one can use byte, bool, int and long as data variables
  // Other feeds to be published go here
  // Stuff
}

void publishData(unsigned long &now, const int interval, Adafruit_MQTT_Publish &feed, const long structmember) // Pass memory address of timestamp so the function can modify it, use the interval, pass memory address of the instanced object, use the struct variable
{
  if (millis() - now >= interval)
  {
    now = millis();

    MQTT_connect();

    feed.publish(structmember);
  }
}
Might be useful for other users.

Systembolaget
 
Posts: 227
Joined: Wed Mar 08, 2017 1:01 pm

Please be positive and constructive with your questions and comments.