RR_28023
RR_28023

Reputation: 168

MQTT client not subscribing to a given topic (or callback not working as intended)

I'm going nuts trying to guess why my Arduino Nano33 is not being able to receive mqtt messages. Or may be it receives them but the callback function is not working as I intend (since the callback is the only way I have to see if a message was received).

I can publish messages without problem. Any clues on what can be wrong in my code? (I have zero experience with C++ so it could be some stupid mistake).

I'm copying the entire code in case the issue is somewhere else, but I guess the key functions to look at are callback and setup.

#include <WiFiNINA.h> 
#include <PubSubClient.h>
#include <Arduino_LSM6DS3.h>
#include "credentials.h"

const char* ssid = SSID_WIFI;
const char* password = PW_WIFI;
const char* mqttServer = MQTT_SERVER;
const int mqttPort = MQTT_PORT;
const char* mqttUsername = MQTT_USRNM;
const char* mqttPassword = MQTT_PW;
char pubTopic[] = "sensors/imu1/values";
char subTopic[] = "sensors/imu1/mode";

WiFiSSLClient wifiClient; //SSL
PubSubClient client(wifiClient);
void setup_wifi()

//Connect to wifi network 
{
  delay(10);  
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) 
  {
    delay(500);
    Serial.print(".");
  }
  randomSeed(micros());
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

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

void reconnect() 
{
  // Loop until we're reconnected
  while (!client.connected()) 
  {
    Serial.print("Attempting MQTT connection...");
    String clientId = "Nano33-";
    clientId += String(random(0xffff), HEX);
    // Attempt to connect
    if (client.connect(clientId.c_str(), mqttUsername, mqttPassword)) 
    {
      Serial.println("connected");
      // ... and resubscribe
      client.subscribe(subTopic);
    } else 
    {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

void setup() 
{   
  Serial.begin(9600);
  setup_wifi();
  client.setServer(mqttServer, mqttPort);
  client.setCallback(callback);  
  if (!IMU.begin()) {
    Serial.println("Failed to initialize IMU!");
    while (1);
  }
  Serial.println("IMU initialized!");  
}

void publish_imu_values(float x_acc, float y_acc, float z_acc, 
                        float x_gyr, float y_gyr, float z_gyr){
  //Publish imu readings in InfluxDB Line Protocol format
  String temp_str;
  char mensaje[100];
  temp_str  = "imu x_acc=";
  temp_str += String(x_acc);
  temp_str += ",y_acc=";
  temp_str += String(y_acc);
  temp_str += ",z_acc=";
  temp_str += String(z_acc);
  temp_str += ",x_gyr=";
  temp_str += String(x_gyr);
  temp_str += ",y_gyr=";
  temp_str += String(y_gyr);
  temp_str += ",z_gyr=";
  temp_str += String(z_gyr);        
  temp_str.toCharArray(mensaje, temp_str.length() + 1);  
  client.publish(pubTopic, mensaje);      
}

void loop() 
{
  if (!client.connected()) 
  {
    reconnect();
  }
  float x_acc, y_acc, z_acc;
  float x_gyr, y_gyr, z_gyr;  
  if (IMU.accelerationAvailable() && IMU.gyroscopeAvailable()) {
    IMU.readAcceleration(x_acc, y_acc, z_acc);
    IMU.readGyroscope(x_gyr, y_gyr, z_gyr);
    publish_imu_values(x_acc, y_acc, z_acc, x_gyr, y_gyr, z_gyr);    
  }  
  delay(1000);
}

Upvotes: 0

Views: 1422

Answers (1)

JD Allen
JD Allen

Reputation: 944

You need a client.loop(); line in your loop() main function. Without that line, you MQTT code never gets executed.

Upvotes: 3

Related Questions