It's Holiday Sale Weekend at Adafruit - use the code ADATY to get 15% off items storewide! Some restrictions apply.
0

MQTT subscriptions callback doesn't work
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 subscriptions callback doesn't work

by aelorenzo on Sun Oct 17, 2021 5:52 pm

Hi all!

I have an Arduino Sketch for an ESP32 board (ESPDUINO), configured to use my free MQTT Adafruit IO account services.

I am subscribed to two feeds linked to the dashboard (a slider and a button), and defined as follows:

Slider: Name: led-int Key: led-int
Button: Name: led-onoff Key: led-onoff

and I publish in two feeds without any problem with the same wificlientsecure instance (mqtt).

If I modified the value of the slider or the button state in the dashboard, no data arrived to the device.

I have tried several ways to setup the subs, etc...

any help please?

The code declarations for the subs are:

Code: Select all | TOGGLE FULL SIZE
// Setup the MQTT client class by passing in the WiFi client and MQTT server and login details.
Adafruit_MQTT_Client mqtt(&client, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_KEY);

/****************************** Feeds ***************************************/

// Setup feeds for subscribing
Adafruit_MQTT_Subscribe LED_int_feed = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "/feeds/led-int", MQTT_QOS_1);
Adafruit_MQTT_Subscribe LED_onoff_feed = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "/feeds/led-onoff", MQTT_QOS_1);


void LEDintcallback(double x) {
  Serial.print("Hey we're in a slider callback, the slider value is: ");
  Serial.println(x);
}

void LEDonoffcallback(char *data, uint16_t len) {
  Serial.print("Hey we're in a onoff callback, the button value is: ");
  Serial.println(data);
}


And in the setup():

Code: Select all | TOGGLE FULL SIZE
// Set Adafruit IO's root CA
  client.setCACert(adafruitio_root_ca);

  // Ensure the connection to the MQTT server is alive (this will make the first
  // connection and automatically reconnect when disconnected).  See the MQTT_connect
  // function definition further below.
  MQTT_connect();

  Serial.println("done");

  Serial.print("Starting MQTT client... ");
/*
 * Subscribing configuration
 */

  LED_int_feed.setCallback(LEDintcallback);
  LED_onoff_feed.setCallback(LEDonoffcallback);

// Setup MQTT subscription
  mqtt.subscribe(&LED_int_feed);
  mqtt.subscribe(&LED_onoff_feed);


In the loop() section:

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

  // Now we can publish stuff!

  if (! TD_feed.publish(tdsValue)) {
    Serial.println(F("Failed TD feed"));
  } else {
    Serial.println(F("TD feed published"));
  }

  if (! Temp_feed.publish(tempavg)) {
    Serial.println(F("Failed temperature feed"));
  } else {
    Serial.println(F("Temperature feed published"));
  }

  Serial.println();

// MQTT subcriptions
// this is our 'wait for incoming subscription packets and callback em' busy subloop
// try to spend your time here:

  mqtt.processPackets(10000);

aelorenzo
 
Posts: 5
Joined: Sun Oct 17, 2021 3:44 pm

Re: MQTT subscriptions callback doesn't work

by brubell on Mon Oct 18, 2021 9:33 am

Could you please copy and paste the full code here so I can take a look, thank you.

brubell
 
Posts: 1557
Joined: Fri Jul 17, 2015 10:33 pm

Re: MQTT subscriptions callback doesn't work

by aelorenzo on Mon Oct 18, 2021 3:33 pm

Hi @brubell,

Here is a sketch that I used just to test the Adafruit IO functions.

I trimmed all the "not related" code.

Code: Select all | TOGGLE FULL SIZE
 /*
 * DESCRIPTION
 *   
 */

#include <WiFi.h>
#include "WiFiClientSecure.h"
#include "Adafruit_MQTT.h"
#include "Adafruit_MQTT_Client.h"
#include <ESPmDNS.h>
#include <Pushover.h>
#include <IRremoteESP8266.h>
#include <NTPClient.h>
#include <WiFiUdp.h>
#include <TimeLib.h>
#include <Timezone.h>
#include <time.h>
#include <IRutils.h>
#include <IRsend.h>
#include <RCSwitch.h>
#include <Dusk2Dawn.h>
#include "config.h"
#include <OneWire.h>
#include <DallasTemperature.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Fonts/Org_01.h>

static const uint8_t LED_BUILTIN = 2;
#define BUILTIN_LED  LED_BUILTIN // backward compatibility

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET     -1 // Reset pin # (or -1 if sh aring Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

/************************* Adafruit.io Setup *********************************/

// Create an ESP32 WiFiClient class to connect to the MQTT server.
WiFiClientSecure client;

#define AIO_SERVER      "io.adafruit.com"

// Using port 8883 for MQTTS
#define AIO_SERVERPORT  8883

// Adafruit IO Account Configuration
// (to obtain these values, visit https://io.adafruit.com and click on Active Key)

#define AIO_USERNAME  "XXXXX"
#define AIO_KEY       "XXXX"

// Setup the MQTT client class by passing in the WiFi client and MQTT server and login details.
Adafruit_MQTT_Client mqtt(&client, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_KEY);

/****************************** Feeds ***************************************/

// Setup a feeds for subscribing
Adafruit_MQTT_Subscribe LED_int_feed = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "/feeds/led-int", MQTT_QOS_1);
Adafruit_MQTT_Subscribe LED_onoff_feed = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "/feeds/led-onoff", MQTT_QOS_1);

// Setup a feeds for publishing.
// Notice MQTT paths for AIO follow the form: <username>/feeds/<feedname>
Adafruit_MQTT_Publish TDS_feed = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/TDS");
Adafruit_MQTT_Publish Temperature_feed = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/Temperature");

// MQTT example

void LEDintcallback(double x) {
  Serial.print("Hey we're in a slider callback, the slider value is: ");
  Serial.println(x);
}

void LEDonoffcallback(char *data, uint16_t len) {
  Serial.print("Hey we're in a onoff callback, the button value is: ");
  Serial.println(data);
}

// io.adafruit.com root CA
const char* adafruitio_root_ca = \
    "-----BEGIN CERTIFICATE-----\n" \
    "MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh\n" \
    "MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\n" \
    "d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD\n" \
    "QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT\n" \
    "MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j\n" \
    "b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG\n" \
    "9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB\n" \
    "CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97\n" \
    "nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt\n" \
    "43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P\n" \
    "T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4\n" \
    "gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO\n" \
    "BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR\n" \
    "TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw\n" \
    "DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr\n" \
    "hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg\n" \
    "06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF\n" \
    "PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls\n" \
    "YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk\n" \
    "CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=\n" \
    "-----END CERTIFICATE-----\n";

/****************************** Feeds ***************************************/

// Function to connect and reconnect as necessary to the MQTT server.
// Should be called in the loop function and it will take care if connecting.
void MQTT_connect() {
  int8_t ret;

  // Stop if already connected.
  if (mqtt.connected()) {
    return;
  }

  Serial.print("Connecting to MQTT... ");

  uint8_t retries = 3;
  while ((ret = mqtt.connect()) != 0) { // connect will return 0 for connected
       Serial.println(mqtt.connectErrorString(ret));
       Serial.println("Retrying MQTT connection in 5 seconds...");
       mqtt.disconnect();
       delay(5000);  // wait 5 seconds
       retries--;
       if (retries == 0) {
         // basically die and wait for WDT to reset me
         while (1);
       }
  }
  Serial.println("MQTT Connected!");
}

  unsigned long current_millis;
  unsigned long start_millis;
  unsigned long timing;

void setup(void){
  Serial.begin(115200);
  while (!Serial)  // Wait for the serial connection to be establised.
    delay(500);

  WiFi.mode(WIFI_STA);
 
  WiFi.begin(SSID, PASSWORD);
  Serial.println();
  Serial.print("Trying to set WIFI link up");

  // Wait for connection
  while (WiFi.status() != WL_CONNECTED) {  //TODO no wifi available
    delay(500);
    Serial.print(".");
  }
  Serial.println();
  Serial.print("Connected to ");
  Serial.println(SSID);
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());

  WiFi.setAutoReconnect(true);
  WiFi.persistent(true);

// MQTT

  Serial.print("Starting Adafruit MQTT service... ");

// Set Adafruit IO's root CA
  client.setCACert(adafruitio_root_ca);

  // Ensure the connection to the MQTT server is alive (this will make the first
  // connection and automatically reconnect when disconnected).  See the MQTT_connect
  // function definition further below.
  MQTT_connect();

  Serial.println("done");

  Serial.print("Starting MQTT client... ");
/*
 * Subscribing configuration
 */

  LED_int_feed.setCallback(LEDintcallback);
  LED_onoff_feed.setCallback(LEDonoffcallback);

// Setup MQTT subscription
  mqtt.subscribe(&LED_int_feed);
  mqtt.subscribe(&LED_onoff_feed);

  Serial.println("done");
}

void loop(void){
//
  Serial.println();
  Serial.println("Tasks LOOP started");
  Serial.println();

  current_millis = millis();

// Check WIFI status

  switch (WiFi.status()){
    case WL_NO_SSID_AVAIL:
      Serial.println("WIFI configured SSID cannot be reached");
      break;
    case WL_CONNECTED:
      Serial.println("WIFI connection successfully established");
      break;
    case WL_CONNECT_FAILED:
      Serial.println("WIFI connection failed");
      break;
  }

  int wifi_rssi = WiFi.RSSI();
  Serial.printf("WIFI connection status: %d RSSI %d", WiFi.status(),wifi_rssi);
  Serial.println();

  float tdsValue = 414.14;
  float tempavg = 26.0;

// MQTT publishing

  Serial.println();
  Serial.println(F("MQTT publishing..."));

  // Ensure the connection to the MQTT server is alive (this will make the first
  // connection and automatically reconnect when disconnected).  See the MQTT_connect
  // function definition further below.
  MQTT_connect();

  // Now we can publish stuff!

  if (! TDS_feed.publish(tdsValue)) {
    Serial.println(F("Failed TDS feed"));
  } else {
    Serial.println(F("TDS feed published"));
  }

  if (! Temperature_feed.publish(tempavg)) {
    Serial.println(F("Failed temperature feed"));
  } else {
    Serial.println(F("Temperature feed published"));
  }

// Timing

  Serial.println();

  timing = millis()-current_millis;

  Serial.print("Tasks took (ms): ");
  Serial.println(timing);

  Serial.println();

  Serial.println("Waiting for new tasks cycle...");
  Serial.println();
  Serial.print("Free memory: ");
  Serial.print(ESP.getFreeHeap(),DEC);
  Serial.print(" Running for (mins): ");
  Serial.println(((millis()/1000)/60));
  Serial.println();

// MQTT subcriptions
// this is our 'wait for incoming subscription packets and callback em' busy subloop
// try to spend your time here:

  mqtt.processPackets(10000-timing);
}

aelorenzo
 
Posts: 5
Joined: Sun Oct 17, 2021 3:44 pm

Re: MQTT subscriptions callback doesn't work

by aelorenzo on Wed Oct 20, 2021 4:13 am

Hi again!

Is this sketch useful for you?

I have the same problem with this simplified version of my project.

I left the includes for all the libraries that I am using just to be able to check if maybe there is some kind of incompatibility.

Thank you!

aelorenzo
 
Posts: 5
Joined: Sun Oct 17, 2021 3:44 pm

Re: MQTT subscriptions callback doesn't work

by aelorenzo on Fri Oct 22, 2021 12:28 pm

I have read more info, and I think that this setup should work. Why it doesn´t work?

Any help would be appreciated.

Thank you!

aelorenzo
 
Posts: 5
Joined: Sun Oct 17, 2021 3:44 pm

Re: MQTT subscriptions callback doesn't work

by aelorenzo on Sat Oct 23, 2021 3:39 pm

Solved.

I have two MQTT_connect() calls, one in setup and another in loop.

Only one, and in the loop section of the sketch should be used.

aelorenzo
 
Posts: 5
Joined: Sun Oct 17, 2021 3:44 pm

Re: MQTT subscriptions callback doesn't work

by brubell on Mon Oct 25, 2021 9:56 am

Code: Select all | TOGGLE FULL SIZE
// function definition further below.
  MQTT_connect();

  Serial.println("done");

  Serial.print("Starting MQTT client... ");
/*
 * Subscribing configuration
 */

  LED_int_feed.setCallback(LEDintcallback);
  LED_onoff_feed.setCallback(LEDonoffcallback);

// Setup MQTT subscription
  mqtt.subscribe(&LED_int_feed);
  mqtt.subscribe(&LED_onoff_feed);


Place the mqtt_connect call after the subscription and callback calls, it should be last. The connect() call sends all information relating to the client's setup to the broker.

brubell
 
Posts: 1557
Joined: Fri Jul 17, 2015 10:33 pm

Please be positive and constructive with your questions and comments.