[SOLVED] Only one variable will publish using ESP32 and revised sample sketch


#1

Hello, adding upon the sample MQTT sketch I have the below sketch to publish 2 sensors and subscribe 2 relays. Only the one sensor publishes and creates a variable.

Can anyone tell me what I am missing?

#define VARIABLE_LABEL_PUBLISH "sensor" 
#define VARIABLE_LABEL_SUBSCRIBE "relay" 
#define VARIABLE_LABEL_PUBLISH "sensor2" 
#define VARIABLE_LABEL_SUBSCRIBE "relay2" 
#define DEVICE_LABEL "esp32" 

#define SENSOR 14 
#define RELAY 16 
#define SENSOR2 13 
#define RELAY2 15 

char mqttBroker[]  = "things.ubidots.com";
char payload[100];
char payload2[100];
char topic[150];
char topic2[150];
// Space to store values to send 
char str_sensor[10];
char str_sensor2[10];

/****************************************
 * Auxiliar Functions
 ****************************************/
WiFiClient ubidots;
PubSubClient client(ubidots);

void callback(char* topic, byte* payload, unsigned int length) {
  char p[length + 1];
  memcpy(p, payload, length);
  p[length] = NULL;
  String message(p);
  if (message == "0") {
    digitalWrite(RELAY, LOW);
  } else {
    digitalWrite(RELAY, HIGH);
  }
  Serial.write(payload, length);
  Serial.println();
}

void callback2(char* topic2, byte* payload2, unsigned int length) {
  char q[length + 1];
  memcpy(q, payload2, length);
  q[length] = NULL;
  String message(q);
  if (message == "0") {
    digitalWrite(RELAY2, LOW);
  } else {
    digitalWrite(RELAY2, HIGH);
  }
  Serial.write(payload2, length);
  Serial.println();
}

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.println("Attempting MQTT connection...");
    
    // Attemp to connect
    if (client.connect(MQTT_CLIENT_NAME, TOKEN, "")) {
      Serial.println("Connected");
      client.subscribe("/v1.6/devices/"DEVICE_LABEL"/"VARIABLE_LABEL_SUBSCRIBE"/lv");
    } else {
      Serial.print("Failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 2 seconds");
      // Wait 2 seconds before retrying
      delay(2000);
    }
  }
}

/****************************************
 * Main Functions
 ****************************************/
void setup() {
  Serial.begin(115200);
  WiFi.begin(WIFISSID, PASSWORD);
  // Assign the pins as INPUT/OUTPUT 
  pinMode(SENSOR, INPUT);
  pinMode(RELAY, OUTPUT);
  pinMode(SENSOR2, INPUT);
  pinMode(RELAY2, OUTPUT);

  Serial.println();
  Serial.print("Wait for WiFi...");
  
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(500);
  }
  
  Serial.println("");
  Serial.println("WiFi Connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  client.setServer(mqttBroker, 1883);
  client.setCallback(callback);
  client.setServer(mqttBroker, 1883);
  client.setCallback(callback2);
  
  client.subscribe("/v1.6/devices/"DEVICE_LABEL"/"VARIABLE_LABEL_SUBSCRIBE"/lv");
}

void loop() {
  if (!client.connected()) {
    reconnect();
    client.subscribe("/v1.6/devices/"DEVICE_LABEL"/"VARIABLE_LABEL_SUBSCRIBE"/lv");   
  }
  sprintf(topic, "%s%s", "/v1.6/devices/", DEVICE_LABEL); 
  sprintf(topic2, "%s%s", "/v1.6/devices/", DEVICE_LABEL);  
  sprintf(payload, "%s", ""); // Cleans the payload
  sprintf(payload2, "%s", ""); // Cleans the payload2
  sprintf(payload, "{\"%s\":", VARIABLE_LABEL_PUBLISH); // Adds the variable label
  sprintf(payload2, "{\"%s\":", VARIABLE_LABEL_PUBLISH); // Adds the variable label
  
  float sensor = analogRead(SENSOR);
  float sensor2 = analogRead(SENSOR2); 
  
  /* 4 is mininum width, 2 is precision; float value is copied onto str_sensor*/
  dtostrf(sensor, 4, 2, str_sensor);
  dtostrf(sensor2, 4, 2, str_sensor2);
  
  sprintf(payload, "%s {\"value\": %s}}", payload, str_sensor); // Adds the value
  sprintf(payload2, "%s {\"value\": %s}}", payload2, str_sensor2); // Adds the value
  Serial.println("Publishing data to Ubidots Cloud");
  client.publish(topic, payload);
  client.publish(topic2, payload2);
  client.loop();
  delay(1000);
}


#2

Greetings @richrich36,

Looking into your code I see some errors:

  1. You are trying to publish to two different variables but you have defined only one labeled as ‘VARIABLE_LABEL_PUBLISH’, you should use two different variables if you wish to publish to two different topics.

  2. You are using two callback functions, I am not sure if the PubSubclient library supports this so I advise you to code only one of them.

I advise you too to refer to this article to know how to create properly your MQTT requests.

Also, the code below may serve you as reference too to reach your goal:

/****************************************
 * Include Libraries
 ****************************************/
 
#include <PubSubClient.h>
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <stdio.h>  


/****************************************
 * Define Constants
 ****************************************/

#define WIFISSID "...." // Put your WifiSSID here
#define PASSWORD "...." // Put your wifi password here
#define TOKEN "...." // Put your Ubidots' TOKEN
#define VARIABLE_LABEL "..." // Assing the variable label
#define VARIABLE_LABEL_2 "...." // Assing the variable label
#define DEVICE_LABEL "...." // Assing the device label
#define MQTT_CLIENT_NAME "...." // MQTT client Name

char mqttBroker[] = "things.ubidots.com";
char payload[700];
char topic[150];
char topic2[150];

// Space to store values to send
char str_temp[6];
char str_lat[6];
char str_lng[6];


/****************************************
 * Initializate constructors for objects
 ****************************************/

ESP8266WiFiMulti WiFiMulti;
WiFiClient ubidots;
PubSubClient client(ubidots);


/****************************************
 * Auxiliar Functions
 ****************************************/
 
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();
} 

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.println("Attempting MQTT connection...");
    
    // Attempt to connect
    if (client.connect(MQTT_CLIENT_NAME, TOKEN,"")) {
      Serial.println("connected");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 2 seconds");
      // Wait 2 seconds before retrying
      delay(2000);
    }
  }
}


/****************************************
 * Main Functions
 ****************************************/
 
void setup() {
    Serial.begin(115200);
    pinMode(A0, INPUT);
    WiFiMulti.addAP(WIFISSID, PASSWORD);
    Serial.println();
    Serial.println();
    Serial.print("Wait for WiFi... ");

    while(WiFiMulti.run() != WL_CONNECTED) {
        Serial.print(".");
        delay(500);
    }
    
    Serial.println("");
    Serial.println("WiFi connected");
    Serial.println("IP address: ");
    Serial.println(WiFi.localIP());
    client.setServer(mqttBroker, 1883);
    client.setCallback(callback);
}

void loop() {

    if (!client.connected()) {
      reconnect();

      // Subscribes for getting the value of the control variable in the temperature-box device
      char topicToSubscribe[200];
      sprintf(topicToSubscribe, "%s", ""); // Cleans the content of the char
      sprintf(topicToSubscribe, "%s%s", "/v1.6/devices/", "temperature-box");
      sprintf(topicToSubscribe, "%s/%s/lv", topicToSubscribe, "control");
      client.subscribe(topicToSubscribe);
    }
    
    // Values to send
    float temperature = random(0, 9);
    float lat = 6.101;
    float lng= -1.293;
    
    /* 4 is mininum width, 2 is precision; float value is copied onto str_temp*/
    dtostrf(temperature, 4, 2, str_temp);
    dtostrf(lat, 4, 2, str_lat);
    dtostrf(lng, 4, 2, str_lng);

    sprintf(topic, "%s", ""); // Cleans the topic content
    sprintf(topic, "%s%s", "/v1.6/devices/", DEVICE_LABEL);

    sprintf(payload, "%s", ""); // Cleans the payload content
    sprintf(payload, "{\"%s\":", VARIABLE_LABEL); // Adds the variable label   
    sprintf(payload, "%s {\"value\": %s", payload, str_temp); // Adds the value
    sprintf(payload, "%s, \"context\":{\"lat\": %s, \"lng\": %s}", payload, str_lat, str_lng); // Adds coordinates
    sprintf(payload, "%s } }", payload); // Closes the dictionary brackets
    client.publish(topic, payload);
    
    sprintf(topic2, "%s", ""); // Cleans the topic content
    sprintf(topic2, "%s%s", "/v1.6/devices/", DEVICE_LABEL);

    sprintf(payload, "%s", ""); // Cleans the payload content
    sprintf(payload, "{\"%s\":", VARIABLE_LABEL_2); // Adds the variable label   
    sprintf(payload, "%s {\"value\": %s", payload, str_temp); // Adds the value
    sprintf(payload, "%s, \"context\":{\"lat\": %s, \"lng\": %s}", payload, str_lat, str_lng); // Adds coordinates
    sprintf(payload, "%s } }", payload); // Closes the dictionary brackets
    
    client.publish(topic2, payload);
    client.loop();
    delay(1000);
}

Regards