Search code examples
arduinomqttesp8266

ESP8266 mqtt messages don't get published


So I got the following situation: I'm trying to publish data from an DHT11 sensor (sensor is working just fine) via mqtt to my broker. But the messages don't get published - I'm testing it via client.state, which returns 5, which means "the client was not authorized to connect" (API Documentation).

This is my code (I replaced sensible data with XXs):

#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);
    }
  }
}

The output looks like this:

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...

To me it looks like the ESP gets rejected by the server, but user, password and servername are correct - I just don't get what's the problem. I'd love some help!


Solution

  • Your code defines a username and password for the MQTT broker but never actually uses them. You need to pass them to the connect method or else they do nothing.

        if (client.connect(clientID)) {
    

    should be

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

    You're also calling client.connect(clientID); before you connect to wifi and before you set the server, which is a bold choice and not helpful. Don't do that.

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

    You might take a look over PubSubClient's examples to see how to use it properly.

    should be

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