• Уважаемые посетители сайта esp8266.ru!
    Мы отказались от размещения рекламы на страницах форума для большего комфорта пользователей.
    Вы можете оказать посильную поддержку администрации форума. Данные средства пойдут на оплату услуг облачных провайдеров для сайта esp8266.ru
  • Система автоматизации с открытым исходным кодом на базе 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.
 
Сверху Снизу