问题描述
我正在尝试将一个额外的自定义参数保存到 wifimanager,这是 mqtt 服务器地址,但库中和互联网上的所有代码都适用于 Arduinojson 5,我尝试尽我所能升级到 Arduinojson 6。代码运行没有问题,但是,当我重新启动 esp 时,它消失了。由于某种原因,它没有保存。
#include <FS.h> //this needs to be first,or it all crashes and burns...
#include <ESP8266WiFi.h> //https://github.com/esp8266/Arduino
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h> //https://github.com/tzapu/WiFiManager
#include <ArduinoJson.h> //https://github.com/bblanchon/ArduinoJson
#define TRIGGER_PIN 16
char mqtt_server[40];
bool shouldSaveConfig = false;
void saveConfigCallback () { Serial.println("Should save config"); shouldSaveConfig = true; }
WiFiManager wifiManager;
WiFiManagerParameter custom_mqtt_server("server","mqtt server",mqtt_server,40);
void setup() {
Serial.begin(115200);
Serial.println("\n Starting");
pinMode(TRIGGER_PIN,INPUT);
//clean FS,for testing
//SPIFFS.format();
if (SPIFFS.begin()) {
Serial.println("** Mounting file system **");
if (SPIFFS.exists("/config.json")) {
//file exists,reading and loading
Serial.println("** Reading config file **");
File configFile = SPIFFS.open("/config.json","r");
if (configFile) {
size_t size = configFile.size();
// Allocate a buffer to store contents of the file.
std::unique_ptr<char[]> buf(new char[size]);
configFile.readBytes(buf.get(),size);
DynamicJsonDocument doc(1024);
DeserializationError error = deserializeJson(doc,buf.get());
// Test if parsing succeeds.
if (error) {
Serial.print(F("deserializeJson() Failed: "));
Serial.println(error.c_str());
return;
}
strcpy(mqtt_server,doc["mqtt_server"]); //get the mqtt_server <== you need one of these for each param
} else {
Serial.println("** Failed to load json config **");
}
configFile.close();
Serial.println("** Closed file **");
}
}
else {
Serial.println("** Failed to mount FS **");
}
wifiManager.setSaveConfigCallback(saveConfigCallback);
wifiManager.addParameter(&custom_mqtt_server);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
resetbtn();
}
Serial.println("connected...yeey :)");
//read updated parameters
strcpy(mqtt_server,custom_mqtt_server.getValue());
//save the custom parameters to FS
if (shouldSaveConfig) {
Serial.println("saving config");
DynamicJsonDocument doc(1024);
doc["mqtt_server"] = mqtt_server;
File configFile = SPIFFS.open("/config.json","w");
if (!configFile) {
Serial.println("Failed to open config file for writing");
}
serializeJson(doc,Serial);
serializeJson(doc,configFile);
configFile.close();
//end save
}
}
void loop() {
resetbtn();
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
resetbtn();
}
Serial.println("Connected");
wifiManager.process();
saveParamsCallback();
delay(3000);
}
void resetbtn() { if ( digitalRead(TRIGGER_PIN) == HIGH ) { wifiManager.startConfigPortal("Horray"); Serial.println("connected...yeey :)"); } }
void saveParamsCallback () {
Serial.println("Get Params:");
Serial.print(custom_mqtt_server.getID());
Serial.print(" : ");
Serial.println(custom_mqtt_server.getValue());
}
解决方法
出于同样的目的而不是使用:serializeJson(doc,configFile); 我正在使用这个功能,对我来说效果很好
// for writing
bool writeFile(const char * path,const char * message,unsigned int len){
File file = SPIFFS.open(path,FILE_WRITE);
if(!file){
return false;
}
if(!file.write((const uint8_t *)message,len)){
return false;
}
return true;
}
为了阅读,我正在使用这个功能
// for reading
int readFile(const char * path,char ** text){
// retval int - number of characters in the file
// in case of empty file 0
// in case of directory or not found -1
File file = SPIFFS.open(path);
if(!file || file.isDirectory()){
return -1;
}
int file_lenght = file.size();
*text = (char*) malloc(file_lenght*sizeof(char));
for(int i = 0; i < file_lenght; i++){
(*text)[i] = file.read();
}
return file_lenght;
}
你可以这样使用这个函数:
#define WIFI_credential_filename "/config.json"
char * wifi_credentials;
int file_len = readFile(WIFI_credential_filename,&wifi_credentials);
// at this point "wifi_credentials" is filled with the content of
"/config.json" file
这是我的实现,当然可以改进,但我已经测试过它并且有效