Ошибка при подключении к mqtt

Рейтинг: 0Ответов: 1Опубликовано: 20.06.2023

Всем привет, пишу что-то на подобии умной розетки и столкнулся с проблемой, что PubSubClient категорически отказывается подключаться к mqtt, хотя все настройки, адреса и данные для авторизации правильные. Пишу на стаке GyverPortal + EEPROM + PubSubClient. Логика такова: подключаемся к wifi, пробуем подключится к mqtt брокеру, если неудачно, то открываем портал для обновления данных для работы с mqtt, которые записываем в eeprom память, после подключаемся и слушаем команды. Всё, кроме последнего пункта я сделал, но при попытке подключиться выдаёт код ошибки -2, что значит неправильные данные (хотя они точно правильные). И я нашёл проблему - структура LoginPass с char значениями, почему-то он не хочет их принимать (или какая-то другая ошибка). Вот код:

#define AP_SSID "ssid"
#define AP_PASS "1243234234"
#include <GyverPortal.h>
#include <EEPROM.h>
#include <PubSubClient.h>

struct LoginPass {
  char url[20];
  char port[20];
  char login[20];
  char pasw[20];
};

LoginPass lp;

WiFiClient espClient;
PubSubClient client(espClient);

void setup_wifi() {

  delay(10);
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(AP_SSID);

  WiFi.mode(WIFI_STA);
  WiFi.begin(AP_SSID, AP_PASS);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  randomSeed(micros());

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}


void build() {

  GP.BUILD_BEGIN();
  GP.THEME(GP_DARK);

  GP.FORM_BEGIN("/login");
  GP.TEXT("ur", "Url", lp.url);
  GP.BREAK(); 
  GP.TEXT("po", "Port", lp.port);
  GP.BREAK();
  GP.TEXT("lg", "Login", lp.login);
  GP.BREAK();
  GP.TEXT("ps", "Password", lp.pasw);
  GP.SUBMIT("Submit");
  GP.FORM_END();

  GP.BUILD_END();
}

void setup() {
  Serial.begin(115200);
  setup_wifi();
  
  EEPROM.begin(100);
  EEPROM.get(0, lp);

  Serial.println("Url: ");
  Serial.println(lp.url);
  Serial.println("Port: ");
  Serial.println(lp.port);
  Serial.println("Login: ");
  Serial.println(lp.login);
  Serial.println("Passw: ");
  Serial.println(lp.pasw);
  
  
  client.setServer(lp.url, (int)lp.port);
  client.setCallback(MQTTcallback);

}

void reconnect() {
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");

    if (client.connect("EspDoors", lp.login, lp.pasw) ) {
      Serial.println("connected");
      
      client.subscribe("doors");

    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      //delay(5000);
      loginPortal(); // если ошибка, то открываем портал для обновления данных
    }
  }
}

void MQTTcallback(char* topic, byte* payload, unsigned int length) 
{
  Serial.print("Message received in topic: ");
  Serial.println(topic);
  Serial.print("Message:");
  String message;
  for (int i = 0; i < length; i++) 
  {
    message = message + (char)payload[i];
  }
  Serial.print(message);
  if (message == "on") 
  {
    Serial.print(message);
  }
  else if (message == "off") 
  {
    Serial.print(message);
  }
  Serial.println();
  Serial.println("-----------------------");
}

void loginPortal() {
  Serial.println("Portal start");

  // запускаем портал
  GyverPortal ui;
  ui.attachBuild(build);
  ui.start();
  ui.attach(action);

  // работа портала
  while (ui.tick());
}

void action(GyverPortal& p) {
  if (p.form("/login")) {      // кнопка нажата
    p.copyStr("ur", lp.url);  // копируем себе
    p.copyStr("po", lp.port);
    p.copyStr("lg", lp.login);
    p.copyStr("ps", lp.pasw);
    EEPROM.put(0, lp);              // сохраняем
    EEPROM.commit();                // записываем
    Serial.println("Updated eeprom");
    ESP.restart();
  }
}

void loop() {

  if (!client.connected()) {
    reconnect();
  }
  client.loop();

}

Буду рад любой помощи! P.S. брокер в логах молчит

Ответы

▲ 0

В общем починил вот так: с client.setServer(lp.url, (int)lp.port); на client.setServer(lp.url, atoi(lp.port));