Wemos D1 ESP8266,ioBroker(Raspberry Pi 3 Model B)MQTT连接失败

时间:2019-02-12 19:27:16

标签: arduino mqtt raspbian esp8266 mikrotik

我有一个带有ioBroker(Raspbian light Stretch)作为MQTT代理的Raspberry Pi 3 Model B和一个带有测试脚本的Wemos D1 ESP 8266。两台设备均通过Wi-Fi连接到网络。

好消息:

1)我可以从手机(myMQTT应用程序)发送MQTT信号,它将显示在ioBroker日志中(手机已连接到Wi-Fi,MicroTik)。 我可以从笔记本电脑(连接到Wi-Fi或以太网)发送MQTT信号。 我可以从Debian虚拟服务器(在vmware上)发送成功的MQTT信号。

2)Wemos D1成功连接到测试服务器test.mosquitto.org。

坏消息: Wemos D1不想连接到本地网络上的ioBroker,并报告错误“尝试建立MQTT连接...失败,rc = -2在5秒钟内重试”。

为什么除Wemos D1 ESP 8266之外的所有设备都成功连接到mqtt broker? 防火墙可能是这种情况吗? 请告诉我,我该怎么做才能解决这个问题。

/*
 Basic ESP8266 MQTT example

 This sketch demonstrates the capabilities of the pubsub library in combination
 with the ESP8266 board/library.

 It connects to an MQTT server then:
  - publishes "hello world" to the topic "outTopic" every two seconds
  - subscribes to the topic "inTopic", printing out any messages
    it receives. NB - it assumes the received payloads are strings not binary
  - If the first character of the topic "inTopic" is an 1, switch ON the ESP Led,
    else switch it off

 It will reconnect to the server if the connection is lost using a blocking
 reconnect function. See the 'mqtt_reconnect_nonblocking' example for how to
 achieve the same result without blocking the main loop.

 To install the ESP8266 board, (using Arduino 1.6.4+):
  - Add the following 3rd party board manager under "File -> Preferences -> Additional Boards Manager URLs":
       http://arduino.esp8266.com/stable/package_esp8266com_index.json
  - Open the "Tools -> Board -> Board Manager" and click install for the ESP8266"
  - Select your ESP8266 in "Tools -> Board"

*/

#include <ESP8266WiFi.h>
#include <PubSubClient.h>

// Update these with values suitable for your network.

const char* ssid = "XXX";
const char* password = "XXX";
const char* mqtt_server = "test.mosquitto.org";

WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
char msg[50];
int value = 0;

void setup_wifi() {

  delay(5000);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.mode (WIFI_STA);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    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) {
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();

  // Switch on the LED if an 1 was received as first character
  if ((char)payload[0] == '1') {
    digitalWrite(BUILTIN_LED, LOW);   // Turn the LED on (Note that LOW is the voltage level
    // but actually the LED is on; this is because
    // it is active low on the ESP-01)
  } else {
    digitalWrite(BUILTIN_LED, HIGH);  // Turn the LED off by making the voltage HIGH
  }

}

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Create a random client ID
    String clientId = "ESP8266Client-";
    clientId += String(random(0xffff), HEX);
    // Attempt to connect
    if (client.connect(clientId.c_str())) {
      Serial.println("connected");
      // Once connected, publish an announcement...
      client.publish("outTopic", "hello world");
      // ... and resubscribe
      client.subscribe("inTopic");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(1000);
    }
  }
}

void setup() {
  pinMode(BUILTIN_LED, OUTPUT);     // Initialize the BUILTIN_LED pin as an output
  Serial.begin(115200);
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
}

void loop() {

  if (!client.connected()) {
    reconnect();
  }
  client.loop();

  long now = millis();
  if (now - lastMsg > 2000) {
    lastMsg = now;
    ++value;
    snprintf (msg, 50, "hello world #%ld", value);
    Serial.print("Publish message: ");
    Serial.println(msg);
    client.publish("outTopic", msg);
  }
}

屏幕截图: 1)netstat -tulpn | grep LISTEN

2)ioBrocker log

3)Arduino IDE

更新:

我没有找到可以更改或禁用侦听端口1883 tcp6的位置。

但是我设法用Keenetic代替了Mikrotik路由器,从而在设备之间建立了连接。

现在,我们需要弄清楚路由器的设置出了什么问题。

1 个答案:

答案 0 :(得分:0)

您的屏幕截图:

enter image description here

显示ioBroker正在侦听端口9000和9001的IPv4环回接口(127.0.0.1),并正在侦听端口8081、8082和1883的tcp6(IPv6)接口。

这意味着只能通过与该服务器在同一服务器上运行的程序或能够运行IPv6的计算机上运行的程序通过IPv4进行访问。

ESP8266无法使用IPv6。

您需要重新配置ioBroker来监听0.0.0.0:mqtt,以便IPv4软件可以访问它。