MQTT on Arduino not working

2020-05-01 09:05发布

I'm using Arduino Uno and Wi-Fi shield. I'm trying to implement MQTT protocol for communication and I tried two libraries for Arduino. First one is Knolleary's PubSubClient: http://pubsubclient.knolleary.net/ . I modified original example a little bit to use WiFi module instead of ethernet. Sending works but not every time (sometimes, the message is sent and sometimes not). But receiving via callback function doesn't work at all.

Here is my code:

/*
Basic MQTT example with Authentication

  - connects to an MQTT server, providing username
    and password
  - publishes "hello world" to the desired topic
  - subscribes to the desired topic
*/

#include <WiFi.h>
#include <PubSubClient.h>

char ssid[] = "[DELETED]";     //  your network SSID (name) 
char pass[] = "[DELETED]";    // your network password
int status = WL_IDLE_STATUS;     // the Wifi radio's status

// Update these with values suitable for your network.
IPAddress server(85, 119, 83, 194);
WiFiClient WifiClient;

void callbackFunc(char* topic, byte* payload, unsigned int length) {
  Serial.println("test message received");

  /*Serial.println();
  Serial.println("=============== MESSAGE RECEIVED       ================================");
  Serial.print("Topic: ");
  Serial.print(topic);
  Serial.println();
  Serial.println((const char *) payload);*/
}

PubSubClient client(server, 1883, callbackFunc, WifiClient);

void setup()
{
  delay(2000);

  Serial.begin(9600);
  Serial.println("Starting....");

  Serial.println("Initializing Wifi...");

  // check for the presence of the shield:
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi shield not present");    
  }

  // attempt to connect using WPA2 encryption:
  Serial.println("Attempting to connect to WPA network...");
  status = WiFi.begin(ssid, pass);

  // if you're not connected, stop here:
  if (status != WL_CONNECTED) {
    Serial.println("Couldn't get a wifi connection");
    while(true);
  }

  // If you are connected, print out success message
  else
    Serial.println("Connected to network");

  if (client.connect("arduinoClient")) {
    Serial.println("Connected to server! Sending message...");
    client.publish("randy/test","hello world");
    client.subscribe("randy/test");
    Serial.println("Sent!");
  }

  else
  {
    Serial.println("ERROR: Cannot connect to MQTT server!");
    Serial.println(client.state());
  }
}

void loop()
{
  client.loop();
  delay(1000);

  if (!client.connected())
  {
    if(!client.connect("arduinoClient"))
    {
      Serial.println("ERROR: Cannot connect to MQTT server!");
      Serial.println(client.state());
    }

    else
    {
      client.subscribe("randy/test");
      Serial.println("INFO: reconnected!");
    }
  }
}

As you can see, I'm using http://test.mosquitto.org/ for testing. I'm also using mosquitto on Ubuntu where I'm subscribed to the same topic and from where (another terminal window) I'm publishing to the same topic. Here is the picture of both windows:

mosquitto on Ubuntu

As you can see, "hello world" message from Arduino is received successfully (but not every time), and when I publish "bla" message from another window, it's successfully received on mosquitto (on image) but NOT on Arduino. Is there something wrong with my code or? I found similar problem here: Arduino Knolleary PubSubClient will publish messages but can't receive them

It's worth noticing that it keeps getting reconnected all the time. As you can see, in loop() I put a part of code which will connect and subscribe again if connection is lost. On Serial Monitor I get "INFO: Reconnected!" message every 2-3 seconds.

Adafruit library Then I tried the Adafruit library, but it won't connect at all! I tried with test.mosquitto.org and with io.adafruit.com from their example, but I just keep getting "Connection failed!" error. I tried making many changes and combinations but no luck so far. Once I managed to get "Failed to subscribe" instead of "Connection failed" but this was only once and next time with the same code I get "Connection failed" again.

Here's my code:

/*
 Basic MQTT example with Authentication

  - connects to an MQTT server, providing username
    and password
  - publishes "hello world" to the topic "outTopic"
  - subscribes to the topic "inTopic"
*/

#include <WiFi.h>
#include <PubSubClient.h>

char ssid[] = "[DELETED]";     //  your network SSID (name) 
char pass[] = "[DELETED]";    // your network password
int status = WL_IDLE_STATUS;     // the Wifi radio's status

// Update these with values suitable for your network.
IPAddress server(85, 119, 83, 194);
WiFiClient WifiClient;

void callbackFunc(char* topic, byte* payload, unsigned int length) {
  Serial.println("test message received");

  /*Serial.println();
  Serial.println("=============== MESSAGE RECEIVED ================================");
  Serial.print("Topic: ");
  Serial.print(topic);
  Serial.println();
  Serial.println((const char *) payload);*/
}

PubSubClient client(server, 1883, callbackFunc, WifiClient);

void setup()
{
  delay(2000);

  Serial.begin(9600);
  Serial.println("Starting....");

  Serial.println("Initializing Wifi...");

  // check for the presence of the shield:
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi shield not present");    
  }

  // attempt to connect using WPA2 encryption:
  Serial.println("Attempting to connect to WPA network...");
  status = WiFi.begin(ssid, pass);

  // if you're not connected, stop here:
  if (status != WL_CONNECTED) {
    Serial.println("Couldn't get a wifi connection");
    while(true);
  }

  // Ff you are connected, print out success message
  else
    Serial.println("Connected to network");

  if (client.connect("arduinoClient")) {
    Serial.println("Connected to server! Sending message...");
    client.publish("randy/test","hello world");
    client.subscribe("randy/test");
    Serial.println("Sent!");
  }

  else
  {
    Serial.println("ERROR: Cannot connect to MQTT server!");
    Serial.println(client.state());
  }
}

void loop()
{
  client.loop();
  delay(1000);

  if (!client.connected())
  {
    if(!client.connect("arduinoClient"))
    {
      Serial.println("ERROR: Cannot connect to MQTT server!");
      Serial.println(client.state());
    }

    else
    {
      client.subscribe("randy/test");
      Serial.println("INFO: reconnected!");
    }
  }
}

Any idea what's wrong with those libraries or my code?

1条回答
我想做一个坏孩纸
2楼-- · 2020-05-01 09:43

As mentioned in the comments

When using example code on public brokers make sure you change the client id to something random as the odds of clashing with somebody else are pretty high. Because client ids have to be unique else they will cause a reconnection storm

查看更多
登录 后发表回答