ESP8266 MQTT funktioniert nicht

Moin Moin,

ich habe mehrere (etwa 17 st.) ESP8266 bei mir im umlauf.
Auf diesen läuft die MQTT Anbindung entweder mit der [PubSubClient] (PubSubClient - Arduino Reference) oder der [ArduinoMqttClient] (ArduinoMqttClient - Arduino Reference) Library.

Auf den meisten läuft noch der PubSubClient, als ich damals damit anfing, funktionierte das problemlos.
Damals war aber auf dem MQTT-Server nicht viel los, nun ist das aber anders.
Sehr viele (30 +) Virtuelle Server senden darüber im Sekunden Takt ihren Status und so kommt es zu mehreren 50 Nachrichten die Sekunde die über den MQTT Broker laufen.
Unter Linux kein Thema, wenn ich per mosquitto_pub oder mosquitto_sub nachrichten Schicke oder zuhöre funktioniert das Perfekt.

Der Virtuelle MQTT-Server hat 4GB Ram und 8 CPU Kerne von einem AMD Ryzen 9 5950X, an dem dürfte das nicht liegen.

Da jetzt aber immer mehr ESP8266 Clients im Netzwerk sind, funktioniert das zuhören oder das schicken von Nachrichten sehr schlecht.
Es sind überwiegend Bewegungsmelder, Tür Sensoren etc. halt zur Raumüberwachung, also eine selbstgebaute Alarmanlage.
Bei den einen funktioniert es nur noch, wenn ich bei den Skripts den delay(); rausnehme und sie pausenlos senden, da habe ich einen, der läuft seit einem Halben Jahr.

Die meisten Stürzen nach knapp einem Tag ab, einen Fehler habe ich schon entdeckt.
Es macht einen Unterschied ob viele Fenster am Computer beim Kompilieren geöffnet sind oder nicht, da dass Kompilieren sonst meistens schief läuft und der ESP8266 nichts macht.

Das wäre mal ein Skript welches am Ende zur Steuerung von Philips Hue ist, ein Server hört den verschiedenen Topics zu und reagiert dementsprechend.

#include <ArduinoMqttClient.h>
#include <ESP8266WiFi.h>

#define wifi_ssid "IOT"
#define wifi_password "MeinWLANPASSWD"

WiFiClient espClient;
MqttClient mqttClient(espClient);

const char broker[] = "10.100.0.154";
int        port     = 1883;

//set interval for sending messages (milliseconds)
const long interval = 200;
unsigned long previousMillis = 0;

int count = 0;
int count_online = 10;

int Button_1 = 12; // D6 
int Button_2 = 13; // D7
int Button_3 = 2; // D4
int Button_4 = 14; // D5 

#define Topic_Status_Online "JJ-Button/Serverraum/phue/Serverraum_button1_tisch_phue/Online"
#define Topic_Button_one "JJ-Button/Serverraum/phue/Serverraum_button1_tisch_phue/Button_one"
#define Topic_Button_two "JJ-Button/Serverraum/phue/Serverraum_button1_tisch_phue/Button_two"
#define Topic_Button_three "JJ-Button/Serverraum/phue/Serverraum_button1_tisch_phue/Button_three"
#define Topic_Button_four "JJ-Button/Serverraum/phue/Serverraum_button1_tisch_phue/Button_four"

void setup() {
  Serial.begin(9600);

  delay(120);

  pinMode(Button_1, INPUT);
  pinMode(Button_1, OUTPUT);
  pinMode(Button_2, INPUT);
  pinMode(Button_2, OUTPUT);
  pinMode(Button_3, INPUT);
  pinMode(Button_3, OUTPUT);
  pinMode(Button_4, INPUT);
  pinMode(Button_4, OUTPUT);

  digitalWrite(Button_1, LOW);
  digitalWrite(Button_2, LOW);
  digitalWrite(Button_3, LOW);
  digitalWrite(Button_4, LOW);

  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, HIGH);

  delay(120);
  
  Serial.println(" ");
  Serial.println("Moin Moin ....");
  Serial.println("Der Arduino Startet nun     //JJ");
  
  Serial.print("Attempting to connect to WPA SSID: ");
  Serial.println(wifi_ssid);
  while (WiFi.begin(wifi_ssid, wifi_password) != WL_CONNECTED) {
    Serial.print(".");
    delay(5000);
  }
  Serial.print("Ich habe die IP Addresse : ");
  Serial.print(WiFi.localIP());

  Serial.println("You're connected to the network");
  Serial.println();

  Serial.print("Attempting to connect to the MQTT broker: ");
  Serial.println(broker);

  if (!mqttClient.connect(broker, port)) {
    Serial.print("MQTT connection failed! Error code = ");
    Serial.println(mqttClient.connectError());

    while (1);
  }

  Serial.println("You're connected to the MQTT broker!");
  Serial.println();

  mqttClient.beginMessage("JJ-Button/Serverraum/phue/Status");
  mqttClient.print("Hello World! - Start now");
  mqttClient.endMessage();
}

void loop() {
  delay(60);
  // call poll() regularly to allow the library to send MQTT keep alive which
  // avoids being disconnected by the broker
  mqttClient.poll();

  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;

    if (digitalRead(Button_1) == HIGH ) {
      mqttClient.beginMessage(Topic_Button_one);
      mqttClient.print("1");
      mqttClient.endMessage();

      Serial.println("Button one");
      delay(200);
      digitalWrite(Button_1, LOW);
      mqttClient.beginMessage(Topic_Button_one);
      mqttClient.print("0");
      mqttClient.endMessage();
    }
    
    if (digitalRead(Button_2) == HIGH ) {
      mqttClient.beginMessage(Topic_Button_two);
      mqttClient.print("1");
      mqttClient.endMessage();

      Serial.println("Button two");
      delay(200);
      digitalWrite(Button_2, LOW);
      mqttClient.beginMessage(Topic_Button_two);
      mqttClient.print("0");
      mqttClient.endMessage();
    }
    
    if (digitalRead(Button_3) == HIGH ) {
      mqttClient.beginMessage(Topic_Button_three);
      mqttClient.print("1");
      mqttClient.endMessage();

      Serial.println("Button three");
      delay(200);
      digitalWrite(Button_3, LOW);
      mqttClient.beginMessage(Topic_Button_three);
      mqttClient.print("0");
      mqttClient.endMessage();
    }
    
    if (digitalRead(Button_4) == HIGH ) {
      mqttClient.beginMessage(Topic_Button_four);
      mqttClient.print("1");
      mqttClient.endMessage();

      Serial.println("Button four");
      delay(200);
      digitalWrite(Button_4, LOW);
      mqttClient.beginMessage(Topic_Button_four);
      mqttClient.print("0");
      mqttClient.endMessage();
    }

    if (count_online == 0) {
      mqttClient.beginMessage(Topic_Status_Online);
      mqttClient.print("1");
      mqttClient.endMessage();
      count_online = 40;
    }
    count_online--;
  }
}

Oder von einem Bewegungsmelder:

#include <ArduinoMqttClient.h>
#include <ESP8266WiFi.h>

#define wifi_ssid "IOT"
#define wifi_password "MeinWLANPASSWORT"

WiFiClient espClient;
MqttClient mqttClient(espClient);

const char broker[] = "10.100.0.154";
int        port     = 1883;

//set interval for sending messages (milliseconds)
const long interval = 100;
unsigned long previousMillis = 0;

int count = 0;
int count_online = 10;

#define door_sensor = 5;
#define Topic_Status_Online "JJ-Sensor/Serverraum/Door_sensor/Online_OpenHab"
#define Topic_Status_door_sensor "JJ-Sensor/Serverraum/Door_sensor/Sensor"
#define Topic_Status_door_sensor_OpenHab "JJ-Sensor/Serverraum/Door_sensor/Sensor_OpenHab"

void setup() {
  //Initialize serial and wait for port to open:
  Serial.begin(9600);

  delay(120);

  pinMode(door_sensor, INPUT);

  delay(120);
  
  Serial.println(" ");
  Serial.println("Moin Moin ....");
  Serial.println("Der Arduino Startet nun     //JJ");
  
  Serial.print("Attempting to connect to WPA SSID: ");
  Serial.println(wifi_ssid);
  while (WiFi.begin(wifi_ssid, wifi_password) != WL_CONNECTED) {
    Serial.print(".");
    delay(5000);
  }
  Serial.print("Ich habe die IP Addresse : ");
  Serial.print(WiFi.localIP());

  Serial.println("You're connected to the network");
  Serial.println();

  Serial.print("Attempting to connect to the MQTT broker: ");
  Serial.println(broker);

  if (!mqttClient.connect(broker, port)) {
    Serial.print("MQTT connection failed! Error code = ");
    Serial.println(mqttClient.connectError());

    while (1);
  }

  Serial.println("You're connected to the MQTT broker!");
  Serial.println();

  mqttClient.beginMessage("JJ-Button/Serverraum/phue/Status");
  mqttClient.print("Hello World! - Start now");
  mqttClient.endMessage();
}

void loop() {
  delay(60);
  // call poll() regularly to allow the library to send MQTT keep alive which
  // avoids being disconnected by the broker
  mqttClient.poll();

  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;

    if (digitalRead(door_sensor) == LOW) {
      mqttClient.beginMessage(Topic_Status_door_sensor);
      mqttClient.print("Tür offen");
      mqttClient.endMessage();
      delay(60);
      mqttClient.beginMessage(Topic_Status_door_sensor_OpenHab);
      mqttClient.print("1");
      mqttClient.endMessage();
      digitalWrite(door_sensor, HIGH);
    }

    if (digitalRead(door_sensor) == HIGH) {
      mqttClient.beginMessage(Topic_Status_door_sensor);
      mqttClient.print("Tür zu");
      mqttClient.endMessage();
      delay(60);
      mqttClient.beginMessage(Topic_Status_door_sensor_OpenHab);
      mqttClient.print("0");
      mqttClient.endMessage();
      digitalWrite(door_sensor, LOW);
    }

    if (count_online == 0) {
      mqttClient.beginMessage(Topic_Status_Online);
      mqttClient.print("1");
      mqttClient.endMessage();
      count_online = 40;
    }
    count_online--;
  }
}

Nachdem die ESP8266 nicht mehr reagieren, hatte ich mal geguckt ob ich sie mit der IP Adresse noch Pingen kann und ja, sie reagieren auf den Ping, nur unter MQTT passiert nichts mehr.

Habt ihr eine Idee woran das liegen kann?
Langsam steigt die lust alles in die Luft zu jagen, bin schon so lange dabei das zum laufen zu kriegen aber irgendwie wollen die net.

Liebe Grüße

Ich denke, das Problem liegt im WIFI-Router

Naja, bei WLAN setzte ich auf unifi und selbst wenn ich die ESP's auf einen eigenen WLAN AP setze bleiben die Fehler, der unifi AP AC Pro ist vom letzen Jahr und funktioniert tadellos.
Der unifi Controller sagt, dass die WLAN Auslastung bei 3% liegt, also "WLAN Erfahrung Ausgezeichnet (97%)", desto niedriger die Prozentzahl von der WLAN Erfahrung ist desto ausgelasteter ist das WLAN.

Wenn ich das ganze mit Raspberry Pi's mache, also über Linux und diese per WLAN anbinde funktioniert das auch problemlos.

Starten Sie den Router neu, wenn der Broker funktioniert, ist er drin

Alles schon gemacht, er ist nach ein paar Sekunden drin, nur die meisten hören nach 1 Tag auf zu arbeiten und Publishen nichts mehr

Das Problem liegt im Router, ändern Sie zuerst die Stromversorgung

Was soll ich da genau ändern, dieser läuft über PoE und wurde vorgestern neugestartet?

alle Anzeichen dafür, dass "die Erinnerung fließt"
Gibt es defekte Ethernet-Pakete?

Also wenn ich auf dem Controller gucke, habe ich 0,2% verlorene Pakete beim empfangen in den letzten 24 Stunden gehabt.
Beim senden sind es 0.0%.

Überprüfen Sie die Verbindung zum Ethernet-Anschluss des Routers, möglicherweise ist Feuchtigkeit in den Anschluss eingedrungen

Ne, soweit alles trocken, im Raum sind auch nur etwa 35% Feuchtigkeit.

ist im Zimmer?

Ja, genau

Überprüfen Sie die Stromversorgung, sehen Sie die Welligkeit

Es ist PoE mit 48V DC da gibt es bei mir keine Schwankung.
Ich schließe WLAN aus, da ich mit andern Access Points (auch von anderen Firmen) die selben Fehler habe.

Nach einem Tag kann ich die IP Adresse des ESP8266 Ping'en jedoch sendet er per MQTT nichts mehr.

Raspberry Pi's welche auch über das WLAN verbunden sind funktionieren ja auch.....
Ist halt nur eine andere Programmiersprache und ein anderes Board

und wenn der ESP8266 neu gestartet wird?

Dann funktioniert er für einen Tag, danach ist er nur noch mit Ping erreichbar, MQTT funktioniert nicht mehr.
Dass könnte er mit einem stück Code automatisch machen, aber die schöne feine Englische Art ist das nicht.

Überprüfen Sie die Stromversorgung am ESP8266

Die ist über all unterschiedlich, manche haben ein neues 5V 2A Netzteil, andere sind an einem Großen Netzteil mit den Raspberry Pi's mit 5,8V 10A angeschlossen.
Alle haben die selben Fehler

Wenn ich bei allen eine 5V 2A last anschließe funktioniert es immer noch, Netzteile sind also in Ordnung.

Ich vermute das es an der MQTT Lib oder an meinem Code liegt, da ich auch gelesen hatte das die MQTT Lib allgemein schlecht und fehlerhaft ist.