Arduino上的MQTT无法正常工作

时间:2016-05-03 21:09:46

标签: arduino wifi mqtt

我正在使用Arduino Uno和Wi-Fi屏蔽。我正在尝试实现MQTT协议进行通信,我为Arduino尝试了两个库。第一个是Knolleary的PubSubClient:http://pubsubclient.knolleary.net/。我稍微修改了原始示例以使用WiFi模块而不是以太网。发送工作但不是每次都发送(有时,消息发送,有时不发送)。但是通过回调函数接收根本不起作用。

这是我的代码:

/*
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!");
    }
  }
}

如您所见,我正在使用http://test.mosquitto.org/进行测试。我也在Ubuntu上使用mosquitto,我订阅了相同的主题,并从哪里(另一个终端窗口)我发布到相同的主题。这是两个窗口的图片:

mosquitto on Ubuntu

正如你所看到的,来自Arduino的“hello world”消息被成功接收(但不是每次都被接收),当我从另一个窗口发布“bla”消息时,它在mosquitto上成功接收(在图像上)但不在Arduino上。我的代码有问题吗?我在这里发现了类似的问题:Arduino Knolleary PubSubClient will publish messages but can't receive them

值得注意的是,它一直在重新连接。正如您所看到的,在loop()中,我放置了一部分代码,如果连接丢失,它将再次连接和订阅。在串行监视器上我得到“信息:重新连接!”消息每2-3秒。

Adafruit图书馆 然后我尝试了Adafruit库,但它根本不会连接!我尝试使用test.mosquitto.org和io.adafruit.com,但我只是继续“连接失败!”错误。我尝试了很多改变和组合,但到目前为止没有运气。一旦我设法得到“无法订阅”而不是“连接失败”,但这只是一次,下次使用相同的代码我再次“连接失败”。

这是我的代码:

/*
 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!");
    }
  }
}

知道这些库或我的代码有什么问题吗?

1 个答案:

答案 0 :(得分:0)

如评论中所述

在公共经纪人上使用示例代码时,请确保将客户端ID更改为随机的,因为与其他人发生冲突的可能性非常高。因为客户端ID必须是唯一的,否则会导致重新连接风暴