Проблема с подключением MQTT PubSubClient к ESP32
У меня возникли некоторые проблемы со строкой в приложении Arduino с ESP32. Я не понимаю, почему этот код работает:
mqtt.setServer("m20.cloudmqtt.com", порт); //в порядке
а это не работает не подключается
String strSBM = "m20.cloudmqtt.com";
mqtt.setServer(strSBM.c_str(), порт); //нет ОК
Я использую библиотеку PubSubClient 2.7
Любой из вас может мне помочь
Большое спасибо
@Michele, 👍0
1 ответ
Когда вы устанавливаете сервер из строки C, он не копирует строку, а просто сохраняет указатель на нее:
PubSubClient& PubSubClient::setServer(const char * domain, uint16_t port) {
this->domain = domain;
this->port = port;
return *this;
}
Если строка, на которую он указывает, выходит за пределы области видимости (это локальная переменная и функция завершает работу), данные строки будут признаны недействительными и потеряны.
Он действительно предназначен для работы со строковыми литералами и глобальными постоянными переменными, которые никогда не изменяются.
Если это единственный раз, когда вы когда-либо устанавливали сервер, вы можете обойтись без использования strdup()
для дублирования строковых данных в куче, но без прямого доступа к domain
класса PubSubClient
, у вас нет возможности снова free()
память, если вы когда-нибудь захотите сменить сервер.
String strSBM = "m20.cloudmqtt.com";
mqtt.setServer (strdup(strSBM.c_str()), port);
Чтобы сделать так, чтобы вы могли освободить
значение, вам нужно отслеживать его отдельно:
static char *temp = NULL;
if (temp != NULL) {
free(temp);
temp = NULL;
}
temp = strdup(strSBM.c_str());
mqtt.setServer(temp, port);
- esp32-cam публикует изображение в mqtt
- Публиковать данные json в mqtt
- Не удалось подключиться к брокеру MQTT через esp8266/32 и pub/sub client
- PubSubClient: Подписка работает, но обратный вызов никогда не вызывался
- Подключение ESP32 через MQTT
- Невозможно подключить ESP32 к Mosquitto на Raspberry с использованием сертификатов
- Несколько тем MQTT
- Опубликовать чип в mqtt с помощью ESP32-CAM
та же проблема с номером порта какую функцию я должен использовать для порта? Спасибо за вашу помощь, @Michele
Нет, не та же проблема с номером порта - это просто номер, и он копируется. Проблема существует только для имени сервера, потому что это указатель., @Majenko
Хорошо, теперь все работает с client.setServer(strdup(strSBM.c_str()), (int)strPSBM.toInt());, @Michele
Пока вы делаете это только один раз, все в порядке - если вы сделаете это более одного раза, вы создадите утечку памяти, и через некоторое время вы выйдете из строя. Почему именно вы хотите, чтобы имя сервера было в строке?, @Majenko
Ооо, тогда это не хорошо для меня, потому что в моем проекте я сохраняю имя сервера и номер порта во внешнюю EEPROM и у меня есть возможность изменить параметры конфигурации. Так что иметь статические параметры нехорошо. У Вас есть какие-то предложения?, @Michele
Создайте глобальный массив
char
для хранения данных. Считайте его из EEPROM в этот массив char, а затем передайте его в setServer как есть. Каждый раз, когда вы изменяете содержимое этого массива символов, библиотека PubSubClient мгновенно увидит новые данные — все, что осталось, — это снова подключиться., @MajenkoХорошая идея, но мой проект слишком сложен для этого изменения. Что вы думаете об этой аренде символ * темп; бесплатно (темп); temp = strdup(strSBM.c_str()); client.setServer (временный, 15534); так что каждый раз я меняю параметры пустого сервера с помощью free() ??? идея помогите помогите помогите, @Michele
Конечно, это могло бы сработать, пока
temp
является глобальным или статическим, поэтому он остается все время.статический символ *temp = NULL; если (temp!= NULL) { бесплатно(temp); темп = НУЛЬ; } temp = strdup(strSBM.c_str());
- Важно убедиться, что дляtemp
действительно что-то выделено, прежде чем пытаться егоосвободить
..., @Majenko