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

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

Gelöst 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.

Akzeptierte Lösung♥ 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
Ansicht von 7 Beiträgen – 1 bis 7 (von insgesamt 7)
  • 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