ESP8266 mqtt 消息未发布

ESP8266 mqtt messages don't get published

所以我遇到了以下情况:我正在尝试通过 mqtt 从 DHT11 传感器(传感器工作正常)向我的经纪人发布数据。但是消息没有发布 - 我正在通过 client.state 测试它,returns 5,这意味着“客户端未被授权连接”(API Documentation)。

这是我的代码(我用 XX 替换了敏感数据):

#include "DHT.h" //DHT Bibliothek laden
#include <PubSubClient.h>
#include <ESP8266WiFi.h>

#define WLAN_SSID "XXXXXXX"
#define WLAN_PASS "XXXXXXX"

const char* mqtt_server = "XXXXXXX";
#define mqtt_user "XXXXXX"         
#define mqtt_password "XXXXXX"  

#define DHTPIN D4       //Der Sensor wird an PIN D4 angeschlossen    
#define DHTTYPE DHT11   // Es handelt sich um den DHT11 Sensor

#define humidity_topic "esp01/humidity"
#define temperature_topic "esp01/temperature"
#define status_topic "esp01/status" 

DHT dht(DHTPIN, DHTTYPE); //Der Sensor wird ab jetzt mit „dht“ angesprochen
WiFiClient espClient;  
PubSubClient client(mqtt_server, 1883, espClient); 
const char* clientID = "clientID";

float Luftfeuchtigkeit = 0.0;
float Temperatur = 0.0;
  
void setup() {
  Serial.begin(9600); //Serielle Verbindung starten
  dht.begin(); //DHT11 Sensor starten
  client.connect(clientID);
  
  setup_wifi();  
  client.setServer(mqtt_server, 1883); 
  if (!client.connected()) {  
    reconnect();  
  }  
  client.loop();

  Luftfeuchtigkeit = dht.readHumidity(); //die Luftfeuchtigkeit auslesen und unter „Luftfeuchtigkeit“ speichern
  Temperatur = dht.readTemperature();//die Temperatur auslesen und unter „Temperatur“ speichern 
  
  Serial.print(F("Luftfeuchtigkeit: ")); //Im seriellen Monitor den Text und 
  Serial.print(String(Luftfeuchtigkeit).c_str()); //die Dazugehörigen Werte anzeigen
  Serial.println(" %");
  client.publish(humidity_topic, String(Luftfeuchtigkeit).c_str()); 
  
  Serial.print("Temperatur: ");
  Serial.print(Temperatur);
  Serial.println(" Grad Celsius");
  client.publish(temperature_topic, String(Temperatur).c_str(), true);
}

void loop() {
  
  delay(2000);

  Serial.print("Luftfeuchtigkeit: "); //Im seriellen Monitor den Text und 
  Serial.print(String(Luftfeuchtigkeit).c_str()); //die Dazugehörigen Werte anzeigen
  Serial.println(" %");
  client.publish(humidity_topic, String(Luftfeuchtigkeit).c_str(), true); 
  
  Serial.print("Temperatur: ");
  Serial.print(Temperatur);
  Serial.println(" Grad Celsius");
  client.publish(temperature_topic, String(Temperatur).c_str(), true);

  delay(60000);
}
  
void setup_wifi() {  
  delay(10);  
  // We start by connecting to a WiFi network  
  Serial.println();  
  Serial.print("Connecting to ");  
  Serial.println(WLAN_SSID);  
  int _try = 0;
  WiFi.begin(WLAN_SSID, WLAN_PASS);  
  while (WiFi.status() != WL_CONNECTED) {  
   Serial.print("."); 
   delay(500);
  }
  Serial.println("");  
  Serial.println("WiFi connected");  
  Serial.println("IP address: ");  
  Serial.println(WiFi.localIP());  
 }

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect(clientID)) {
      Serial.println("connected");
      client.publish(humidity_topic, String(Luftfeuchtigkeit).c_str(), true);
    } else {
      Serial.print("failed, state: ");
      Serial.println(client.state());
      Serial.println("attempting reconnection...");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

输出如下所示:

19:13:42.245 -> 
19:13:42.245 -> Connecting to XXXXXXX
19:13:42.292 -> .......
19:13:46.608 -> WiFi connected
19:13:46.608 -> IP address: 
19:13:46.645 -> XXXXXXX
19:13:46.645 -> Attempting MQTT connection...failed, state: 5
19:13:46.740 -> attempting reconnection...
19:13:51.706 -> Attempting MQTT connection...failed, state: 5
19:13:51.937 -> attempting reconnection...
19:13:56.919 -> Attempting MQTT connection...failed, state: 5
19:13:57.064 -> attempting reconnection...

在我看来,ESP 似乎被服务器拒绝了,但用户、密码和服务器名是正确的 - 我只是不明白问题出在哪里。我需要一些帮助!

您的代码为 MQTT 代理定义了用户名和密码,但实际上从未使用过它们。您需要将它们传递给 connect 方法,否则它们什么都不做。

    if (client.connect(clientID)) {

应该是

    if (client.connect(clientID, mqtt_user, mqtt_password)) {

你在连接wifi之前和设置服务器之前也在调用client.connect(clientID);,这是一个大胆的选择,但没有帮助。不要那样做。

  client.connect(clientID);
  
  setup_wifi();  
  client.setServer(mqtt_server, 1883); 
  if (!client.connected()) {  

您可以查看 PubSubClient's examples 以了解如何正确使用它。

应该是

  setup_wifi();  
  client.setServer(mqtt_server, 1883); 
  if (!client.connected()) {