Neu: Die KI-Firewall überwacht die gesamte Plattform und erklärt jeden Vorfall in einfachen Worten. So funktioniert es

ESP32 connects in setup() but client.connected() is false a few seconds later in loop()

ESP32 connects in setup() but client.connected() is false a few seconds later in loop()

Gelöst 5 5

Uni lab, ESP32 DevKit, PubSubClient, WiFiClientSecure. In setup() I connect to Wi-Fi and to Hermetry, it prints „MQTT connected“, and the first reading arrives. Then in loop() I read a BME280, publish, and delay(30000). From the second loop on client.connected() is false and client.state() is -3. My reconnect code connects again, one more reading gets through, and it repeats. So I get readings but the device keeps flipping online/offline on the device page.

void loop() {
  if (!client.connected()) reconnect();
  float t = bme.readTemperature();
  snprintf(buf, sizeof buf, "{"temperature":%.2f}", t);
  client.publish("v1/telemetry", buf);
  delay(30000);
}

Keepalive is the default. I’m not sure what I’m doing wrong, it looks like every tutorial.

♥ 0

delay(30000) with nothing serviced. That’s your problem.

♥ 0

Also check the device’s Log tab for the disconnect reasons. If you see „Taken over by a new session“, another board is using the same token.

♥ 0

Tyler’s right in one line, here’s the longer version. PubSubClient only reads from the socket and sends pings inside client.loop(). Its default keepalive is 15 s. You sleep 30 s, so no ping goes out, the broker drops you for keepalive_timeout, and state -3 is „connection lost“.

Never block in loop(), use a timer instead:

unsigned long last = 0;

void setup() {
  ...
  client.setKeepAlive(60);
  client.setBufferSize(512);
}

void loop() {
  if (!client.connected()) reconnect();   // with a back-off, not a tight loop
  client.loop();                          // every pass
  if (millis() - last >= 30000) {
    last = millis();
    snprintf(buf, sizeof buf, "{"temperature":%.2f}", bme.readTemperature());
    client.publish("v1/telemetry", buf);
  }
}

Keepalive between 30 and 300 s is what the docs recommend. And do what Niall said, the Log tab names the reason for every disconnect.

Akzeptierte Lösung♥ 1

Fixed, but it was two things! Log tab showed keepalive_timeout AND „Taken over by a new session“. My first breadboard prototype was still plugged into a USB charger at home with the same token. Unplugged it, switched to the millis() version, and the device has been online for 6 hours.

♥ 0

The Log tab saves so much guessing. +1

QoS 1 and a lot of patience.
♥ 0
Ansicht von 6 Beiträgen – 1 bis 6 (von insgesamt 6)
  • Du musst angemeldet sein, um auf dieses Thema antworten zu können.

Mitdiskutieren

Melde dich an, um Fragen zu stellen und zu beantworten, hilfreiche Beiträge mit „Gefällt mir“ zu markieren und die Antwort zu kennzeichnen, die dein Problem gelöst hat. Jeder Beitrag bringt Punkte und Stufen.

Teilen