точка доступа для выбора и подключения к wi-fi

igorlab
Offline
Зарегистрирован: 11.11.2015

привет, народ, есть у кого-то пример кода для ESP32 or ESP8266, который создает точку доступа для выбора и подключения к wifi, а затем, подключившись к wifi запоминает пароль  и используя это подключение создает web server? 

заранее спасибо!

vvadim
Offline
Зарегистрирован: 23.05.2012

в гугле примеров тыщщщи, забанили ?

igorlab
Offline
Зарегистрирован: 11.11.2015

буду благодарен хотябы за один... 

при поиске по запросу "arduino точка доступа для выбора и подключения к wi-fi" нихрена путнего не находит 

FoxJone
Offline
Зарегистрирован: 19.04.2019

Я так понимаю, что вам нужно:

а) Создать на базе ESP точку доступа с вебмордой.

б) Подключиться к вебморде и в ней выбрать WiFi-сеть для подключения (ввести пароль и все прочие настройки).

в) Переподключить ESP в режим клиента, подключенного к выбранной сети и запустить вебсервер.

Все эти вещи есть в стандартных примерах ESP. Вам нужно только собрать это все в кучу. Готовую программу вы вряд ли найдете.

igorlab
Offline
Зарегистрирован: 11.11.2015

FoxJone, спасибо за совет.

точку доступа создал, в предложеном Вами алгоритме после перезагрузки надо будет опять искать сеть и вводить пароль, а затем переключаться или пароль бвудет сохранен? 

vitalikost
Offline
Зарегистрирован: 28.11.2014

Я вот использую эту. https://github.com/tzapu/WiFiManager

FoxJone
Offline
Зарегистрирован: 19.04.2019

igorlab пишет:

FoxJone, спасибо за совет.

точку доступа создал, в предложеном Вами алгоритме после перезагрузки надо будет опять искать сеть и вводить пароль, а затем переключаться или пароль бвудет сохранен? 

После настройки клиента пишите настройки (сеть, пароль и флаг того, что клиент настроен) в постоянную память (например, в EEPROM, или к примеру на SD-карту, если такая есть в конструкции) и при загрузке читайте их оттуда.

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017
void loadDataWiFiEEPROM() {
  byte i = 0; while (((eep_str[i] = EEPROM.read(eep_pos_wifi_p1 + i)) > 0) && (i < eep_max_len_param)) ++i; eep_str[i] = 0;
  strcpy(ssid, eep_str);
  i = 0; while (((eep_str[i] = EEPROM.read(eep_pos_wifi_p2 + i)) > 0) && (i < eep_max_len_param)) ++i; eep_str[i] = 0;
  strcpy(password, eep_str);
}

void EEPROMinit() {
  EEPROM.begin(eep_max_len_param * eep_max_count_params);
}

                        // save
                        String str_ppid = header.substring(p_id + 5, p_pp);
                        str_ppid.toCharArray(eep_str, l_id + 1); eep_str[l_id] = 0;
                        byte i = 0; while (eep_str[i] > 0) {
                          EEPROM.write(eep_pos_wifi_p1 + i, eep_str[i]); ++i;
                        } EEPROM.write(eep_pos_wifi_p1 + i, 0);
                        str_ppid = header.substring(p_pp + 6, p_act);
                        str_ppid.toCharArray(eep_str, l_pp + 1); eep_str[l_pp] = 0;
                        i = 0; while (eep_str[i] > 0) {
                          EEPROM.write(eep_pos_wifi_p2 + i, eep_str[i]); ++i;
                        } EEPROM.write(eep_pos_wifi_p2 + i, 0);
                        EEPROM.commit();
                        EEPROM.end();
                        EEPROMinit();
                        loadDataWiFiEEPROM();
                        // stop server and wifi

 

igorlab
Offline
Зарегистрирован: 11.11.2015

Мужики, спасибо за подсказки в каком направлении двигаться, к сожалению готовые решения не помогли - это часть огромного проэкта и попытка внедрить тот же вифи-менеджер приводила к неработоспособности кода сервера и телеграмм-бота, поэтому написал костыльный, но рабочий подход. В eeprom выделяется место 40 байт под хранение двух пар: ssid и пароль, при запуске ЕСПхи пробуются имеющиеся пароли - если не удается подключиться, то создается точка доступа с простой формой - только для вводи имени сети и пароля. дальше проблемка))) в терминале вижу строку с введенными ИД и паролем:

 

но не пойму как она выводится (в коде нет такго сериал-принтлайна), как это вывести в скетче, где это выводится в библеотеке тоже пока не нашел - поиск по слову в документе "Referer: " в папке с библитоеками ничего не находит, да и не придумал как разбить на аргументы, юзать регулярные выражения или есть более простой способ?.

в планах:

- добавить сканер доступных сетей, чтобы не вводить название, а выбирать. 

- возможно отимизировать место в памяти, а не выделять по 10  символов на каждый пароль и ssid 

#include <EEPROM.h>
#include <WiFi.h>

WiFiServer wifi_server(80);
byte wifi_server_run = 0;

#define last_byte_to_eeprom   106
String    webpage;


// Variable to store the HTTP request
String header;

// Replace with your network credentials
const char* ssid     = "KH-WiFi";
const char* password = "123456789";

void setup() {
  EEPROM.begin(last_byte_to_eeprom);
  Serial.begin(115200);
  connect_wifi ();
}

void loop() {
  while (true) {
    String command = Serial.readString(); // read a command
    if (command == "") break; // if no more commands, then exit

    else if (command.startsWith("psw2")) { // для тестирования записи ИД сети и пароля в EEPROM
      Serial.println("psw2");
      write_wifi_password("Guest", "88888888");
    }
    else if (command.startsWith("psw1")) { // для тестирования записи ИД сети и пароля в EEPROM
      Serial.println("psw1");
      write_wifi_password("ASUS", "99999999");
    }
  }

  if (wifi_server_run == 1) { // если не законектились к вайфаю начинаем слушать 

    WiFiClient client = wifi_server.available();   // Listen for incoming clients

    if (client ) {                             // If a new client connects,
      Serial.println("New Client.");          // print a message out in the serial port
      String currentLine = "";                // make a String to hold incoming data from the client
      while (client.connected()) {            // loop while the client's connected
        if (client.available()) {             // if there's bytes to read from the client,
          char c = client.read();             // read a byte, then
          Serial.write(c);                    // print it out the serial monitor
          header += c;
          if (c == '\n') {                    // if the byte is a newline character
            // if the current line is blank, you got two newline characters in a row.
            // that's the end of the client HTTP request, so send a response:
            if (currentLine.length() == 0) {
              // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
              // and a content-type so the client knows what's coming, then a blank line:
              client.println("HTTP/1.1 200 OK");
              client.println("Content-type:text/html");
              client.println("Connection: close");
              client.println();

              // turns the GPIOs on and off
              if (header.indexOf("wifisave") >= 0) {
                Serial.print("header ");Serial.println(header);                       
              } 

              // Display the HTML web page
              client.println("<!DOCTYPE html> <html lang=\"en\"> <head> <meta charset=\"UTF-8\"> <title>Title</title> <style> .wrapper { margin: 0 auto; text-align: center; } </style> </head> <body> <div class=\"wrapper\"> <form method='get' action='wifisave'> <input id='s' name='SSID' length=32 placeholder='SSID'><br/> <input id='p' name='password' length=64 type='password' placeholder='password'><br/> <br/><button type='submit'>save</button> </form> </div> </body> </html>");
              // The HTTP response ends with another blank line
              client.println();
              // Break out of the while loop
              break;
            } else { // if you got a newline, then clear currentLine
              currentLine = "";
            }
          } else if (c != '\r') {  // if you got anything else but a carriage return character,
            currentLine += c;      // add it to the end of the currentLine
          }
        }
      }      
      header = ""; // Clear the header variable      
      client.stop(); // Close the connection
      Serial.println("Client disconnected.");
      Serial.println("");
    }
  }
}
/*
    - Password and SSID couldn't be more than 10 chars
    - when writing new password the oldest one will be cleared
    - the script keeps max two pair of SSID and password
*/
void connect_wifi () {
  for (int i = 0; i < 30; i += 20) // пробуем подключиться к сети по всем паролям которіе есть в памяти
  {
    //    Serial.print("try: ");  Serial.println(i);
    char ssid[EEPROM_String_read(i).length() + 1];
    char password[EEPROM_String_read(i + 10).length() + 1] ;
    EEPROM_String_read(i).toCharArray(ssid, EEPROM_String_read(i).length() + 1);
    EEPROM_String_read(i + 10).toCharArray(password, EEPROM_String_read(i + 10).length() + 1);
    Serial.print("ssid: ");  Serial.print(ssid); Serial.print("; password: ");  Serial.println(password);

    int x = 0;
    WiFi.mode(WIFI_STA);
    WiFi.begin(ssid, password);
    while (x < 10) {
      if (WiFi.status() == WL_CONNECTED) break;
      Serial.println(x);
      x++;
      delay(500);
    }
    if (WiFi.status() == WL_CONNECTED)
    {
      Serial.println(""); Serial.println(F("WiFi connected")); Serial.print(F("IP address: ")); Serial.println(WiFi.localIP());
      break;
    }
  }
  if (WiFi.status() != WL_CONNECTED) { // если не подклбчились к сети - создаем точку доступа для ввода имени сети и пароля
    Serial.println("Cant connect to wifi");
    // Connect to Wi-Fi network with SSID and password
    Serial.print("Setting AP (Access Point)…"); // Remove the password parameter, if you want the AP (Access Point) to be open
    WiFi.softAP(ssid, password);
    IPAddress IP = WiFi.softAPIP();
    Serial.print("AP IP address: ");
    Serial.println(IP);
    Serial.println("Start local Wi-Fi server");
    wifi_server.begin();
    wifi_server_run = 1;
  }
}
void write_wifi_password (String ssid, String pswrd) { 
  Serial.print("ssid: ");  Serial.print(ssid);  Serial.print("; password: ");  Serial.println(pswrd);
  EEPROM_String_write(0,  EEPROM_String_read(20));
  EEPROM_String_write(10, EEPROM_String_read(30));
  EEPROM_String_write(20, ssid);
  EEPROM_String_write(30, pswrd);
}

void EEPROM_String_write(char add, String data)
{
  int _size = data.length();
  int i;
  for (i = 0; i < _size; i++)
    EEPROM.write(add + i, data[i]);
  EEPROM.write(add + _size, '\0'); //Add termination null character for String Data
  EEPROM.commit();
}

String EEPROM_String_read(char add)
{
  int i;
  char data[50]; //Max 100 Bytes
  int len = 0;
  unsigned char k;
  k = EEPROM.read(add);
  while (k != '\0' && len < 500) //Read until null character
  {
    k = EEPROM.read(add + len);
    data[len] = k;
    len++;
  }
  data[len] = '\0';
  return String(data);
}

 

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

Пример сканера сетей есть уже с библиотеками к платам
Чем вам не нравиться выделять по 10 байт под Логин пароль? Там памяти дофига
Работа с get и post запросами в esp8266 и esp32s немного отличается и библиотеки разные, но общий смысл одинаков- берём входящую строку и парсим её на нужные куски и вытаскиваем данные из нее

FoxJone
Offline
Зарегистрирован: 19.04.2019

С ESP32 не работал, ничего не могу сказать, а у ESP8266 море памяти и нормальная скорость, вполне себе может поддержать нормальный веб-интерфейс. Я на коленке собирал простенькую вебморду и успешно продал девайсину с ней клиенту - клиент очень был доволен тем, что управлять можно с любого устройства лишь бы был браузер. И это при том, что в html вообще играл чуть ли не первый раз в жизни. Не понимаю, зачем использовать GET-запросы м вообще все эти танцы с адресной строкой браузера.

С другой стороны, НАСТОЙЧИВО НЕ РЕКОМЕНДУЮ (сам обжегся очень) вешать на ESP8266 какие то другие задачи, кроме WiFi, web-сервера и вебинтерфейса. Ну максимум что то простенькое, типа кнопки или датчика температуры. Иначе, ой сколько вам открытий чудных готовит парадоксов друг....

igorlab
Offline
Зарегистрирован: 11.11.2015

добавил сканер, сделал парсинг строки, но после ее записи (строка write_wifi_password ( String(SSID_s), String(password_s)); // ТАК НЕ РАБОТАЕТ - ВИСНЕТ) и попытке обращения к этой ячейке - происходит перезагрузка еспэхи... чтобы вернуть есп к жизни приходится заплнять память нулями...

хел плиз...

if (header.indexOf("GET /wifisave?") >= 0) {
                Serial.print("!!!!!!!!!!header "); Serial.println(header);//String header = "GET /wifisave?SSID=ASUS&password=123456 HTTP/1.1";
                header.replace("GET /wifisave?SSID=", "");
                header.replace("password=", "");
                header.replace(" HTTP/1.1", "");

                char token1[header.length()];
                header.toCharArray(token1, header.length() + 1);
                //  header.toCharArray(token1, header.length() + 1);
                char *token = strtok(token1, "&");
                String SSID_s = token;
                token = strtok (NULL, "&");
                String password_s = token;                
                Serial.print("Extracted "); Serial.print(SSID_s);Serial.print(" "); Serial.println(password_s);
                delay(100);
                write_wifi_password ( String(SSID_s), String(password_s)); // ТАК НЕ РАБОТАЕТ - ВИСНЕТ
                // write_wifi_password("ASUS", "88888888"); // С ЭТОЙ СТРОКОЙ РАБОТАЕТ НОРМАЛЬНО
              }

полный код:

#include <EEPROM.h>
#include <WiFi.h>

WiFiServer wifi_server(80);
byte wifi_server_run = 0;
String wifi_ssid[20] = {};
int Networks_count = 0;

#define last_byte_to_eeprom   106
String    webpage;


// Variable to store the HTTP request
String header;

// Replace with your network credentials
const char* ssid     = "KH-цшаш";
const char* password = "123456789";


void setup() {
  EEPROM.begin(last_byte_to_eeprom);
  Serial.begin(115200);
  connect_wifi();
}

void loop() {
  while (true) {
    String command = Serial.readString(); // read a command
    if (command == "") break; // if no more commands, then exit

    else if (command.startsWith("psw2")) {
      Serial.println("psw2");
      String s = "Guest", p = "88888888";
      write_wifi_password(s, p);
    }
    else if (command.startsWith("psw1")) {
      Serial.println("psw1");
      write_wifi_password("ASUS", "88888888");
    }
  }

  if (wifi_server_run == 1) {
    WiFiClient client = wifi_server.available();   // Listen for incoming clients
    if (client ) {                             // If a new client connects,
      Serial.println("New Client.");          // print a message out in the serial port
      String currentLine = "";                // make a String to hold incoming data from the client
      while (client.connected()) {            // loop while the client's connected
        if (client.available()) {             // if there's bytes to read from the client,
          char c = client.read();             // read a byte, then
          Serial.write(c);                    // print it out the serial monitor
          header += c;
          if (c == '\n') {                    // if the byte is a newline character
            // if the current line is blank, you got two newline characters in a row.
            // that's the end of the client HTTP request, so send a response:
            if (currentLine.length() == 0) {
              // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
              // and a content-type so the client knows what's coming, then a blank line:
              client.println("HTTP/1.1 200 OK");
              client.println("Content-type:text/html");
              client.println("Connection: close");
              client.println();

              if (header.indexOf("GET /wifisave?") >= 0) {
                Serial.print("!!!!!!!!!!header "); Serial.println(header);//String header = "GET /wifisave?SSID=ASUS&password=123456 HTTP/1.1";
                header.replace("GET /wifisave?SSID=", "");
                header.replace("password=", "");
                header.replace(" HTTP/1.1", "");

                char token1[header.length()];
                header.toCharArray(token1, header.length() + 1);
                //  header.toCharArray(token1, header.length() + 1);
                char *token = strtok(token1, "&");
                String SSID_s = token;
                token = strtok (NULL, "&");
                String password_s = token;                
                Serial.print("Extracted "); Serial.print(SSID_s);Serial.print(" "); Serial.println(password_s);
                delay(100);
                write_wifi_password ( String(SSID_s), String(password_s)); // ТАК НЕ РАБОТАЕТ - ВИСНЕТ
                // write_wifi_password("ASUS", "88888888"); // С ЭТОЙ СТРОКОЙ РАБОТАЕТ НОРМАЛЬНО
              }
              String web = "<!DOCTYPE html> <html lang=\"en\"> <head> <meta charset=\"UTF-8\"> <title>Title</title> <style> .wrapper { margin: 0 auto; text-align: center; } </style> </head> <body> <div class=\"wrapper\"> <form method='get' action='wifisave'>";

              web += "<select id=\"SSID\" name=\"SSID\">";

              // Serial.print("Networks_count "); Serial.println(Networks_count);
              if (Networks_count > 0) {
                for (int i = 0; i < Networks_count; ++i) {
                  web += "<option value=\"" + WiFi.SSID(i) + "\">" + WiFi.SSID(i) + "</option>";
                  delay(10);
                }
              }
              // Display the HTML web page
              web += "</select>";

              //              web += "<input id='s' name='SSID' length=32 placeholder='SSID'>";

              web += "<br/> <input id='p' name='password' length=64 type='password' placeholder='password'><span></span><br/> <br/><button type='submit'>save</button> </form> </div> </body> </html>";
              client.println(web);
              // The HTTP response ends with another blank line
              client.println();
              // Break out of the while loop
              break;
            } else { // if you got a newline, then clear currentLine
              currentLine = "";
            }
          } else if (c != '\r') {  // if you got anything else but a carriage return character,
            currentLine += c;      // add it to the end of the currentLine
          }
        }
      }
      // Clear the header variable
      header = "";
      // Close the connection
      client.stop();
      Serial.println("Client disconnected.");
      Serial.println("");
    }
  }
}

/*
    - Password and SSID couldn't be more than 10 chars
    - when writing new password the oldest one will be cleared
    - the script keeps max two pair of SSID and password
*/
void connect_wifi () {
  for (int i = 0; i <30; i += 20)
  {
    if (EEPROM_String_read(i).length() > 2 && EEPROM_String_read(i + 10).length() > 2) {

      Serial.print("EEPROM_String_read(i).length(): ");  Serial.println(EEPROM_String_read(i).length());
      Serial.print("EEPROM_String_read(i+10).length(): ");  Serial.println(EEPROM_String_read(i+10).length());
      
      //    Serial.print("try: ");  Serial.println(i);
      char ssid[EEPROM_String_read(i).length() + 1];
      char password[EEPROM_String_read(i + 10).length() + 1] ;
      EEPROM_String_read(i).toCharArray(ssid, EEPROM_String_read(i).length() + 1);
      EEPROM_String_read(i + 10).toCharArray(password, EEPROM_String_read(i + 10).length() + 1);
      Serial.print("ssid: ");  Serial.print(ssid); Serial.print("; password: ");  Serial.println(password);

      int x = 0;
      WiFi.mode(WIFI_STA);
      WiFi.begin(ssid, password);
      while ((WiFi.status() != WL_CONNECTED) && x < 10) { // (выполнять цикл, пока хотя бы одно из условий истинно)
        if (WiFi.status() == WL_CONNECTED) break;
        Serial.println(x);
        x++;
        delay(500);
      }
      if (WiFi.status() == WL_CONNECTED)
      {
        Serial.println(""); Serial.println(F("WiFi connected")); Serial.print(F("IP address: ")); Serial.println(WiFi.localIP());
        break;
      }
    }    
  }
  if (WiFi.status() != WL_CONNECTED) {
    Serial.println("Cant connect to wifi");
    // Connect to Wi-Fi network with SSID and password
    WiFi.mode(WIFI_STA);
    WiFi.disconnect();
    delay(100);
    Networks_count = WiFi.scanNetworks();
    Serial.println("scan done");
    if (Networks_count == 0) {
      Serial.println("no networks found");
    } else {
      Serial.print(Networks_count);
      Serial.println(" networks found");
      if (Networks_count > 20) Networks_count = 20;
      for (int i = 0; i < Networks_count; ++i) {
        // Print SSID and RSSI for each network found
        wifi_ssid[i] = WiFi.SSID(i);
        Serial.print(i + 1);
        Serial.print(": ");
        Serial.print(WiFi.SSID(i));
        Serial.print(" (");
        Serial.print(WiFi.RSSI(i));
        Serial.print(")");
//        Serial.println((WiFi.encryptionType(i) == WIFI_AUTH_OPEN) ? " " : "*");
        delay(10);
      }
    }
    Serial.print("Setting AP (Access Point)…"); // Remove the password parameter, if you want the AP (Access Point) to be open
    WiFi.softAP(ssid, password); //
    IPAddress IP = WiFi.softAPIP();
    Serial.print("AP IP address: ");
    Serial.println(IP);
    Serial.println("Start local Wi-Fi server");
    wifi_server.begin();
    wifi_server_run = 1;
  }
}
void write_wifi_password (String ssid, String pswrd) {
  Serial.print("ssid: ");  Serial.print(ssid);  Serial.print("; password: ");  Serial.println(pswrd);
  EEPROM_String_write(0,  EEPROM_String_read(20));
  EEPROM_String_write(10, EEPROM_String_read(30));
  EEPROM_String_write(20, ssid);
  EEPROM_String_write(30, pswrd);
}

void EEPROM_String_write(char add, String data)
{
  int _size = data.length();
  int i;
  for (i = 0; i < _size; i++)
    EEPROM.write(add + i, data[i]);
  EEPROM.write(add + _size, '\0'); //Add termination null character for String Data
  EEPROM.commit();
}

String EEPROM_String_read(char add)
{
  int i;
  char data[50]; //Max 100 Bytes
  int len = 0;
  unsigned char k;
  k = EEPROM.read(add);
  while (k != '\0' && len < 55) //Read until null character
  {
    k = EEPROM.read(add + len);
    data[len] = k;
    len++;
  }
  data[len] = '\0';
  return String(data);
}

 

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

странно как то...  зачем закомментирована //  server.handleClient(); ? в ESP32, да она не нужна, а тут работать не будет, потом еще и цикл бесконечный - конечно будет зависать.

Посмотретие пример из поставки HTTP сервер, там все просто и прозрачно.

Куски из моего проекта:

       WiFi.disconnect();
        Serial.print("Configuring access point...");
        WiFi.mode(WIFI_AP);
        WiFi.softAP(srvssid, srvpass);
        IPAddress myIP = WiFi.softAPIP();
        Serial.print("AP IP address: ");
        Serial.println(myIP);
        // прописываем какие страницы открывать на разные запросы
        server.on("/", handleRoot);
        server.on("/setup", HTTP_GET, handleSetupGet);
        server.on("/setup", HTTP_POST, handleSetupPost);
        server.onNotFound(handleNotFound);
        server.begin(); // запускаем сервер
        Serial.println("HTTP server started");



       server.handleClient();
        // обрабатываем запрос
        if (server.hasArg("action")) {
          if (((server.arg("action").indexOf("savewifi")) >= 0) && (server.hasArg("ssid")) && (server.hasArg("pass"))) {
            Serial.println("There are new WiFi data");
            // save data to eeprom // записываем введенные данные в eeprom
            byte l = server.arg("ssid").length() + 1;
            server.arg("ssid").toCharArray(eep_str, l); eep_str[l] = 0;
            byte i = 0; while (eep_str[i] > 0) {
              EEPROM.write(eep_pos_wifi_p1 + i, eep_str[i]); ++i;
            } EEPROM.write(eep_pos_wifi_p1 + i, 0);
            l = server.arg("pass").length() + 1;
            server.arg("pass").toCharArray(eep_str, l); eep_str[l] = 0;
            i = 0; while (eep_str[i] > 0) {
              EEPROM.write(eep_pos_wifi_p2 + i, eep_str[i]); ++i;
            } EEPROM.write(eep_pos_wifi_p2 + i, 0);
            EEPROM.commit();
            EEPROM.end();
            EEPROMinit();
            loadDataWiFiEEPROM();
            server.stop();
            WiFi.disconnect();
            ++deviceMode;
          }
        }




void handleNotFound() {
  String message = "File Not Found\n\n";
  message += "URI: ";
  message += server.uri();
  message += "\nMethod: ";
  message += (server.method() == HTTP_GET) ? "GET" : "POST";
  message += "\nArguments: ";
  message += server.args();
  message += "\n";
  for (uint8_t i = 0; i < server.args(); i++) {
    message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
  }
  server.send(404, "text/plain", message);
}

void handleRoot() {
  server.send(200, "text/html", "<h1>You are connected</h1>");
}

void handleSetupGet() {
  String message = "<html lang='ru'>\
              <head>\
              <meta charset='utf - 8'>\
              <title>ESP Server</title>\
              </head>\
              <body>\
    <h1>WiFi Acces Point data</h1>\
  <form action='?' method='post'>\
        <div>\
        <label for='ssid'>WiFi SSID: <input type='text' name='ssid' id='ssid' value='";
  message += ssid;
  message += "'></label>\
        </div>\
        <div>\
        <label for='pass'>WiFi Password: <input type='password' name='pass' id='pass' value='";
  message += password;
  message += "'></label>\
        </div>\
        <p></p>\
        <input type='hidden' name='action' value='savewifi'>\
        <input type='submit' value='Save'>\
        </div>\
  </form>\
        <p></p>\
  <a href='../'>Return to main page</a>\
              </body>\
              </html>";
  server.send(200, "text/html", message);
}

void handleSetupPost() {
  server.send(200, "text/html", "<html lang='ru'>\
              <head>\
              <meta charset='utf - 8'>\
              <title>ESP temperature Server</title>\
              </head>\
              <body>\
    <h1>OK</h1>\
        <p></p>\
  <a href='../'>Return to main page</a>\
              </body>\
              </html>");
}

 

igorlab
Offline
Зарегистрирован: 11.11.2015

- так у меня как раз ESP32, та строка не нужна

- потом еще и цикл бесконечный - конечно будет зависать. - там нет бесконечных циклов... оно не зависает, а перезагружается после записи в память распарсеной строки, до сохранения все отлично работает...

у Вас пример для ESP8266? потому что у меня библиотека #include <WiFi.h> не поддерживает .hasArg ...

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

пример для esp32s

        WiFi.mode(WIFI_AP);
        WiFi.disconnect();
        Serial.print("Configuring access point...");
        WiFi.softAP(srvssid, srvpass);
        IPAddress myIP = WiFi.softAPIP();
        Serial.print("AP IP address: ");
        Serial.println(myIP);
        server.begin(); // запускаем сервер
        header = ""; // очистка строки запроса
 

        WiFiClient client = server.available();   // Listen for incoming clients
        if (client) {                             // If a new client connects,
          Serial.println("New Client.");          // print a message out in the serial port
          String currentLine = "";                // make a String to hold incoming data from the client
          while (client.connected()) {            // loop while the client's connected
            if (client.available()) {             // if there's bytes to read from the client,
              char c = client.read();             // read a byte, then
              Serial.write(c);                    // print it out the serial monitor
              header += c;
              if (c == '\n') {                    // if the byte is a newline character
                // if the current line is blank, you got two newline characters in a row.
                // that's the end of the client HTTP request, so send a response:
                if (currentLine.length() == 0) {
                  // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
                  // and a content-type so the client knows what's coming, then a blank line:
                  client.println("HTTP/1.1 200 OK");
                  client.println("Content-type:text/html");
                  client.println("Connection: close");
                  client.println();
                  if (header.indexOf("GET / HTTP/") >= 0) {
                    handleSetupGet(client);
                  } else if (header.indexOf("POST /? HTTP/") >= 0) {
                    // read data POST
                    while (client.available()) {
                      char c = client.read();             // read a byte, then
                      Serial.write(c);                    // print it out the serial monitor
                      header += c;
                    }
                    // start page
                    handleRoot(client);
                    // processing header
                    int p_act = header.indexOf("&action=savewifi");
                    if (p_act >= 0) {
                      // and find login password WiFi
                      int p_id = header.indexOf("ssid=");
                      int p_pp = header.indexOf("&pass=");
                      int l_id = p_pp - p_id - 5;
                      int l_pp = p_act - p_pp - 6;
                      if ((l_pp > 0) && (l_id > 0)) {
                        // save
                        String str_ppid = header.substring(p_id + 5, p_pp);
                        str_ppid.toCharArray(eep_str, l_id + 1); eep_str[l_id] = 0;
                        byte i = 0; while (eep_str[i] > 0) {
                          EEPROM.write(eep_pos_wifi_p1 + i, eep_str[i]); ++i;
                        } EEPROM.write(eep_pos_wifi_p1 + i, 0);
                        str_ppid = header.substring(p_pp + 6, p_act);
                        str_ppid.toCharArray(eep_str, l_pp + 1); eep_str[l_pp] = 0;
                        i = 0; while (eep_str[i] > 0) {
                          EEPROM.write(eep_pos_wifi_p2 + i, eep_str[i]); ++i;
                        } EEPROM.write(eep_pos_wifi_p2 + i, 0);
                        EEPROM.commit();
                        EEPROM.end();
                        EEPROMinit();
                        loadDataWiFiEEPROM();
                        // stop server and wifi
                        header = ""; // Clear the header variable
                        delay(500);
                        client.stop(); // Close the connection
                        Serial.println("Client disconnected.");
                        server.stop();
                        delay(500);
                        ++deviceMode;
                        break;
                      }
                    }
                  } else {
                    handleRoot(client);
                  }
                  break;
                } else { // if you got a newline, then clear currentLine
                  currentLine = "";
                }
              } else if (c != '\r') {  // if you got anything else but a carriage return character,
                currentLine += c;      // add it to the end of the currentLine
              }
            }
          }
          header = ""; // Clear the header variable
          delay(100);
          client.stop(); // Close the connection
          Serial.println("Client disconnected.");
        }



 

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

сами странички




void handleSetupGet(WiFiClient clwf) {
  String message = "<html lang='ru'>\
              <head>\
              <meta charset='utf - 8'>\
              <title>ESP Server</title>\
              </head>\
              <body>\
    <h1>WiFi Acces Point data</h1>\
  <form action='?' method='post'>\
        <div>\
        <label for='ssid'>WiFi SSID: <input type='text' name='ssid' id='ssid' value='";
  message += ssid;
  message += "'></label>\
        </div>\
        <div>\
        <label for='pass'>WiFi Password: <input type='password' name='pass' id='pass' value='";
  message += password;
  message += "'></label>\
        </div>\
        <p></p>\
        <input type='hidden' name='action' value='savewifi'>\
        <input type='submit' value='Save'>\
        </div>\
  </form>\
        <p></p>\
              </body>\
              </html>";
  clwf.println(message);
}

void handleRoot(WiFiClient clwf) {
  clwf.println("<h1>You are connected</h1>");
}

 

igorlab
Offline
Зарегистрирован: 11.11.2015

всем спасибо! все получилось :)

 andycat, спасибо, добавил еще выпадающее меню с перечнем доступных сетей

#include <EEPROM.h>
#include <WiFi.h>

WiFiServer wifi_server(80);
byte wifi_server_run = 0;
String wifi_ssid[20] = {};
int Networks_count = 0;

#define last_byte_to_eeprom   106
String    webpage;

int eep_pos_wifi_p1 = 0;
int eep_pos_wifi_p2 = 10;
// Variable to store the HTTP request
String header;

// Replace with your network credentials
const char* ssid     = "KH-wifi";
const char* password = "123456789";


void setup() {
  EEPROM.begin(last_byte_to_eeprom);
  Serial.begin(115200);
  connect_wifi();
}

void loop() {
  while (true) {
    String command = Serial.readString(); // read a command
    if (command == "") break; // if no more commands, then exit

    else if (command.startsWith("psw2")) {
      Serial.println("psw2");
      String s = "Guest", p = "88888888";
      write_wifi_password(s, p);
    }
    else if (command.startsWith("psw1")) {
      Serial.println("psw1");
      write_wifi_password("ASUS", "99999999");
    }
  }

  if (wifi_server_run == 1) {
    WiFiClient client = wifi_server.available();   // Listen for incoming clients
    if (client) {                             // If a new client connects,
      Serial.println("New Client.");          // print a message out in the serial port
      String currentLine = "";                // make a String to hold incoming data from the client
      while (client.connected()) {            // loop while the client's connected
        if (client.available()) {             // if there's bytes to read from the client,
          char c = client.read();             // read a byte, then
          Serial.write(c);                    // print it out the serial monitor
          header += c;
          if (c == '\n') {                    // if the byte is a newline character
            // if the current line is blank, you got two newline characters in a row.
            // that's the end of the client HTTP request, so send a response:
            if (currentLine.length() == 0) {
              // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
              // and a content-type so the client knows what's coming, then a blank line:
              client.println("HTTP/1.1 200 OK");
              client.println("Content-type:text/html");
              client.println("Connection: close");
              client.println();
              if (header.indexOf("GET / HTTP/") >= 0) {
                handleSetupGet(client);
              } else if (header.indexOf("POST /? HTTP/") >= 0) {
                // read data POST
                while (client.available()) {
                  char c = client.read();             // read a byte, then
                  Serial.write(c);                    // print it out the serial monitor
                  header += c;
                }
                // start page
                handleRoot(client);
                // processing header
                int p_act = header.indexOf("&action=savewifi");
                if (p_act >= 0) {
                  // and find login password WiFi
                  int p_id = header.indexOf("ssid=");
                  int p_pp = header.indexOf("&pass=");
                  int p_ws = header.indexOf("&action=");
                  String str_ppid   = header.substring(p_id + 5, p_pp);
                  String str_pppass = header.substring(p_pp + 6, p_ws);

                  if ((str_ppid.length() > 0) && (str_pppass.length() > 0)) { // save                   
//                    Serial.println("");Serial.println("----------------------------------------------------------");
//                    Serial.print("str_ppid: ");   Serial.print(str_ppid); Serial.print("; str_pppass: "); Serial.print(str_pppass); Serial.println(";");
//                    Serial.println("----------------------------------------------------------");
                    write_wifi_password(str_ppid, str_pppass);
                    // stop server and wifi
                    header = ""; // Clear the header variable
                    delay(500);
                    client.stop(); // Close the connection
                    Serial.println("Client disconnected.");
                    wifi_server.stop();
                    delay(500);
                    break;
                  }
                }
              } else {
                handleRoot(client);
              }
              break;
            } else { // if you got a newline, then clear currentLine
              currentLine = "";
            }
          } else if (c != '\r') {  // if you got anything else but a carriage return character,
            currentLine += c;      // add it to the end of the currentLine
          }
        }
      }
      header = ""; // Clear the header variable
      delay(100);
      client.stop(); // Close the connection
      Serial.println("Client disconnected.");
    }

  }
}

void handleSetupGet(WiFiClient clwf) {
  String message = "<html lang='ru'>\
              <head>\
              <meta charset='utf - 8'>\
              <title>KH-wifi Server</title>\
              </head>\
              <body>\
    <h1>WiFi Acces Point data</h1>\
  <form action='?' method='post'>\
        <div>\
          <label for='ssid'>WiFi SSID: <select  name='ssid' id='ssid'>";
  if (Networks_count > 0) {
    for (int i = 0; i < Networks_count; ++i) {
      message += "<option value=\"" + WiFi.SSID(i) + "\">" + WiFi.SSID(i) + "</option>";
      delay(10);
    }
  }
  message += "</select></div>\
        <div>\
        <label for='pass'>WiFi Password: <input type='password' name='pass' id='pass' value='"; //<label for='ssid'>WiFi SSID: <input type='text' name='ssid' id='ssid' value='"; message += ssid; message += "'></label>
  message += password;
  message += "'></label>\
        </div>\
        <p></p>\
        <input type='hidden' name='action' value='savewifi'>\
        <input type='submit' value='Save'>\
        </div>\
  </form>\
        <p></p>\
              </body>\
              </html>";
  clwf.println(message);
}

void handleRoot(WiFiClient clwf) {
  clwf.println("<h1>SSID and Password saved</h1><br><br><h1>reload your KH-wifi</h1>");
}
/*
    - Password and SSID couldn't be more than 10 chars
    - when writing new password the oldest one will be cleared
    - the script keeps max two pair of SSID and password
*/
void connect_wifi () {
  for (int i = 0; i < 30; i += 20)
  {
    if (EEPROM_String_read(i).length() > 2 && EEPROM_String_read(i + 10).length() > 2) {
//      Serial.print("EEPROM_String_read(i).length(): ");  Serial.println(EEPROM_String_read(i).length());
//      Serial.print("EEPROM_String_read(i+10).length(): ");  Serial.println(EEPROM_String_read(i + 10).length());
      char ssid[EEPROM_String_read(i).length() + 1];
      char password[EEPROM_String_read(i + 10).length() + 1] ;
      EEPROM_String_read(i).toCharArray(ssid, EEPROM_String_read(i).length() + 1);
      EEPROM_String_read(i + 10).toCharArray(password, EEPROM_String_read(i + 10).length() + 1);
      Serial.print("ssid: ");  Serial.print(ssid); Serial.print("; password: ");  Serial.println(password);

      int x = 0;
      WiFi.mode(WIFI_STA);
      WiFi.begin(ssid, password);
      while ((WiFi.status() != WL_CONNECTED) && x < 10) { // (выполнять цикл, пока хотя бы одно из условий истинно)
        if (WiFi.status() == WL_CONNECTED) break;
        Serial.println(x);
        x++;
        delay(500);
      }
      if ( WiFi.status() == WL_CONNECTED )
      {
        Serial.println(""); Serial.println(F("WiFi connected")); Serial.print(F("IP address: ")); Serial.println(WiFi.localIP());
        break;
      }
    }
  }
  if (WiFi.status() != WL_CONNECTED) {
    Serial.println("Cant connect to wifi");
    // Connect to Wi-Fi network with SSID and password
    WiFi.mode(WIFI_STA);
    WiFi.disconnect();
    delay(100);
    Networks_count = WiFi.scanNetworks();
    Serial.println("scan done");
    if (Networks_count == 0) {
      Serial.println("no networks found");
    } else {
      Serial.print(Networks_count);
      Serial.println(" networks found");
      if (Networks_count > 20) Networks_count = 20;
      for (int i = 0; i < Networks_count; ++i) {
        // Print SSID and RSSI for each network found
        wifi_ssid[i] = WiFi.SSID(i);
        Serial.print(i + 1);
        Serial.print(": ");
        Serial.print(WiFi.SSID(i));
        Serial.print(" (");
        Serial.print(WiFi.RSSI(i));
        Serial.print(")");
        //        Serial.println((WiFi.encryptionType(i) == WIFI_AUTH_OPEN) ? " " : "*");
        delay(10);
      }
    }
    WiFi.mode(WIFI_AP);
    WiFi.disconnect();
    Serial.print("Configuring access point...");
    WiFi.softAP(ssid, password);
    
    IPAddress myIP = WiFi.softAPIP();
    Serial.print("AP IP address: ");
    Serial.println(myIP);
    
    header = ""; // очистка строки запроса
    wifi_server.begin(); // запускаем сервер
    wifi_server_run = 1;
  }
}
void write_wifi_password (String ssid, String pswrd) {
  Serial.print("ssid: ");  Serial.print(ssid);  Serial.print("; password: ");  Serial.println(pswrd);
  EEPROM_String_write(20,  EEPROM_String_read(0));
  EEPROM_String_write(30, EEPROM_String_read(10));
  EEPROM_String_write(0, ssid);
  EEPROM_String_write(10, pswrd);
}

void EEPROM_String_write(char add, String data)
{
  int _size = data.length();
  int i;
  for (i = 0; i < _size; i++)
    EEPROM.write(add + i, data[i]);
  EEPROM.write(add + _size, '\0'); //Add termination null character for String Data
  EEPROM.commit();
}

String EEPROM_String_read(char add)
{
  int i;
  char data[50]; //Max 100 Bytes
  int len = 0;
  unsigned char k;
  k = EEPROM.read(add);
  while (k != '\0' && len < 10) //Read until null character
  {
    k = EEPROM.read(add + len);
    data[len] = k;
    len++;
  }
  data[len] = '\0';
  return String(data);
}

 

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

igorlab пишет:

 добавил еще выпадающее меню с перечнем доступных сетей

вот просто из любопытства: в наше время с почти халявным и качественным 4G интернетом еще кому то нужны незапароленные WiFi сети?

FoxJone
Offline
Зарегистрирован: 19.04.2019

andycat пишет:

вот просто из любопытства: в наше время с почти халявным и качественным 4G интернетом еще кому то нужны незапароленные WiFi сети?

А как же. Надзорным органам очень нужны!

За предоставление анонимного доступа в интернет с любого юрика можно очень красиво штрафов сорвать.

Именно поэтому все общественные вайфаи требуют авторизацию через телефон. Либо пароль предоставляется конкретному лицу (к примеру, жильцу в гостинице).

sqafaroff
Offline
Зарегистрирован: 10.01.2021

Вы использовали ESP32? Все работает? Я просто ищу нечто похожее для своего проекта. Есть ли баги при использовании?

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

sqafaroff пишет:
Вы использовали ESP32? Все работает? Я просто ищу нечто похожее для своего проекта. Есть ли баги при использовании?

если длина ssid и пароля более 10 символов видимо багам быть

sqafaroff
Offline
Зарегистрирован: 10.01.2021

Да, так у меня и получилось. Придется писать свой код. А если заказать, то почем выйдет?

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

sqafaroff пишет:
Да, так у меня и получилось. Придется писать свой код. А если заказать, то почем выйдет?

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

sqafaroff
Offline
Зарегистрирован: 10.01.2021

Ну так дело в том что вначале должна точка доступа с предустановленным именем и паролем. А после человек должен сам выбрать свою сеть и подключиться к ней. Ограничение по длине имени и паролю - осуждаю )))

sqafaroff
Offline
Зарегистрирован: 10.01.2021

ua6em пишет:

sqafaroff пишет:
Вы использовали ESP32? Все работает? Я просто ищу нечто похожее для своего проекта. Есть ли баги при использовании?

если длина ssid и пароля более 10 символов видимо багам быть

Не подскажете, где в этом коде я могу исправить сие недоразумение?

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

Помоему стандартные ограничения на длину имени точки доступа и пароля 128 символов. Сканинг сетей на тему имен точек доступа с ESP32 на стандартных ардуиновских библиотеках работает через раз. Нужно спускаться на более низкий уровень. На первый взгляд простое задание, по факту окажется больше того кода который вы уже имеете :) Раза в три :)))

sqafaroff пишет:

Не подскажете, где в этом коде я могу исправить сие недоразумение?

Серьезно ?! Начните с 6 строки :)

sqafaroff
Offline
Зарегистрирован: 10.01.2021

Ну а отчего же не серьезно? )) Был бы профи, то стал бы я сидеть на форуме? Я только начинаю, и для меня пока что все в диковинку.

sadman41
Offline
Зарегистрирован: 19.10.2016

У Arduino-EPS-шек всё немного покороче, чем 128 chars

ESP32 core:

    if(!ssid || *ssid == 0x00 || strlen(ssid) > 31) {
        log_e("SSID too long or missing!");
        return WL_CONNECT_FAILED;
    }

    if(passphrase && strlen(passphrase) > 64) {
        log_e("passphrase too long!");
        return WL_CONNECT_FAILED;
    }

ESP8266 Core:

    if(!ssid || *ssid == 0x00 || strlen(ssid) > 32) {
        // fail SSID too long or missing!
        return WL_CONNECT_FAILED;
    }

    int passphraseLen = passphrase == nullptr ? 0 : strlen(passphrase);
    if(passphraseLen > 64) {
        // fail passphrase too long!
        return WL_CONNECT_FAILED;
    }

 

sqafaroff
Offline
Зарегистрирован: 10.01.2021

Ребят, помогите запустить код, пожалуйста. Ну хотя бы сделать возможность ввода пароля длиной 20-30 символов.

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

Я этими костылями не пользуюсь :) Если уж делать то по "ГОСТУ" :)

sqafaroff
Offline
Зарегистрирован: 10.01.2021

Ого, по ГОСТу это как?

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

Это я так стандарты назвал.

На самом деле ошибся я. Садман прав, респект. Длинна SSID максимум 32 символа, длинна пароля до 64 символов.

sqafaroff
Offline
Зарегистрирован: 10.01.2021

brokly пишет:

Это я так стандарты назвал.

На самом деле ошибся я. Садман прав, респект. Длинна SSID максимум 32 символа, длинна пароля до 64 символов.

Тогда тем более интересно, почему ТС счел целесообразным остановиться именно на такой длине пароля?

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

От балды, память пожалел. Не всем приходит в голову посмотреть стандарты. Но в шестой строке , на самом деле описана переменная которая сохраняет всего 20 имен сетей, причем их длина не ограничена.

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

потому, что 9 символов в пароле, это минимум, когда включается шифрование, иначе точка открыта

sqafaroff
Offline
Зарегистрирован: 10.01.2021

brokly пишет:

От балды, память пожалел. Не всем приходит в голову посмотреть стандарты. Но в шестой строке , на самом деле описана переменная которая сохраняет всего 20 имен сетей, причем их длина не ограничена.

Стало еще непонятней и одновременно непонятно. Значит длина имен сетей практически неограничена, на кой хрен нужно 20 имен сетей, хотя за глаза хватило бы и 6-7 по убыванию мощности. А вот на пароль длины пожалел (( крыса ...

sqafaroff
Offline
Зарегистрирован: 10.01.2021

ua6em пишет:

потому, что 9 символов в пароле, это минимум, когда включается шифрование, иначе точка открыта

Запомнил )) Спасибо.

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

Ну почему же, у меня бывает что требуемая сеть находится где нибудь на 30м месте. Кроме того этот код не ранжирует сети по RSSI.Так что для того что бы вывести на экран десяток самых "громких" нужно отсортировать весь список.

Я не знаю какие косяки вылезают в этом коде, но самое главное не забывать, что из-за того, что ESP имеют единый радиоканал для точки доступа и клиента, на время сканирования эфира на тему других точек доступа, она сама перестает быть точкой доступа, а это влечет отсоединение остальных клиентов от сети. 

Поэтому вы хотите иметь список доступных сетей на страничке сформированной ESPшкой как http-сервером  и одновременно точкой доступа. То есть вы должны так написать веб интерфейс и организовать сканирование, что бы клиенты вашей ESP как точки доступа не сваливали во время отключения.

sqafaroff
Offline
Зарегистрирован: 10.01.2021

brokly пишет:

Ну почему же, у меня бывает что требуемая сеть находится где нибудь на 30м месте. Кроме того этот код не ранжирует сети по RSSI.Так что для того что бы вывести на экран десяток самых "громких" нужно отсортировать весь список.

Я не знаю какие косяки вылезают в этом коде, но самое главное не забывать, что из-за того, что ESP имеют единый радиоканал для точки доступа и клиента, на время сканирования эфира на тему других точек доступа, она сама перестает быть точкой доступа, а это влечет отсоединение остальных клиентов от сети. 

Поэтому вы хотите иметь список доступных сетей на страничке сформированной ESPшкой как http-сервером  и одновременно точкой доступа. То есть вы должны так написать веб интерфейс и организовать сканирование, что бы клиенты вашей ESP как точки доступа не сваливали во время отключения.


Умно, нужно поглядеть пример из Factory test там есть скан сетей, и помоему они ранжируются. Попозже выложу этот скетч.

Rumata
Offline
Зарегистрирован: 29.03.2019

Хорошая тема. Подпишусь. В этом году планирую вшить подобный функционал в свой зоопарк устройств. Пока работает только быстрое переключение сценариев: работа - дом/дача - мобильный. К неизвестным сетям не умеют подключаться

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

brokly пишет:

Ну почему же, у меня бывает что требуемая сеть находится где нибудь на 30м месте. Кроме того этот код не ранжирует сети по RSSI.Так что для того что бы вывести на экран десяток самых "громких" нужно отсортировать весь список.

Я не знаю какие косяки вылезают в этом коде, но самое главное не забывать, что из-за того, что ESP имеют единый радиоканал для точки доступа и клиента, на время сканирования эфира на тему других точек доступа, она сама перестает быть точкой доступа, а это влечет отсоединение остальных клиентов от сети. 

Поэтому вы хотите иметь список доступных сетей на страничке сформированной ESPшкой как http-сервером  и одновременно точкой доступа. То есть вы должны так написать веб интерфейс и организовать сканирование, что бы клиенты вашей ESP как точки доступа не сваливали во время отключения.

надо посмотреть, если проверяю подключенных клиентов к первичной AP, то таки да, а сканирование точек безобрывное вроде )))

sqafaroff
Offline
Зарегистрирован: 10.01.2021

Хочу поделиться опытом. Полчаса назад нашел библиотеку tzapu/WiFiManager  https://github.com/tzapu/WiFiManager.git но обязательно билд Developer. С ее помощью помощью можно к примеру создать точку доступа при подключении к которой можно выбрать из списка сетей искомую и введя ее пароль подключиться к ней. При этом точка доступа отключается (по крайней мере ее не видно в телефоне) и при необходимости нажав на кнопку на модуле инициировать ее вновь чтобы выбрать другую вай фай сеть. Код короткий, работает стабильно )) Замучал я его уже ... 

 

/**
 * OnDemandConfigPortal.ino
 * example of running the configPortal AP manually, independantly from the captiveportal
 * trigger pin will start a configPortal AP for 120 seconds then turn it off.
 * 
 */
#include <WiFiManager.h> // https://github.com/tzapu/WiFiManager

// select which pin will trigger the configuration portal when set to LOW
#define TRIGGER_PIN 35

int timeout = 120; // seconds to run for

void setup() {
  WiFi.mode(WIFI_STA); // explicitly set mode, esp defaults to STA+AP  
  // put your setup code here, to run once:
  Serial.begin(115200);
  Serial.println("\n Starting");
  pinMode(TRIGGER_PIN, INPUT_PULLUP);
}

void loop() {
  // is configuration portal requested?
  if ( digitalRead(TRIGGER_PIN) == LOW) {
    WiFiManager wm;    

    //reset settings - for testing
    //wifiManager.resetSettings();
  
    // set configportal timeout
    wm.setConfigPortalTimeout(timeout);

    if (!wm.startConfigPortal("OnDemandAP")) {
      Serial.println("failed to connect and hit timeout");
      delay(3000);
      //reset and try again, or maybe put it to deep sleep
      ESP.restart();
      delay(5000);
    }

    //if you get here you have connected to the WiFi
    Serial.println("connected...yeey :)");

  }

  // put your main code here, to run repeatedly:
}

 

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

Какой же он короткий !? Вы в файл wifimanager.cpp заглядывали ? Там всего ТРИ ТЫСЯЧИ строк кода.

sqafaroff
Offline
Зарегистрирован: 10.01.2021

brokly пишет:

Какой же он короткий !? Вы в файл wifimanager.cpp заглядывали ? Там всего ТРИ ТЫСЯЧИ строк кода.

Это я про тот что в скетче ))

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

С таким подходом могу написать код из двух строк и восьми букв.