Ubidots Community

ESP32 and Ubidots: subscribing multiple variables

// callback:
void callback(char *topic, byte *payload, unsigned int length)
{
Serial.print(“Message arrived [”);
Serial.print(topic);
Serial.print("] ");
for (int i = 0; i < length; i++)
{
Serial.print((char)payload[i]);
}
Serial.println();
}

This is the callback function I am using.
I have subscribed to three different variables. All three of them gets printed together. How can I “take out” one of these variables and use the resultant value?

Hello @me

We’re glad to see you around the community!

Please refer to the code below, this is an example of the MQTT subscription for more than one variable at the same time with an ESP32.

//Include Libraries
#include "UbidotsEsp32Mqtt.h"

//Define Constants
const char *UBIDOTS_TOKEN = "YOUR-UBIDOTS-TOKEN";
const char *WIFI_SSID = "YOUR-WIFI";  
const char *WIFI_PASS = "YOUR-WIFI-PASSWORD";  
const char *DEVICE_LABEL = "YOUR-DEVICE-LABEL"; 
char *var_labels[] = {
  "YOUR-VARIABLE-LABEL-1",
  "YOUR-VARIABLE-LABEL-2",
  "YOUR-VARIABLE-LABEL-3",
  "YOUR-VARIABLE-LABEL-4"
  // Add more variable labels here. Do not forget the comma ;)
};

#define DIMENSION_OF(x) (sizeof(x)/sizeof(x[0]))

float var_last_values[DIMENSION_OF(var_labels)] = {};
Ubidots ubidots(UBIDOTS_TOKEN);

//Callback function
void callback(char* topic, byte* payload, unsigned int length) {
  // Limitations: Variable label must not be the same as device label
  
  char *topic_cpy = strdup(topic);
  char *payload_str = (char *) malloc(length + sizeof(""));
  char *topic_item = strtok(topic_cpy, "/");
  char *label = NULL;
  float value = NAN;
  size_t index = DIMENSION_OF(var_labels);
  size_t i;

  memcpy(payload_str, payload, length);
  payload_str[length] = '\0';
  
  while ((NULL != topic_item) && (NULL == label)) {
    for (i = 0; i < DIMENSION_OF(var_labels); i++) {
      if (0 == strcmp(var_labels[i], topic_item)) {
        label = topic_item;
        value = atof(payload_str);
        index = i;
        break;
      }
    }
    topic_item = strtok(NULL, "/");
  }

  if (index < DIMENSION_OF(var_labels)) {
    var_last_values[index] = value;
    
    Serial.print(label);
    Serial.print(": ");
    Serial.println(var_last_values[index]);
  }

  free(topic_cpy);
  free(payload_str);
}

//Suscribe function
void subscribe_to_vars(char **labels, size_t n_labels) {
  size_t i;
  for (i = 0; i < n_labels; i++) {
    char *label = labels[i];
    ubidots.subscribeLastValue(DEVICE_LABEL, label);
  }
}

//Print last values function
void print_last_values(void) {
  char str_buff[64] = "";
  size_t i;

  for (i = 0; i < DIMENSION_OF(var_labels); i++) {
    snprintf(str_buff, sizeof(str_buff), "%s: %f", var_labels[i], var_last_values[i]);
    Serial.println(str_buff);
  }
}

//Main functions
void setup()
{
  // put your setup code here, to run once:
  Serial.begin(115200);
  // ubidots.setDebug(true);  // uncomment this to make debug messages available
  ubidots.connectToWifi(WIFI_SSID, WIFI_PASS);
  ubidots.setCallback(callback);
  ubidots.setup();
  ubidots.reconnect();
  subscribe_to_vars(var_labels, DIMENSION_OF(var_labels));
}

void loop()
{
  // put your main code here, to run repeatedly:
  if (!ubidots.connected())
  {
    ubidots.reconnect();
    subscribe_to_vars(var_labels, DIMENSION_OF(var_labels));
  }
  ubidots.loop();
}

The next segment is the one that will allow you to use the variables received with the subscription in your code.

//Print last values function
void print_last_values(void) {
  char str_buff[64] = "";
  size_t i;

  for (i = 0; i < DIMENSION_OF(var_labels); i++) {
    snprintf(str_buff, sizeof(str_buff), "%s: %f", var_labels[i], var_last_values[i]);
    Serial.println(str_buff);
  }
}

NOTE : Bear in mind that the Ubidots library only supports the ESP32 platform version v.2.0.0. Please, when installing this platform, make sure that you’re using the correct version.

Let me know if you need anything else!

All the best,
Ángela