ESP8266 12-E не может подключиться ни к одной точке доступа с преобразованными переменными из строк в массивы символов

Я использую esp8266 12-E nodemcu Я написал код, который сканирует доступные сети WiFi, выводит их через последовательную связь, спрашивает пользователя, к какой сети он хочет подключиться, а затем пароль для этой сети. Проблема в том, что nodemcu не подключается к этой сети. Я думаю, что проблема в том, что я преобразую строки buffer_pw и buffer_ssid в массивы символов password и ssid. Почему возникают проблемы с подключением?

#include <ESP8266WiFi.h>

int num_ap; //количество точек доступа
String buffer_ssid = "empty"; //временно сохраняет ssid здесь, потому что затем его нужно будет преобразовать в массив символов
String buffer_pw = "empty"; //временно хранит пароль и то же самое, что^^
bool askPW = false; //"Я уже спрашивал пароль?"
bool connesso = false; //"Я уже подключился?"


void setup()
{
  Serial.begin(9600);
  WiFi.mode(WIFI_STA); //переводим nodemcu в режим sta, чтобы он мог подключаться к точкам доступа
  WiFi.disconnect();   //отключается от любой точки доступа, к которой был подключен
  Serial.println("Setup completo"); 
  num_ap = WiFi.scanNetworks(); //сканирует точки доступа
  if (num_ap == 0)   //если нет доступных точек доступа
  {
    Serial.println("Nessun Access Point rilevato");
  }
  else //если есть доступные точки доступа
  {
    Serial.println("Access Point rilevati:");
    delay(200);
    for (int i = 0; i < num_ap; i++)
    {
      Serial.println(" ");
      Serial.print(i + 1);
      Serial.print(") ");
      Serial.print(WiFi.SSID(i)); //вывести ssid точки доступа
      Serial.print(" ");
      Serial.print("(Potenza segnale: ");
      Serial.print(WiFi.RSSI(i)); //выводит rssi точки доступа (силу сигнала)
      Serial.print(")");
      delay(50);
    }
    delay(500);
    Serial.println(" ");
    Serial.println(" ");
    Serial.println("A quale Access Point ti vuoi connettere?");

  }
}



void loop()
{
  if (buffer_ssid == "empty") //если переменная имеет стандартное значение "empty", то есть если пользователь уже указал ssid. Мне это нужно, чтобы выполнить этот фрагмент кода один раз
   {
    if (Serial.available() > 0)
     {
      buffer_ssid = Serial.readString();  //сохраняет пользовательский ввод (ssid) в buffer_ssid
      if (buffer_ssid != "empty") //если переменная не пустая (если код успешно сохранил ssid), печатает ssid
       {
        Serial.println(buffer_ssid);
       }
     }
   }

  if(buffer_ssid != "empty") //если пользователь указал ssid
  {
   if(askPW == false) //если код запросил пароль(мне это нужно, чтобы выполнить этот фрагмент кода один раз)
    {
     Serial.println("Inserire la password per connettersi all'Access Point, se non serve premere spazio e invio"); //"вставьте пароль"
     askPW = true;
    }
    if (Serial.available() > 0)
    {
      buffer_pw = Serial.readString(); //сохраняет введенные пользователем данные (пароль) в переменной buffer_pw
      if(buffer_pw != "empty") //если код успешно сохранил пароль, то он не имеет стандартного значения "empty"
      {
        Serial.println(buffer_pw);
      }
    }
  }

  if (buffer_pw != "empty" && buffer_ssid != "empty") //если buffer_ssid и buffer_pw не "пустые", то если пользователь вставил их
  {
    if(connesso == false) //чтобы выполнить этот фрагмент кода один раз
    {
     //преобразует строки buffer_ssid и buffer_pw в массивы символов (мне приходится это делать, потому что WiFi.begin() не принимает строки)
     char ssid[buffer_ssid.length()];
     buffer_ssid.toCharArray(ssid,buffer_ssid.length());
     char password[buffer_pw.length()];
     buffer_pw.toCharArray(password,buffer_pw.length());
     //начать подключение
     Serial.println("Connessione in corso");
     Serial.println(ssid); //выводит ssid
     Serial.println(password);//выводит пароль, чтобы я знал, что он был успешно преобразован
     WiFi.begin(ssid,password);//начать подключение
     while(WiFi.status() != WL_CONNECTED) //пока не подключено
     {
      Serial.print(".");
      delay(500); 
     }
      Serial.println("Connesso!"); //"Подключено!"
      Serial.println("Il mio ip locale: ");
      Serial.print(WiFi.localIP()); //локальный IP-адрес nodemcu

    }
    connesso = true;  //установите connesso в значение true, чтобы этот фрагмент кода не зацикливался
  }
}

, 👍0

Обсуждение

[Не допускайте перекрестного постинга.](https://meta.stackexchange.com/q/64068) Вы уже [задавали этот вопрос на SO](https://stackoverflow.com/q/52010255)., @gre_gor

Хорошо, спасибо, я больше так не буду. Я сделал это, потому что парень в комментарии предложил мне задать этот вопрос в этом Stack Exchange, @MyAlexro


1 ответ


Лучший ответ:

1

Проблема в том, что вы устанавливаете в toCharArray длину строки. Но второй параметр — это максимально допустимая длина вывода, и тогда нет места для завершающего нуля, и строка обрезается на последнем символе.

Функция toCharArray знает размер строки. Вторым параметром должен быть размер массива символов buffer_ssid.toCharArray(ssid, sizeof(ssid));

И следующая проблема может быть в том, что вы копируете символы CR/LF из ввода в sid и пароль. Вы можете увидеть это в отладочных распечатках.

,

Спасибо большое! Одна проблема, мне пришлось добавить "- 1" к длине символа, так что теперь это: char ssid[buffer_ssid.length() - 1]; символьный пароль[buffer_pw.length() - 1];, @MyAlexro

потому что вы оставили там CR/LF. это отключает их. но это неправильное решение. установите None или только CR или LF в Serial Monitor, и это снова будет неправильно, @Juraj

@MyAlexro Лучше вообще избегать массивов. Вам не нужно копировать в них содержимое строк — просто используйте метод c_str() String. Вы вызовете WiFi.begin(buffer_ssid.c_str(), buffer_pw.c_str()) и пропустите копии и char[]s. c_str() очень эффективен; он просто возвращает указатель на внутренний буфер символов строки. Конечно, после того, как вы обрежете CRLF из конца ваших строк., @romkey

@JohnRomkey Хорошо, спасибо, я не знал об этой функции., @MyAlexro