Yeni: Yapay zekâ güvenlik duvarı tüm platformu izliyor ve her olayı sade bir dille açıklıyor. Nasıl çalıştığını görün

PubSubClient connect() fails with rc=2 when I build the client ID from String objects

PubSubClient connect() fails with rc=2 when I build the client ID from String objects

Çözüldü 6 5

Weird one. ESP32, Arduino core 2.0.14, PubSubClient 2.8. This connects fine every time:

mqtt.connect("barn-01", "my_access_token", "");

But I want the client ID to come from the MAC so I can flash the same sketch to five boards, and the token comes from a settings struct. So I did this:

const char* clientId = (String("barn-") + WiFi.macAddress()).c_str();
const char* token = settings.token.c_str();
mqtt.setServer(host.c_str(), 8883);
if (!mqtt.connect(clientId, token, "")) {
  Serial.println(mqtt.state());
}

Now it prints 2 forever. Same token, same host. I’m going slightly mad. Is it the colons in the MAC address?

♥ 0

I had something like this, added a delay(500) before connect and it went away.

Ask me about 4–20 mA.
♥ 0

Can you print what clientId actually contains right before connect?

Timestamps in UTC or it didn't happen.
♥ 1

rc=2 is “client ID rejected”. Colons are allowed in Hermetry client IDs (letters, digits and . _ : -, 1 to 64 chars), so it’s not the MAC format. Something else is getting into the ID.

♥ 0

Printed it, and it’s garbage:

clientId=[□□?□barn-]

sometimes empty, sometimes junk. The delay didn’t change anything.

♥ 2

The String is gone before you use it. (String("barn-") + WiFi.macAddress()) makes a temporary that’s destroyed at the end of that line, so clientId points into freed memory. Whatever the heap does next ends up in your client ID. Bit me on a sensor board years ago and I wasted a day too.

Same trap with setServer(host.c_str(), ...): PubSubClient keeps the pointer, not a copy, so if host is a local String in setup() you’ll get odd reconnect failures later.

Use buffers that live as long as the client:

static char clientId[32];
static char brokerHost[64];

void setupMqtt() {
  uint8_t mac[6];
  WiFi.macAddress(mac);
  snprintf(clientId, sizeof(clientId), "barn-%02x%02x%02x", mac[3], mac[4], mac[5]);
  strlcpy(brokerHost, settings.host.c_str(), sizeof(brokerHost));
  mqtt.setServer(brokerHost, 8883);
}

// later
mqtt.connect(clientId, settings.token.c_str(), "");

settings.token.c_str() is fine inside the call as long as settings lives globally.

Kabul edilen çözüm♥ 4

That was it. Static buffers and it connects first time on all five boards. I’d also been building the host in setup() exactly like you said, which explains the random reconnect failures I’d been blaming on my Wi-Fi. Thanks Laura.

♥ 0
7 yazı görüntüleniyor – 1 ile 7 arası (toplam 7)
  • 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.

Paylaş