ESP32 connects in setup() but client.connected() is false a few seconds later in loop()
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.
delay(30000) with nothing serviced. That’s your problem.
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.
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.
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.
The Log tab saves so much guessing. +1
- Bu konuyu yanıtlamak için giriş yapmış olmalısınız.
Sohbete katılın
Soru sormak ve yanıtlamak, yararlı gönderileri beğenmek ve sorununuzu çözen yanıtı işaretlemek için oturum açın. Her katkı puan ve seviye kazandırır.

