【问题标题】:MQTT on Arduino not workingArduino 上的 MQTT 不起作用
【发布时间】:2016-05-03 21:09:45
【问题描述】:

我正在使用 Arduino Uno 和 Wi-Fi shield。我正在尝试实现 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,我订阅了同一个主题,并且从哪里(另一个终端窗口)发布到同一个主题。这是两个窗口的图片:

如您所见,来自 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!");
    }
  }
}

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

【问题讨论】:

  • 快速建议,如果可能,请尝试使用您自己的本地经纪人进行测试。如果没有,请将 client_id(当前为“arduinoClient”)更改为随机值,以确保它不会与可能使用这些公共代理的其他任何人发生冲突
  • 正如 hardillb 所说,在公共代理上使用像 arduinoClient 这样的通用客户端 ID 可能会发生冲突并导致断开/重新连接周期。如果它不断断开/重新连接,那么它很可能会丢失消息。选择一个唯一的客户 ID,然后重试。
  • 好吧,我真傻:) 我什至没有注意客户ID,我只是把它放在示例中。老实说,我可能会再花几十个小时,而且可能永远不会想到这个。谢谢,现在它就像一个魅力!由于另一个图书馆,我将把问题留在那里。我正在为我的大学做一些研究,所以我想比较这些图书馆。知道是否可以查看消息大小和发送 PubSubClient 库所花费的时间吗?

标签: arduino wifi mqtt


【解决方案1】:

如 cmets 中所述

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

【讨论】:

    猜你喜欢
    • 2018-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多