I'm using an esp8266 12-E nodemcu I wrote a code that scans the available WiFi networks, print them through serial communication,ask the user which network he wants to connect to and then the password for that network. The problem is that the nodemcu won't connect to that network. I think that the problem is when I convert the strings buffer_pw and buffer_ssid to the char arrays password and ssid. Why does it give problems to connect?
#include <ESP8266WiFi.h>
int num_ap; //number of access points
String buffer_ssid = "empty"; //temporary stores the ssid in here because then it has to be converted in a char array
String buffer_pw = "empty"; //temporary stores password and same thing as^^
bool askPW = false; //"Did I already ask the password?"
bool connesso = false; //"Did I already connect?"
void setup()
{
Serial.begin(9600);
WiFi.mode(WIFI_STA); //put the nodemcu in sta mode so that it can connect to access points
WiFi.disconnect(); //it disconnects from any access point it was connected to
Serial.println("Setup completo");
num_ap = WiFi.scanNetworks(); //scans for access points
if (num_ap == 0) //if there aren't any access points available
{
Serial.println("Nessun Access Point rilevato");
}
else //if there are some access points available
{
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)); //print access point's ssid
Serial.print(" ");
Serial.print("(Potenza segnale: ");
Serial.print(WiFi.RSSI(i)); //prints access point's rssi(strength of signal)
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") //if the variable has the standard value "empty" so if the user has already given an ssid. I need this to execute this piece of code once
{
if (Serial.available() > 0)
{
buffer_ssid = Serial.readString(); //stores user input(the ssid) in buffer_ssid
if (buffer_ssid != "empty") //if the variable isn't empty(if the code has successfully saved the ssid) prints the ssid
{
Serial.println(buffer_ssid);
}
}
}
if(buffer_ssid != "empty") //if the user has given an ssid
{
if(askPW == false) //if the code has asked the password(I need this in order to execute this piece of code once)
{
Serial.println("Inserire la password per connettersi all'Access Point, se non serve premere spazio e invio"); //"insert the password"
askPW = true;
}
if (Serial.available() > 0)
{
buffer_pw = Serial.readString(); //saves user input(the password) in the variable buffer_pw
if(buffer_pw != "empty") //if the code has successfully saved the password so it hasn't the standard value "empty"
{
Serial.println(buffer_pw);
}
}
}
if (buffer_pw != "empty" && buffer_ssid != "empty") //if buffer_ssid and buffer_pw aren't "empty", so if the user inserted them
{
if(connesso == false) //in order to execute this piece of code once
{
//converts the strings buffer_ssid and buffer_pw in char arrays(I have to do this because WiFi.begin() doesn't accept strings)
char ssid[buffer_ssid.length()];
buffer_ssid.toCharArray(ssid,buffer_ssid.length());
char password[buffer_pw.length()];
buffer_pw.toCharArray(password,buffer_pw.length());
//start connecting
Serial.println("Connessione in corso");
Serial.println(ssid); //prints ssid
Serial.println(password);//prints password so I know that they were converted succesffully
WiFi.begin(ssid,password);//start connecting
while(WiFi.status() != WL_CONNECTED) //while it's not connected
{
Serial.print(".");
delay(500);
}
Serial.println("Connesso!"); //"Connected!"
Serial.println("Il mio ip locale: ");
Serial.print(WiFi.localIP()); //nodemcu's local IP
}
connesso = true; //set connesso to true so that this piece of code doesn't loop
}
}
-
Don't cross post. You already asked this on SO.gre_gor– gre_gor08/24/2018 22:38:12Commented Aug 24, 2018 at 22:38
-
Ok thanks, I won't do that anymore. I did this because a guy in the comment suggested me to ask this question in this Stack ExchangeMyAlexro– MyAlexro08/24/2018 23:28:37Commented Aug 24, 2018 at 23:28
1 Answer 1
Problem is that you set to toCharArray
the length of the String. But the second parameter is the maximum allowed length of the output and there is then no space for the terminating zero and string is cut at last character.
The function toCharArray knows the size of the String. The second parameter should be the size of the char array buffer_ssid.toCharArray(ssid, sizeof(ssid));
And next problem could be that you copy the CR/LF characters from input into ssid and password. You can see it in debug printouts.
-
Thank you very much! One thing is that I had to add "- 1" to the char length, so now it is: char ssid[buffer_ssid.length() - 1]; char password[buffer_pw.length() - 1];MyAlexro– MyAlexro08/25/2018 10:28:03Commented Aug 25, 2018 at 10:28
-
because you left the CR/LF there. this cuts it out. but it is not the right solution. set None or only CR or LF in Serial Monitor and it will be wrong again08/25/2018 11:09:54Commented Aug 25, 2018 at 11:09
-
1@MyAlexro You're better off avoiding the arrays altogether. You don't need to copy the String contents into them - just use the c_str() String method. You'd call WiFi.begin(buffer_ssid.c_str(), buffer_pw.c_str()) and skip the copies and char[]s. c_str() is very efficient; it just returns a pointer to the String's internal character buffer. Of course, after you trim the CRLF from the end of your Strings.romkey– romkey08/26/2018 02:05:54Commented Aug 26, 2018 at 2:05
-
@JohnRomkey Ok thanks, I didn't know that functionMyAlexro– MyAlexro08/26/2018 12:39:01Commented Aug 26, 2018 at 12:39