ESP8266 SPIFFS не сохраняется правильно?
Привет всем, у меня возникли проблемы с SPIFFS для этого мини-контроллера ESP8266 Wemos D1.
Это мой скетч Arduino:
#include <FS.h>
#include <ArduinoJson.h>
struct RGBLA {
uint8_t R;
uint8_t G;
uint8_t B;
uint8_t L;
uint8_t A;
};
void setup() {
if (!SPIFFS.begin()) {
Serial.println("error while mounting filesystem!");
} else {
// поместите сюда свой код установки для однократного запуска:
RGBLA returnedVars = readSPIFFS();
Serial.begin(115200);
Serial.println();
Serial.println("Starting...");
Serial.println("readSPIFFS 1");
Serial.print("R: ");
Serial.println(returnedVars.R);
Serial.print("G: ");
Serial.println(returnedVars.G);
Serial.print("B: ");
Serial.println(returnedVars.B);
Serial.print("L: ");
Serial.println(returnedVars.L);
Serial.print("AmbientLight: ");
Serial.println(returnedVars.A);
Serial.println("==================================");
returnedVars = saveToSPIFFS(25,77, 107, 250, 155, false);
Serial.println("saveToSPIFFS #1");
Serial.print("R: ");
Serial.println(returnedVars.R);
Serial.print("G: ");
Serial.println(returnedVars.G);
Serial.print("B: ");
Serial.println(returnedVars.B);
Serial.print("L: ");
Serial.println(returnedVars.L);
Serial.print("AmbientLight: ");
Serial.println(returnedVars.A);
Serial.println("==================================");
returnedVars = saveToSPIFFS(205,17, 68, 50, 15, true);
Serial.println("saveToSPIFFS #2");
Serial.print("R: ");
Serial.println(returnedVars.R);
Serial.print("G: ");
Serial.println(returnedVars.G);
Serial.print("B: ");
Serial.println(returnedVars.B);
Serial.print("L: ");
Serial.println(returnedVars.L);
Serial.print("AmbientLight: ");
Serial.println(returnedVars.A);
returnedVars = readSPIFFS();
Serial.println("readSPIFFS 2");
Serial.print("R: ");
Serial.println(returnedVars.R);
Serial.print("G: ");
Serial.println(returnedVars.G);
Serial.print("B: ");
Serial.println(returnedVars.B);
Serial.print("L: ");
Serial.println(returnedVars.L);
Serial.print("AmbientLight: ");
Serial.println(returnedVars.A);
Serial.println();
Serial.println("END!");
}
}
void loop() {
// поместите сюда свой основной код для повторного запуска:
}
RGBLA saveToSPIFFS(uint8_t R, uint8_t G, uint8_t B, uint8_t L, uint8_t A, bool saveA) {
File configFile = SPIFFS.open("/config.json", "w+");
if (configFile.size() > 3072) {
Serial.println("Config file size is too large.");
} else {
Serial.print("Writing json to Config file...");
StaticJsonBuffer<200> jsonBuffer;
JsonObject& json = jsonBuffer.createObject();
//Получаем старое значение и сохраняем его
RGBLA returnedVars = readSPIFFS();
Serial.println("Old Values?");
Serial.print("R: ");
Serial.println(returnedVars.R);
Serial.print("G: ");
Serial.println(returnedVars.G);
Serial.print("B: ");
Serial.println(returnedVars.B);
Serial.print("L: ");
Serial.println(returnedVars.L);
Serial.print("AmbientLight: ");
Serial.println(returnedVars.A);
if (saveA) {
//Сохраняем данные рассеянного света
json["R"] = returnedVars.R;
json["G"] = returnedVars.G;
json["B"] = returnedVars.B;
json["L"] = returnedVars.L;
json["A"] = A;
//Теперь сохраняем новые данные
returnedVars.A = A;
} else {
//Сохраняем данные RGBL
json["R"] = R;
json["G"] = G;
json["B"] = B;
json["L"] = L;
json["A"] = returnedVars.A;
//Теперь сохраняем новые данные
returnedVars.R = R;
returnedVars.G = G;
returnedVars.B = B;
returnedVars.L = L;
}
json.printTo(configFile);
configFile.close();
//Читаем новые сохраненные значения в структуру
//returnedVars = readSPIFFS();
return returnedVars;
}
}
RGBLA readSPIFFS() {
bool exist = SPIFFS.exists("/config.json");
if (exist) {
Serial.println("YAY!");
} else {
Serial.println("Boo!");
}
File configFile = SPIFFS.open("/config.json", "r");
std::unique_ptr<char[]> buf(new char[configFile.size()]);
configFile.readBytes(buf.get(), configFile.size());
DynamicJsonBuffer jsonBuffer;
JsonObject& json = jsonBuffer.parseObject(buf.get());
RGBLA returnedVars;
String debugLogData;
json.printTo(debugLogData);
Serial.println("===============");
Serial.println(debugLogData);
Serial.println("===============");
returnedVars.R = json["R"];
returnedVars.G = json["G"];
returnedVars.B = json["B"];
returnedVars.L = json["L"];
returnedVars.A = json["A"];
configFile.close();
return returnedVars;
}
А это вывод консоли:
Starting...
readSPIFFS 1
R: 0
G: 0
B: 0
L: 0
AmbientLight: 25
==================================
Writing json to Config file...YAY!
===============
{}
===============
Old Values?
R: 0
G: 0
B: 0
L: 0
AmbientLight: 0
saveToSPIFFS #1
R: 25
G: 77
B: 107
L: 250
AmbientLight: 0
==================================
Writing json to Config file...YAY!
===============
{}
===============
Old Values?
R: 0
G: 0
B: 0
L: 0
AmbientLight: 0
saveToSPIFFS #2
R: 0
G: 0
B: 0
L: 0
AmbientLight: 25
YAY!
===============
{"R":0,"G":0,"B":0,"L":0,"A":25}
===============
readSPIFFS 2
R: 0
G: 0
B: 0
L: 0
AmbientLight: 25
END!
Как видите, первые старые значения содержат все 0, что неверно. В этот момент AmbientLight должно быть 25, поскольку readSPIFFS 1 имеет 25. Итак, это должно читаться так:
Old Values?
R: 0
G: 0
B: 0
L: 0
AmbientLight: 25
saveToSPIFFS #1 отправляет значения 25, 77, 107, 250, 155 и false, которые затем корректно выводятся как:
R: 25
G: 77
B: 107
L: 250
AmbientLight: 0
Но на этот раз AmbientLight все равно должно быть 25, поскольку было отправлено false. Он должен был взять старое значение (25) и поместить его в новое сохранение.
R: 25
G: 77
B: 107
L: 250
AmbientLight: 25
При переходе к saveToSPIFFS #2 значения снова неверны. Однако AmbientLight здесь правильный. Вместо этого вывода:
R: 0
G: 0
B: 0
L: 0
AmbientLight: 25
он должен собрать 4 предыдущих старых значений:
R: 25
G: 77
B: 107
L: 250
AmbientLight: 25
Json после этого не должен быть таким:
{"R":0,"G":0,"B":0,"L":0,"A":25}
Это должно быть так:
{"R":250,"G":77,"B":107,"L":250,"A":25}
И, наконец, вывод readSPIFFS 2:
R: 0
G: 0
B: 0
L: 0
AmbientLight: 25
Неверно. Должно быть выведено:
R: 25
G: 77
B: 107
L: 250
AmbientLight: 25
Тогда после перезагрузки должно быть именно это, а не то, что показано ниже для readSPIFFS 1:
R: 0
G: 0
B: 0
L: 0
AmbientLight: 25
Итак, где я здесь накосячил?
ОБНОВЛЕНИЕ
struct RGBLA {
uint8_t R;
uint8_t G;
uint8_t B;
uint8_t L;
uint8_t A;
};
void setup() {
RGBLA returnedValues = readSPIFFS();
Serial.println("readSPIFFS 1");
Serial.print("R: ");
Serial.println(returnedVars.R);
Serial.print("G: ");
Serial.println(returnedVars.G);
Serial.print("B: ");
Serial.println(returnedVars.B);
Serial.print("L: ");
Serial.println(returnedVars.L);
Serial.print("AmbientLight: ");
Serial.println(returnedVars.A);
returnedValues = saveToSPIFFS(205, 17, 68, 50, 15, false);
Serial.println("saveToSPIFFS 1");
Serial.print("R: ");
Serial.println(returnedVars.R);
Serial.print("G: ");
Serial.println(returnedVars.G);
Serial.print("B: ");
Serial.println(returnedVars.B);
Serial.print("L: ");
Serial.println(returnedVars.L);
Serial.print("AmbientLight: ");
Serial.println(returnedVars.A);
}
RGBLA readSPIFFS() {
RGBLA returnedVars;
File configFile = SPIFFS.open("/config.json", "r");
if (configFile ) {
Serial.println("YAY!");
configFile.readBytes((byte*) &returnedValues, sizeof(RGBLA));
configFile.close();
} else {
Serial.println("Boo!");
}
return returnedValues;
}
RGBLA saveToSPIFFS() {
File configFile = SPIFFS.open("/config.json", "w+");
if (configFile.size() > 3072) {
Serial.println("Config file size is too large.");
} else {
Serial.print("Writing to Config file...");
//Get the old value and save it
RGBLA returnedVars = readSPIFFS();
Serial.println("Old Values:");
Serial.print("R: ");
Serial.println(returnedVars.R);
Serial.print("G: ");
Serial.println(returnedVars.G);
Serial.print("B: ");
Serial.println(returnedVars.B);
Serial.print("L: ");
Serial.println(returnedVars.L);
Serial.print("AmbientLight: ");
Serial.println(returnedVars.A);
if (saveA) {
//Save Ambient Light data
returnedVars.A = A;
} else {
//Save RGBL data
returnedVars.R = R;
returnedVars.G = G;
returnedVars.B = B;
returnedVars.L = L;
}
configFile.write((byte*) &returnedVars, sizeof(RGBLA));
configFile.close();
return returnedVars;
}
@StealthRT, 👍0
Обсуждение1 ответ
Вы можете записать структуру в файл в виде двоичных данных. Этот пример из моего проекта.
глобальные данные:
struct Stats {
int heatingTime; // минуты
int consumedPower; // Вт
};
Stats statsData;
фрагмент из setup():
File file = SPIFFS.open(STATS_FILENAME, "r");
if (file) {
file.readBytes((byte*) &statsData, sizeof(statsData));
file.close();
}
фрагмент из функции statsSave():
File file = SPIFFS.open(STATS_FILENAME, "w");
if (file) {
file.write((byte*) &statsData, sizeof(statsData));
file.close();
}
Ваш обновленный readSPIFFS должен быть:
RGBLA readSPIFFS() {
RGBLA returnedVars;
File configFile = SPIFFS.open("/config.json", "r");
if (configFile ) {
Serial.println("YAY!");
configFile.readBytes((byte*) &returnedValues, sizeof(RGBLA));
configFile.close();
} else {
Serial.println("Boo!");
}
return returnedValues;
}
Значит, я все еще могу вернуть **RGBLA**, например **RGBLA returnVars = readSPIFFS();**?, @StealthRT
Посмотрите мой обновленный ОП., @StealthRT
configFile.readBytes((byte*) &returnedValues, sizeof(returnedValues));
или configFile.readBytes((byte*) &returnedValues, sizeof(RGBLA));
, @Juraj
Хорошо, исправил это в обновлении. Нужно ли мне еще использовать **return returnVars;** или он уже заполняет стойку?, @StealthRT
что такое configFile["R"]
?, @Juraj
Получение значения **R** в **RGBLA.**, @StealthRT
вы читаете его в структуру с помощью readbytes. он находится в returnValues после readBytes, @Juraj
Хорошо, я снова обновил ОП, чтобы отразить изменения. Правильно ли это сейчас?, @StealthRT
вы читаете локальную переменную returnValues, а return
копирует значения структуры в returnValues в переменной в настройке., @Juraj
Хорошо, я снова обновил ОП, чтобы отразить эти изменения. Я также добавил **saveToSPIFFS**, но не знаю, как его сохранить, поскольку в нем есть старые данные, которые необходимо сохранить вместе с новыми данными (пример: RGBL — это новые данные, а A — старые данные), все, что необходимо сохранить. в этот файл конфигурации., @StealthRT
Хорошо, я думаю, что теперь оно у меня есть. Обновил обновление ОП., @StealthRT
После того, как я наконец смог это проверить, я получаю сообщение об ошибке **недопустимого преобразования из 'byte* {aka unsigned char*}' в 'char*' [-fpermissive]**, @StealthRT
**недопустимое преобразование из 'char*' в 'const uint8_t* {aka const unsigned char*}' [-fpermissive]**, @StealthRT
измените приведение на необходимый тип. это всего лишь разные названия байтов., @Juraj
- Передача функции-члена класса в качестве аргумента
- esp32 Stack canary watchpoint срабатывает
- Преобразование byte* в int в Arduino
- NodeMCU (Arduino IDE) «DynamicJsonBuffer» не был объявлен в этой области
- Веб-сервер ESP8266 не отвечает (тайм-аут подключения)
- Прошивать NodeMCU с помощью .ino-файла?
- Ошибка «Неопределенная ссылка» во время компиляции для функций, определенных в исходном файле .cpp, которые вызываются в моем основном файле проекта
- Не могу скомпилировать .ino с помощью библиотеки ArduinoJson
почему вы сохраняете его как JSON? простые
file.write((byte*) rgbla, sizeof (RGBLA))
иfile.read((byte*) rgbla, sizeof (RGBLA))
будут работать, @Juraj@Юрай, можешь ли ты назвать это потенциальным ответом и привести пример?, @StealthRT
если это будет только один экземпляр структуры RGBLA и один файл для ее сохранения, тогда создайте один глобальный экземпляр структуры и скорее верните успешное состояние из функций, @Juraj