Bonjour a tous,
J'essaye de sauvegarder un Json dans le SPIFFS d'un nodemcu, pour les recharger après une panne d'électricité ou un reset du module.
j'ai remarque qu'après un reset cela ne récupère pas les données.
Toutes les variable sont des int.
Les librairies que j'utilise
#include <ArduinoJson.h> #include <FS.h> #include <LittleFS.h>
Je suis partie au debout avec l'exemple du JsonConfigFile de la librairie Arduinojson6.
rajouter quelques lignes selon des exemples trouver sur le net.
J'aimerais votre aide.
bool loadConfiguration() {
File file = LittleFS.open("/config.json", "r");
// File file = SPIFFS.open("/config.json", "r");
if (!file) {
Serial.println("Failed to open config file");
return false;
}
size_t size = file.size();
if (size > 1024) {
Serial.println("Config file size is too large");
return false;
}
// Allocate a buffer to store contents of the file.
std::unique_ptr<char[]> buf(new char[size]);
// We don't use String here because ArduinoJson library requires the input
// buffer to be mutable. If you don't use ArduinoJson, you may as well
// use file.readString instead.
file.readBytes(buf.get(), size);
// StaticJsonDocument<200> doc;
DynamicJsonDocument jsonBuffer(2048);
auto error = deserializeJson(jsonBuffer, buf.get());
if (error) {
Serial.println("Failed to parse config file");
Serial.println(error.f_str());
return false;
}
// Copy values from the JsonObject to the Config
Usermax0 = jsonBuffer["Usermax0"];
Usermin0 = jsonBuffer["Usermin0"];
Usermax1 = jsonBuffer["Usermax1"];
Usermin1 = jsonBuffer["Usermin1"];
Usermax2 = jsonBuffer["Usermax2"];
Usermin2 = jsonBuffer["Usermin2"];
Usermax3 = jsonBuffer["Usermax3"];
Usermin3 = jsonBuffer["Usermin3"];
Usermax4 = jsonBuffer["Usermax4"];
Usermin4 = jsonBuffer["Usermin4"];
Usermax5 = jsonBuffer["Usermax5"];
Usermin5 = jsonBuffer["Usermin5"];
Usermax6 = jsonBuffer["Usermax6"];
Usermin6 = jsonBuffer["Usermin6"];
Usermax7 = jsonBuffer["Usermax7"];
Usermin7 = jsonBuffer["Usermin7"];
Usermax8 = jsonBuffer["Usermax8"];
Usermin8 = jsonBuffer["Usermin8"];
Usermax9 = jsonBuffer["Usermax9"];
Usermin9 = jsonBuffer["Usermin9"];
Usermax10 = jsonBuffer["Usermax10"];
Usermin10 = jsonBuffer["Usermin10"];
Usermax11 = jsonBuffer["Usermax11"];
Usermin11 = jsonBuffer["Usermin11"];
Usermax12 = jsonBuffer["Usermax12"];
Usermin12 = jsonBuffer["Usermin12"];
Usermax13 = jsonBuffer["Usermax13"];
Usermin13 = jsonBuffer["Usermin13"];
Usermax14 = jsonBuffer["Usermax14"];
Usermin14 = jsonBuffer["Usermin14"];
Usermax15 = jsonBuffer["Usermax15"];
Usermin15 = jsonBuffer["Usermin15"];
// Close the file (File's destructor doesn't close the file)
file.close();
return true;
}
L'exemple du JsonConfigFile est configurer pour une carte SD, je n'ai pas de carte SD a la place j'aimerais utiliser l'espace du SPIFFS.
Apres quelques changement j'ai commencer par ce code après avoir déplacer du code de place comme je n'étais pas sur si fonctionne bien.
Je suis repartie avec ce code:
#include <ArduinoJson.h>
#include <FS.h>
int MyValue1,MyValue2,MyValue3,MyValue4;
String MyString1,MyString2,MyString3;
int flag = 1;
bool loadConfiguration() {
File file = SPIFFS.open("/config.json", "r");
if (!file) {
Serial.println("Failed to open config file");
return false;
}
DynamicJsonDocument jsonBuffer(2048);
DeserializationError error = deserializeJson(jsonBuffer, file);
if (error) {
Serial.print(F("deserializeJson() failed: "));
Serial.println(error.f_str());
return false;
}
// Copy values from the JsonObject to the Config
MyValue1 = jsonBuffer["Value1"];
MyValue2 = jsonBuffer["Value2"];
MyValue3 = jsonBuffer["Value3"];
MyValue4 = jsonBuffer["Value4"];
MyString1 = jsonBuffer["StringValue1"].as<String>();
MyString2 = jsonBuffer["StringValue2"].as<String>();
MyString3 = jsonBuffer["MyString3"].as<String>();
// Close the file (File's destructor doesn't close the file)
file.close();
return true;
}
bool saveConfiguration() {
MyValue1 = random(1,99);
MyValue2 = random(1,99);
MyValue3 = random(1,99);
MyValue4 = random(1,99);
MyString1 = "MyString1";
MyString2 = "MyString2";
MyString3 = "MyString3";
Serial.println("Before Saving:");
Serial.print("MyValue1:"); Serial.println(MyValue1);
Serial.print("MyValue2:"); Serial.println(MyValue2);
Serial.print("MyValue3:"); Serial.println(MyValue3);
Serial.print("MyValue4:"); Serial.println(MyValue4);
Serial.print("MyString1:"); Serial.println(MyString1);
Serial.print("MyString2:"); Serial.println(MyString1);
Serial.print("MyString3:"); Serial.println(MyString1);
File file = SPIFFS.open("/config.json", "w");
if (!file) {
Serial.println("Failed to open config file for writing");
return false;
}
// DynamicJsonDocument<1536> jsonBuffer;
DynamicJsonDocument jsonBuffer(1536);
// Set the values
jsonBuffer["Value1"] = MyValue1+1;
jsonBuffer["Value2"] = MyValue2+1;
jsonBuffer["Value3"] = MyValue3+1;
jsonBuffer["Value4"] = MyValue4+1;
jsonBuffer["StringValue1"] = MyString1;
jsonBuffer["StringValue2"] = MyString2;
jsonBuffer["StringValue3"] = MyString3;
// Serialize JSON to file
serializeJson(jsonBuffer, file);
file.close();
return true;
}
void setup() {
Serial.begin(115200);
MyValue1 = 0;
MyValue2 = 0;
MyValue3 = 0;
MyValue4 = 0;
Serial.println("Setup config:");
Serial.print("MyValue1:"); Serial.println(MyValue1);
Serial.print("MyValue2:"); Serial.println(MyValue2);
Serial.print("MyValue3:"); Serial.println(MyValue3);
Serial.print("MyValue4:"); Serial.println(MyValue4);
Serial.println("\n\nMounting FS...\n");
if (!SPIFFS.begin())
{
Serial.println("erreur SPIFFS");
while (true); // on ne va pas plus loin
}
if(!saveConfiguration) {
Serial.println(F("failed to Save..."));
}
else {
Serial.println(F("Saved OK..."));
}
if(!loadConfiguration) {
Serial.println(F("Failed to load..."));
}
else {
Serial.println(F("Load OK..."));
Serial.println("After Loading:");
Serial.print("MyValue1:"); Serial.println(MyValue1);
Serial.print("MyValue2:"); Serial.println(MyValue2);
Serial.print("MyValue3:"); Serial.println(MyValue3);
Serial.print("MyValue4:"); Serial.println(MyValue4);
Serial.print("MyString1:"); Serial.println(MyString1);
Serial.print("MyString2:"); Serial.println(MyString1);
Serial.print("MyString3:"); Serial.println(MyString1);
}
}
void loop() {
// put your main code here, to run repeatedly:
}
La j'ai remarqué que ca ne marche pas je pense que cela vient de la mauvaise config du SPIFFS.
Ahh oui ce n'etais pas le final, par la suite je me suis retourne vers le code qui viens avec la librarire du esp8266 -> ConfigFile
je suis repartie pour ce code :
#include <ArduinoJson.h>
#include "FS.h"
#include <LittleFS.h>
int accessToken;
bool loadConfig() {
File configFile = LittleFS.open("/config.json", "r");
if (!configFile) {
Serial.println("Failed to open config file");
return false;
}
size_t size = configFile.size();
if (size > 1024) {
Serial.println("Config file size is too large");
return false;
}
// Allocate a buffer to store contents of the file.
std::unique_ptr<char[]> buf(new char[size]);
// We don't use String here because ArduinoJson library requires the input
// buffer to be mutable. If you don't use ArduinoJson, you may as well
// use configFile.readString instead.
configFile.readBytes(buf.get(), size);
StaticJsonDocument<200> doc;
auto error = deserializeJson(doc, buf.get());
if (error) {
Serial.println("Failed to parse config file");
return false;
}
const char* serverName = doc["serverName"];
accessToken = doc["accessToken"];
// Real world application would store these values in some variables for
// later use.
Serial.print("Loaded serverName: ");
Serial.println(serverName);
Serial.print("Loaded accessToken: ");
Serial.println(accessToken);
return true;
}
bool saveConfig() {
StaticJsonDocument<200> doc;
doc["serverName"] = "api.example.com";
doc["accessToken"] = 125;
File configFile = LittleFS.open("/config.json", "w");
if (!configFile) {
Serial.println("Failed to open config file for writing");
return false;
}
serializeJson(doc, configFile);
return true;
}
void setup() {
Serial.begin(115200);
Serial.println("");
delay(1000);
Serial.println("Mounting FS...");
if (!LittleFS.begin()) {
Serial.println("Failed to mount file system");
return;
}
if (!saveConfig()) {
Serial.println("Failed to save config");
} else {
Serial.println("Config saved");
}
if (!loadConfig()) {
Serial.println("Failed to load config");
} else {
Serial.println("Config loaded");
}
}
void loop() {
}
Je l'ai modifier pour mes variable.
Avec cette exemple ca a l'air de fonctionner.
Apres avoir envoyer les données du Form, je lance la sauvegarde (saving), dans le setup je lance le chargement (loading) des données, ça ne marche pas toutes les données reste a zéro , même en rajoutant un petit delay d'1s. dans le setup avant et après le chargement.
ile me faut StaticJsonDocument<512> doc d'après l'assistant.
J'ai essayer de refaire mon code, j'ai un code en arduinojson 5 qui marchait, j'ai essayer de faire la migration en arduinojson6, j'espère que je le fais correctement, je ne l'ai pas encore testé.
de sauvgarder les donnees dans un fichier json dans le SPIFFS du NodeMcu
de les charger dans le setup
J'ai mis mon code complet pour que vous puissiez l'examiner et me proposer les changement possible. configjson.h c'est le fichier que j'ai fais selon les exemples de la version 6 configjson1.h c'est le fichier que j'ai essayer de faire la migration.
ESP_Multiplexer_XML.ino:143:6: warning: the address of 'void saveConfiguration()' will never be NULL [-Waddress]
143 | if(!saveConfiguration) {
| ^~~~~~~~~~~~~~~~~
si vous voulez appeler la fonction il faut écrire
if(!saveConfiguration()) { // NE PAS OUBLIER LES PARENTHESES
le compilateur vous prévient aussi de ceci
/readSensor.h:65:12: warning: array subscript 15 is above array bounds of 'int [15]' [-Warray-bounds]
65 | sensor[15] = analogRead(SIG);
➜ tout débordement de tableau rend le fonctionnement de l'ensemble du programme indéterminé
ne laissez pas de warning lors de la compilation (activez les warning détaillés dans les préférences)
Executable segment sizes:
ICACHE : 32768 - flash instruction cache
IROM : 375860 - code in flash (default or ICACHE_FLASH_ATTR)
IRAM : 28165 / 32768 - code in IRAM (IRAM_ATTR, ISRs...)
DATA : 1508 ) - initialized variables (global, static) in RAM/HEAP
RODATA : 5600 ) / 81920 - constants (global, static) in RAM/HEAP
BSS : 26928 ) - zeroed variables (global, static) in RAM/HEAP
Le croquis utilise 411133 octets (39%) de l'espace de stockage de programmes. Le maximum est de 1044464 octets.
Les variables globales utilisent 34036 octets (41%) de mémoire dynamique, ce qui laisse 47884 octets pour les variables locales. Le maximum est de 81920 octets.
esptool.py v3.0
Serial port COM4
Connecting....
Chip is ESP8266EX
Features: WiFi
Crystal is 26MHz
MAC: 3c:71:bf:32:b0:25
Uploading stub...
Running stub...
Stub running...
Configuring flash size...
Auto-detected Flash size: 4MB
Compressed 415280 bytes to 278848...
Writing at 0x00000000... (5 %)
Writing at 0x00004000... (11 %)
Writing at 0x00008000... (16 %)
Writing at 0x0000c000... (22 %)
Writing at 0x00010000... (27 %)
Writing at 0x00014000... (33 %)
Writing at 0x00018000... (38 %)
Writing at 0x0001c000... (44 %)
Writing at 0x00020000... (50 %)
Writing at 0x00024000... (55 %)
Writing at 0x00028000... (61 %)
Writing at 0x0002c000... (66 %)
Writing at 0x00030000... (72 %)
Writing at 0x00034000... (77 %)
Writing at 0x00038000... (83 %)
Writing at 0x0003c000... (88 %)
Writing at 0x00040000... (94 %)
Writing at 0x00044000... (100 %)
Wrote 415280 bytes (278848 compressed) at 0x00000000 in 24.9 seconds (effective 133.6 kbit/s)...
Hash of data verified.
Leaving...
Hard resetting via RTS pin...
bizarre... vous êtes sûr, ça défile très vite - moi j'ai ça qui défile parmi tous les messages
~/Desktop/ESP_Multiplexer_XML/ESP_Multiplexer_XML.ino: In function 'void handleReadUserPlantSelected()':
~/Desktop/ESP_Multiplexer_XML/ESP_Multiplexer_XML.ino:143:6: warning: the address of 'void saveConfiguration()' will never be NULL [-Waddress]
143 | if(!saveConfiguration) {
| ^~~~~~~~~~~~~~~~~
~/Desktop/ESP_Multiplexer_XML/ESP_Multiplexer_XML.ino: In function 'void setup()':
~/Desktop/ESP_Multiplexer_XML/ESP_Multiplexer_XML.ino:345:7: warning: the address of 'void loadConfiguration()' will never be NULL [-Waddress]
345 | if(!loadConfiguration) { Serial.println(F("Failed to load...")); }
| ^~~~~~~~~~~~~~~~~
In file included from ~/Desktop/ESP_Multiplexer_XML/ESP_Multiplexer_XML.ino:83:
~/Desktop/ESP_Multiplexer_XML/readSensor.h: In function 'void getSoilHumidity()':
~/Desktop/ESP_Multiplexer_XML/readSensor.h:65:12: warning: array subscript 15 is above array bounds of 'int [15]' [-Warray-bounds]
65 | sensor[15] = analogRead(SIG);
| ~~~~~~~~~^
~/Desktop/ESP_Multiplexer_XML/ESP_Multiplexer_XML.ino:39:5: note: while referencing 'sensor'
39 | int sensor[15];
| ^~~~~~
~/Desktop/ESP_Multiplexer_XML/ESP_Multiplexer_XML.ino: In function 'void driveSolenoid()':
~/Desktop/ESP_Multiplexer_XML/ESP_Multiplexer_XML.ino:201:35: warning: array subscript 15 is above array bounds of 'int [15]' [-Warray-bounds]
201 | solenoidState15 = solenoidStatus(sensor[15], solenoid15, Usermax15, Usermin15);
| ~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~/Desktop/ESP_Multiplexer_XML/ESP_Multiplexer_XML.ino:39:5: note: while referencing 'sensor'
39 | int sensor[15];
|
donc vous avez oublié les parenthèses et vous débordez dans votre tableau
Bonsoir j'ai redémarré ce soir l'IDE et relance la compile, je ne reçoit pas de warning.
si le int sensor[15] pose problème je peux mettre plusieurs variables.
Ce qui m'intrigue le plus, c'est la partie de la sauvegarde du JSON, de reussir a les sauvegarder pour pouvoir les charger dans le setup après un reset ca pourrait être aussi une panne d'électricité.