• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Нужна помощь проблемы с WiFi.begin(ssid, pwd) arduino ide

Odin

New member
Всем доброго времени суток.
Возникла проблема с подключением к wifi.

в общем долго ковырялся и определил, что проблема в строке вызова:
Код:
WiFi.begin(ss, pw);
По порядку...
есть структура
Код:
struct ConfigData {
  const char* ssid;
  const char* pwd;
};
в методе setup() произвожу считывание в структуру данных из конфига (json файл)
все читается, все отлично.

делаю так:
Код:
    Serial.print("Connect to ");
    Serial.println(data.ssid);
    const char* ss  = data.ssid;
    const char* pw = data.pwd;

    delay(100);
    WiFi.mode(WIFI_OFF);
    WiFi.begin(ss, pw);
и получаю
Код:
Boot...
Boot version: 31
Boot mode: 1
Core version: 2_3_0
SDK version: 1.5.3(aec24ac9)
Chip ID: 8672780
Flash chip ID: 1458400
Flash chip real size: 4194304
CPU Freq: 80MHz
Sketch size: 280032
Free sketch space: 765952
Free heap: 40576

Connect to Keenetic-0502

ets Jan  8 2013,rst cause:4, boot mode:(1,6)

wdt reset
а стоит просто изменить:

Код:
    Serial.print("Connect to ");
    Serial.println(data.ssid);
    const char* ss  = "Keenetic-0502";
    const char* pw = "123456789";

    delay(100);
    WiFi.mode(WIFI_OFF);
    WiFi.begin(ss, pw);
Как все отлично работает.
я в C++ не силен, последний раз писал что-то на нем в 2002 году...
Прошу помощи.
 

Юрий Ботов

Moderator
Команда форума
Сталкивался с тем что в некоторых режимах авторизации некорректно обрабатываются пароли менее 10 символов (точкой доступа - Кинетиксом) и связь не устанавливается. Увеличьте пароль до 10-12 символов (если он короче).
 

Odin

New member
Пароли в обоих случаях одинаковы
но я не поленился проверить :)

Код:
Free sketch space: 765952
Free heap: 40528

{"ssid":"Keenetic-0502","pwd":"321654987000"}
Connect to  pwd 321654987000 / Keenetic-0502

ets Jan  8 2013,rst cause:4, boot mode:(1,6)

wdt reset
321654987000 - тестовый пароль.

Суть в том, что когда я присваиваю переменным текст:

Код:
 const char* ss  = "Keenetic-0502";
    const char* pw = "123456789";
Все работает идеально.
а когда использую так....

Код:
 const char* ss  = data.ssid;
const char* pw = data.pwd;
то получаю ошибку при подключении к сети....
 

tretyakov_sa

Moderator
Команда форума
Я сделал через String:
Код:
String _ssid     = ""; // Для хранения SSID
String _password = ""; // Для хранения пароля сети
String _ssidAP = "";   // SSID AP точки доступа
String _passwordAP = ""; // пароль точки доступа

void WIFIAP_Client() {
  WiFi.mode(WIFI_AP_STA);
  //WiFi.begin(ssid, password);
  Serial.print(_ssid);
  WiFi.begin(_ssid.c_str(), _password.c_str());
  WiFi.softAP(_ssidAP.c_str(), _passwordAP.c_str());

  IPAddress myIP = WiFi.softAPIP();
  Serial.print("AP IP address: ");
  Serial.println(myIP);
  int i = 0;
  while (WiFi.status() != WL_CONNECTED && i < 50) {
    delay(500);
    i++;
    Serial.print(".");
  }
}
 
  • Like
Реакции: Odin

Odin

New member
Я сделал через String:
Код:
String _ssid     = ""; // Для хранения SSID
String _password = ""; // Для хранения пароля сети
String _ssidAP = "";   // SSID AP точки доступа
String _passwordAP = ""; // пароль точки доступа

void WIFIAP_Client() {
  WiFi.mode(WIFI_AP_STA);
  //WiFi.begin(ssid, password);
  Serial.print(_ssid);
  WiFi.begin(_ssid.c_str(), _password.c_str());
  WiFi.softAP(_ssidAP.c_str(), _passwordAP.c_str());

  IPAddress myIP = WiFi.softAPIP();
  Serial.print("AP IP address: ");
  Serial.println(myIP);
  int i = 0;
  while (WiFi.status() != WL_CONNECTED && i < 50) {
    delay(500);
    i++;
    Serial.print(".");
  }
}
ДА!!!! Сразу заработало!!
2 дня я потратил... Спасибо большое!
 

Юрий Ботов

Moderator
Команда форума
Дошло. Дело в "const char*" . Это "указатель который всегда указывает на одно место, причем то что там записано может меняться". Ему нельзя присвоить переменную, только константу. При желании по идее можно сделать так:
const char* a = "застолбитьместо";
strcpy(a, переменная);
Само собой сверху подключить [HASHTAG]#include[/HASHTAG]<string.h>
 
  • Like
Реакции: Odin

KAPbI4

New member
Столкнулся с интересной особенностью String`а.

Код:
String _str = "192.168.1.1";
const char* _ch = _str.c_str();

Serial.println(_str); // все ок
Serial.println(_str.c_str()); // все ок
Serial.println(_ch); // а вот тут выдается какая-то хрень!
пришлось писать сою функцию

Код:
const char* c_str(String str) {
  unsigned char* buf = new unsigned char[str.length()];
  str.getBytes(buf, str.length()+1, 0);
  return (const char*) buf;
}

String _str = "192.168.1.1";
const char* _ch = c_str(_str);

Serial.println(_str); // все ок
Serial.println(c_str(_str)); // все ок
Serial.println(_ch); // теперь все ок!
Мистика!
 
Последнее редактирование:

Сергей_Ф

Moderator
Команда форума
@KAPbI4 нет никакой мистики. Просто Вы не понимаете как работает const char*. А С++ это не контролирует. У Вас он ссылается на временный буффер в первом варианте, а во втором на зарезервированный буфер. Потому и работает во втором и работает в первом, но не так как Вы хотите, а как приказали.
 

Юрий Ботов

Moderator
Команда форума
Нет мистики. Место надо заказать для хранения и туда скопировать полученное.
Код:
вместо

const char* _ch = _str.c_str();

надо

const char _ch[17]; // 17 для максимального ip adress + 0 символ. Тут достаточно  12.
strcpy(_ch,_str.c_str())
 

KAPbI4

New member
Нет мистики. Место надо заказать для хранения и туда скопировать полученное.
Код:
вместо

const char* _ch = _str.c_str();

надо

const char _ch[17]; // 17 для максимального ip adress + 0 символ. Тут достаточно  12.
strcpy(_ch,_str.c_str())
Неудачный пример привел.
Проблема в том что конструкция:

Код:
mqttClient.setServer(mqtt_srv.c_str(), mqtt_port.toInt());
не всегда работает правильно!
 
Последнее редактирование:

Сергей_Ф

Moderator
Команда форума
@KAPbI4 а почему Вы уверены, что она должна работать как Вы хотите? Ещё раз повторю, const char* - это не строка символов. Это статичный указатель на область памяти, который компилятор интерпретирует как набор символов.
На что он будет ссылаться в случае
mqttClient.setServer(mqtt_srv.c_str(), mqtt_port.toInt());
( А это mqttClient.setServer( const char*, int))
Известно только компилятору, и в это место может писать кто угодно в любой момент времени.
Вы же место не зарезервировали.
Вы поставили авто на стоянку открытый и с ключами. Звоните другу и говорите, забери машину на такой стоянке место номер 7. Он едет, а машину угнали и другую поставили. Друг вскрывает машину и пригоняет Вам, а она не та. Разве друг виноват в том, что Вы машину не закрыли?
 
Последнее редактирование:

KAPbI4

New member
@KAPbI4 а почему Вы уверены, что она должна работать как Вы хотите? Ещё раз повторю, const char* - это не строка символов. Это статичный указатель на область памяти, который компилятор интерпретирует как набор символов.
На что он будет ссылаться в случае

( А это mqttClient.setServer( const char*, int))
Известно только компилятору, и в это место может писать кто угодно в любой момент времени.
Вы же место не зарезервировали.
Вы поставили авто на стоянку открытый и с ключами. Звоните другу и говорите, забери машину на такой стоянке место номер 7. Он едет, а машину угнали и другую поставили. Друг вскрывает машину и пригоняет Вам, а она не та. Разве друг виноват в том, что Вы машину не закрыли?
Да, я не компетентен в этом вопросе, но почему вы не поправляете других?
Поясните код выше:

Я сделал через String:
Код:
  ...
WiFi.begin(_ssid.c_str(), _password.c_str());
WiFi.softAP(_ssidAP.c_str(), _passwordAP.c_str());
...
 

Сергей_Ф

Moderator
Команда форума
Да, я не компетентен в этом вопросе, но почему вы не поправляете других?
а кого надо ещё "поправлять"? Вам предложили уже два варианта, а Вы опять на те же грабли наступаете. Полно же учебников в Интернете по С++. Просто почитайте. Раздел Указатели.
 

KAPbI4

New member
а кого надо ещё "поправлять"? Вам предложили уже два варианта, а Вы опять на те же грабли наступаете. Полно же учебников в Интернете по С++. Просто почитайте. Раздел Указатели.
Сергей_Ф, Вы хотите сказать что tretyakov_sa ("Moderator", "Команда форума") сознательно допустил ошибки чтоб ввести в заблуждение посетителей форума?!

А самое интересное что вы так и не помогли Odin у него как раз проблема была в том что он не выделял память для переменных.
Код:
    const char* ss  = data.ssid;
    const char* pw = data.pwd;
 
Последнее редактирование:

Сергей_Ф

Moderator
Команда форума
@KAPbI4 насколько я понял у @Odin все заработало, значит никто никого в заблуждение не ввел. @tretyakov_sa правильно подсказал, там память выделена, просто Вы не видите где. А это делает String.
Каюсь, я Вас перепутал с ТС. Извините.
У Вас есть два пути, либо разобраться что такое указатели и как они работают, или пользоваться тем, что Вам подсказали. Последний путь ведет в тупик, имхо.
 

KAPbI4

New member
@KAPbI4 насколько я понял у @Odin все заработало, значит никто никого в заблуждение не ввел. @tretyakov_sa правильно подсказал, там память выделена, просто Вы не видите где. А это делает String.
Каюсь, я Вас перепутал с ТС. Извините.
У Вас есть два пути, либо разобраться что такое указатели и как они работают, или пользоваться тем, что Вам подсказали. Последний путь ведет в тупик, имхо.
Сергей_Ф, я имею общее представление о выделение памяти, но я и правда не вижу где в примере @tretyakov_sa выделяется память. И меня больше всего интересует чего не хватает в моем примере, учитывая что я вместо

Код:
const char* _ch = mqtt_srv.c_str();
mqttClient.setServer(_ch, mqtt_port.toInt());
использовал

Код:
mqttClient.setServer(mqtt_srv.c_str(), mqtt_port.toInt());
Я и сам пользовался такой формой записи
Код:
WiFi.begin(_ssid.c_str(), _password.c_str());
до того момента как микроконтроллер стал мудрить, пришлось предварительно выделять память для каждой переменной.

Это нормально?!
 

Сергей_Ф

Moderator
Команда форума
чего не хватает в моем примере, учитывая что я вместо
В данном случае надо увидеть всё что до этого момента в Вашей программе есть. Выделять память для набора символов (массива) - это абсолютно нормально. Другое дело, что механизмов выделения довольно много и работают они по разному.
Вот вам надо хранить где то зимние шины, вы оплачивает место (резервируете). Если не оплатите, то туда положат другие шины. А если свои положите не оплатив, ваши кто то выкинет и положит другие. Так что надо резервировать место. Но место для Вас может и диллер зарезервировать или продавец, Вы об этом можете и не знать.
А если машину продали, можно не оплачивать (освободить память). Как то так.
 

Сергей_Ф

Moderator
Команда форума
@KAPbI4 кстати, посмотрел Вашу функцию - она некорректная. Ваш буфер зарезервирован только в пределах функции, потому возвращать указатель на него некорректно. Некоторое время он будет указывать на нужные данные, но очень быстро они затрутся чем то другим. То что у Вас работает, это случай. Попробуйте сделать что то ещё между присваиваем и выводом - содержимое изменится.

Яндекс
 

KAPbI4

New member
В данном случае надо увидеть всё что до этого момента в Вашей программе есть. Выделять память для набора символов - это абсолютно нормально. Другое дело, что механизмов выделения довольно много и работают они по разному.
Вот вам надо хранить где то зимние шины, вы оплачивает место (резервируете). Если не оплатите, то туда положат другие шины. А если свои положите не оплатив, ваши кто то выкинет и положит другие. Так что надо резервировать место. А если машину продали, можно не оплачивать (освободить память). Как то так.
Вот часть кода
Код:
//Загружается через JSON, возвращается String
String ssid_sta = "192.168.1.1";
String ssid_sta_pass = "pass";
...
WiFi.disconnect();
WiFi.mode(WIFI_STA);
...
//Было так:
//WiFi.begin(ssid_sta.c_str(), ssid_sta_pass.c_str());
//Стало так:
const char* _ssid = c_str(ssid_sta);
const char* _pass = c_str(ssid_sta_pass);
WiFi.begin(_ssid, _pass);
...
Я искренне надеялся что String.c_str() выделяет память, похоже что нет или что-то пошло не так...
 

Сергей_Ф

Moderator
Команда форума
String.c_str() выделяет память,
нет, он просто возвращает адрес буффер. Выделяет память объявление переменной типа String. Все остальное, надо смотреть в описании. Вы весь код не привели, а гадать можно бесконечно. Я же не знаю где Вы объявили String.
 
Сверху Снизу