WiFi.begin не работает с выводом const char* ArduinoJson

esp32 json

Я использую ArduinoJson для анализа файла, полного строк JSON, содержащих SSID и пароль для зарегистрированных сетей. У меня есть небольшой веб-интерфейс, который работает в режиме программной точки доступа, поэтому вы можете сканировать сети и добавлять их в файл. Добавление сетей в файл работает нормально, но их чтение и использование в качестве входных данных для WiFi.begin не работает. Он переходит к коду состояния 1, что означает, что ему не удалось найти сеть с таким SSID.

Я сравнил значение результата const char* ssid = network[network]["ssid"]; с const char* _ssid = "MySSID"; с помощью strcmp, и он возвращает 0, поэтому я не могу понять, почему он не работает. Это работает, если я заменяю networks[network]["ssid] своим SSID (хотя мне также нужно заменить пароль строковым литералом, иначе он останется с кодом состояния 6, отключен).

Я не могу понять, что там с ArduinoJson, но кажется, что результат захвата строки не возвращает строку, которая правильно отформатирована для WiFi.begin, но удовлетворяет strcmp?

ОБНОВЛЕНО: Я немного изменил код, чтобы заставить его работать. Я больше не передаю объект ArduinoJson, теперь я передаю структуру с данными, и она все еще не работает. Является ли это работой каких-то продвинутых констант/указателей С++, которые я, кажется, не понимаю?

main.cpp:

#include <ArduinoJson.h>
#include <ESPAsyncWebServer.h>
#include <ESPmDNS.h>
#include <SPIFFS.h>
#include <vector>
#include <elapsedMillis.h>

#include "config.h"
#include "restserver.h"
#include "scanwifiserver.h"

AsyncWebServer *Server = new AsyncWebServer(80);

ScanWifiServer *scanWifi;
RestServer *restServer;

struct Network {
    const char* ssid;
    const char* password;
};

std::vector<Network> readAP(fs::FS &fs) {
    //fs.remove("/ap.txt");
    File file = fs.open("/ap.txt");
    std::vector<Network> networks;
    if (!file) {
#ifdef DEBUG
        Serial.println("Failed to open file for reading");
#endif
        return networks;
    }

    while (file.available()) {
        DynamicJsonDocument n(JSON_CAPACITY);
        auto s = file.readStringUntil('\n');
        deserializeJson(n, s);
        struct Network network = {n["ssid"], n["password"]};
        networks.push_back(network);
        Serial.println(networks.back().ssid);
    }

    file.close();
    return networks;
}

void setup() {
#ifdef DEBUG
    Serial.begin(BAUDRATE);
    delay(2000);
#endif

    SPIFFS.begin();
    auto networks = readAP(SPIFFS);
    if (networks.size() > 0) {
        Serial.println("Networks:");
        int network = 0;
        Serial.println(networks.size());
        while (WiFi.status() != WL_CONNECTED && network < networks.size()) {
            const char* ssid = networks[network].ssid;
            const char* password = networks[network].password;
            Serial.printf("%s, %s\n", ssid, password);

            WiFi.begin(ssid, password);

            while (WiFi.status() != WL_CONNECTED) {
                if (WiFi.status() == WL_CONNECT_FAILED || WiFi.status() == WL_NO_SSID_AVAIL)
                    break;
                delay(500);
                Serial.print(WiFi.status());
            }
            Serial.println("");
            network++;
        }   
        if (WiFi.status() == WL_CONNECTED) Serial.println("Connected");
        else networks.clear();
    }
    if (networks.size() == 0) {
        Serial.println("Starting ScanWifiServer");
        WiFi.mode(WIFI_AP);

        scanWifi = new ScanWifiServer(Server);

        Server->begin();

        MDNS.begin("grow");
        MDNS.addService("http", "tcp", 80);
    }
}

void loop() {}

, 👍1

Обсуждение

добавить WiFi.persistent(false); и WiFi.setAutoConnect(false), @Juraj


2 ответа


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

1

Я сам нашел решение. Я переключился с использования struct Network network = {n["ssid"], n["password"]}; для объявления указателей struct и const char на использование массивов char и strcpy

struct Network network;
strcpy(network.ssid, n["ssid"]);
strcpy(network.password, n["password"]);

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

,

-1

std::vector<JsonDocument> хранит не копию всего документа, а только копию внутренних указателей JsonDocument. Таким образом, когда вы используете это значение, оно указывает на недопустимое местоположение.

Это явно ошибка, поэтому я удалил конструктор копирования JsonDocument, но изменение еще не опубликовано.

Вы можете исправить свою программу, заменив std::vector<JsonDocument> на std::vector<DynamicJsonDocument>.

,

Спасибо за ответ, хотя я немного изменил свой код, и он все еще не работает. Вы знаете, что происходит?, @CurieOS