ESP8266 EEPROM или FLASH Ошибка: Успешное подключение к Wi-Fi с ложными учетными данными - PullRequest
0 голосов
/ 31 мая 2018

Я строю маленький датчик на основе ESP8266.Для настройки Wi-Fi я размещаю небольшой веб-сервер, где пользователь может ввести учетные данные.

В процедуре установки я загружаю учетные данные и пытаюсь подключиться к Wi-Fi.Если соединение не удается, esp создает точку доступа, и пользователь может ввести новые учетные данные.

У меня странное поведение.Потому что, когда я удаляю учетные данные, ESP тем не менее успешно подключается к Wi-Fi.Но 'serial.print ()' не показывает никаких учетных данных.

Возможно, это проблема с EEPROM или FLASH, я понятия не имею.Я мог бы воспроизвести это поведение на нескольких ESP.

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <EEPROM.h>

ESP8266WebServer server(80);

const char *soft_ap_ssid = "Connect Sensor to MCU";
const char *soft_ap_password = "MySensor";

char ssid[32] = "";
char password[32] = "";

bool wifi_status;

void setup()
{
    Serial.begin(115200);
    Serial.println();
    delay(10);

    load_credentials();
    wifi_status = setup_wifi(5);

    if (!wifi_status)
    {
        setup_soft_ap();
        setup_server();
    }
}

void loop()
{
    if (!wifi_status)
    {
        server.handleClient();
    }
    else
    {
        Serial.println("Doing Sensor stuff");
        delay(2000);
        // Remove exsting credentials
        for( int i = 0; i < sizeof(ssid);  i++ ){
            ssid[i] = (char)0;
            password[i] = (char)0;
        }
        save_credentials();
    }
}

/*
############## Gernerische Code ########### TODO LIB
*/
bool setup_wifi(int timeout)
{
    int timeout_ctr = 0;
    Serial.print("Connecting to ");
    Serial.println(ssid);

    WiFi.begin(ssid, password); //Connect to the WiFi network

    while ((WiFi.status() != WL_CONNECTED) && (timeout_ctr < timeout))
    {
        delay(500);
        Serial.println("...");
        timeout_ctr++;
    }

    if (WiFi.status())
    {
        Serial.print("IP address: ");
        Serial.println(WiFi.localIP()); //Print the local IP
    }
    else
    {
        Serial.println("Connection to MCU failed, setting up AP.");
    }

    return (WiFi.status() == WL_CONNECTED);
}

void setup_soft_ap()
{
    Serial.println();
    Serial.println("Creating WiFi AP...");

    WiFi.softAP(soft_ap_ssid, soft_ap_password);
    Serial.print("AP \"");
    Serial.print(soft_ap_ssid);
    Serial.println("\" is online.");
    Serial.print("IP address: ");
    Serial.println(WiFi.softAPIP());
    Serial.println();
}

void setup_server()
{
    server.on("/", handle_root);         //Associate the landingpage function to the path
    server.on("/submit", handle_submit); //Associate the handler function to the path
    server.begin();                     //Start the server
    Serial.println("Server listening");
}

void handle_root()
{
    const char *landingpage = "<html><head> <title>ESP8266 Demo</title> <style></style></head><body> <h1>Sensor einrichten</h1> <p> Eingabe der Wifi Daten </p><form action='/submit' method='post'> <input type='text' name='ssid' placeholder='Wifi SSID'> <input type='text' name='pw' placeholder='Wifi Password'> <input type='submit' value='Submit'> </form></body></html>";
    server.send(200, "text/html", landingpage);
}

void handle_submit()
{
    if (server.args() > 0)
    {
        Serial.println("POST:");
        Serial.println(server.arg("ssid"));
        Serial.println(server.arg("pw"));

        server.arg("ssid").toCharArray(ssid, sizeof(ssid) - 1);
        server.arg("pw").toCharArray(password, sizeof(password) - 1);

        Serial.println("credentials:");
        Serial.println(ssid);
        Serial.println(password);
        save_credentials();
    }
    server.sendHeader("Location", String("/"), true);
    server.send(302, "text/plain", "");
}

void load_credentials()
{
    EEPROM.begin(512);
    EEPROM.get(0, ssid);
    EEPROM.get(0 + sizeof(ssid), password);
    char ok[2 + 1];
    EEPROM.get(0 + sizeof(ssid) + sizeof(password), ok);
    EEPROM.end();
    if (String(ok) != String("OK"))
    {
        ssid[0] = 0;
        password[0] = 0;
    }
    Serial.println("Recovered credentials:");
    Serial.println(ssid);
    Serial.println(password);
}

/** Store WLAN credentials to EEPROM */
void save_credentials()
{
    EEPROM.begin(512);
    EEPROM.put(0, ssid);
    EEPROM.put(0 + sizeof(ssid), password);
    char ok[2 + 1] = "OK";
    EEPROM.put(0 + sizeof(ssid) + sizeof(password), ok);
    EEPROM.commit();
    EEPROM.end();
}

1 Ответ

0 голосов
/ 31 мая 2018

По умолчанию ESP8266 Arduino SDK сохраняет свою конфигурацию Wi-Fi во флэш-памяти.

Это задокументировано , но не вызвано явно.

Вам потребуетсяпозвоните Wifi.persistent(), чтобы ESP не сохранил учетные данные.Похоже, что это не очень четко отражено во многих записях ESP Arduino Core, которые я видел.

Попробуйте:

Serial.print("Connecting to ");
Serial.println(ssid);

WiFi.persistent(false);
WiFi.begin(ssid, password); //Connect to the WiFi network

while ((WiFi.status() != WL_CONNECTED) && (timeout_ctr < timeout))

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

Здесь есть некоторая документация по WiFi.persistent() - представляется неправильным - я полагаю, что этот вызов работает так, как я описал (передача false просто не сохраняет учетные данные).

Если ваш проект будет часто перезапускаться (например, входить ви часто из глубокого сна) Я бы определенно использовал WiFi.persistent(false), чтобы избежать износа вспышки.

...