[RESOLUT]Qui peut m'aider a récupérer les valeurs d'un WebForm vers mon ESP ?

Bonjour a tous, je cherche comment récupérer les valeurs d'un WebForm depuis mon ESP8266

Le code du Form HTML que j'utilise:

<form action="/postindex" method="POST">
<span>1</span>Select sensor 1 sensitivity for Your Plant</div>
<select name="sensor1" id="slct" required>
 <option disabled selected value>Plant Sensor 1</option>
 <option value="0">NONE</option> 
 <option value="1">Mint</option>
 <option value="2">Parsley</option>
 <option value="3">Basil</option>
 <option value="4">Coriander</option>
 <option value="5">Dill</option>
 <option value="6">Sage</option>
 <option value="7">rosemary</option> 
</select>
<div class="button-section">
 <input type="submit" name="Sign Up" />
</div>
</form>

Le code cote ESP

#include <ESP8266WiFi.h> 
#include "FS.h"
const char* CONFIG_HTML = "/html/config.html";
const char* ssid = "SSID";
const char* password = "PASSWORD";
const uint16_t HTTPPort = 80;
WiFiServer serveurWeb(HTTPPort); // crée un serveur sur le port HTTP standard
const byte maxHTTPLine = 100;
char httpLine[maxHTTPLine + 1]; //+1 pour avoir la place du '\0'
const byte maxURL = 50;
char urlRequest[maxURL + 1]; //+1 pour avoir la place du '\0'

void setup()
{
 Serial.begin(115200);
 Serial.println("\n\nTest SPIFFS\n");
 // on démarre le SPIFSS
 if (!SPIFFS.begin())
 {
  Serial.println("erreur SPIFFS");
  while (true); // on ne va pas plus loin
 }
 WiFi.begin(ssid, password);
 Serial.println();
 while (WiFi.status() != WL_CONNECTED)
 {
  delay(500);
  Serial.write('.');
 }
 Serial.println();
 // on démarre le serveur
 serveurWeb.begin();
 printHTTPServerInfo();
}

void loop()
{
 testRequeteWeb();
}

le code testRequeteWeb:

boolean testRequeteWeb()
{
 boolean requeteHTTPRecue = false;
 byte indexMessage = 0;
 char * ptrGET, *ptrEspace;

 WiFiClient client = serveurWeb.available();
 if (!client) return requeteHTTPRecue; // pas de client connecté
 boolean currentLineIsBlank = true;
 while (client.connected())
 {
  if (client.available())
  {
   // on lit toute la trame HTTP, ici sans se soucier de la requête
   char c = client.read();
   //Serial.print(c);
   if (c == '\n' && currentLineIsBlank) // une requête HTTP se termine par une ligne vide
   {


    // Control si le submit a ete presse
     if(strstr(urlRequest, "/postindex"))
     {
       // QUEL SONT LES CODES QUE DOIS-JE UTILISER POUR RECUPERER LA VARIABLE DU FORM ?
     }


    // ON GENERE LA PAGE WEB
    if (strcmp(urlRequest, "/favicon.ico")) // si ce n'est pas pour le favicon
    {
     requeteHTTPRecue = true;

     // -------------------------------- Pour la Page CONFIG_HTML ------------------------------- //

     // on regarde si on a une requete qui contient /reqEtatBouton
     if (strstr(urlRequest, "/config"))
     {
      // on envoie la page web par défaut 
      if (SPIFFS.exists(CONFIG_HTML))
      {
       // On envoie un en tête de réponse HTTP standard
       client.println(F("HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n"));
       File pageWeb = SPIFFS.open(CONFIG_HTML, "r");
       client.write(pageWeb,sizeof(pageWeb));
       pageWeb.close();
      }
      else
      {
       Serial.println(F("Erreur de fichier"));
      }
     }
    // -------------------------------- Fin Page CONFIG_HTML ------------------------------------ //
}
// on sort du while et termine la requête
   break;
  }
  if (c == '\n')
  {
   currentLineIsBlank = true;
   httpLine[indexMessage] = '\0'; // on termine la ligne correctement (c-string)
   indexMessage = 0; // on se reprépre pour la prochaine ligne
   if (ptrGET = strstr(httpLine, "GET"))
   {
    // c'est la requête GET, la ligne continent "GET /URL HTTP/1.1", on extrait l'URL
    ptrEspace = strstr(ptrGET + 4, " ");
    *ptrEspace = '\0';
    strncpy(urlRequest, ptrGET + 4, maxURL);
    urlRequest[maxURL] = '\0'; // par précaution si URL trop longue
   }
  }
  else if (c != '\r')
   {
    currentLineIsBlank = false;
    if (indexMessage <= maxHTTPLine - 1)
    {
     httpLine[indexMessage++] =  c; // sinon on ignore le reste de la ligne
    }
   }
  } // end if available
 } // end while
 delay(1);
 client.stop(); // termine la connexion
 return requeteHTTPRecue;
}

Ce que j'ai envie de faire quand je presse sur le bouton submit du form, comme exemple je choisi 'Parsley' de la liste, donc ça valeur est de 2 -> value="2" , que je recupere la valeur '2' dans une variable.

Je vous demande de l'aide comme je n'est pas réussi a trouver ou a comprendre celon tous les exemple que j'ai trouver sur le net, quel sont les codes que dois-je utiliser pour que ca marche?

Le code

if(strstr(urlRequest, "/postindex"))

est il ou bonne endroit ?

Je remonte mon post.

Je n'ai toujours pas compris, trouver quel sont les code que dois-je utiliser pour récupérer les données de mon webform

Qui peut m'aider ?

Je n'y connais pas grand chose dans ce type de données, mais si ça pouvait être assimilé à du JSON, tu pourrais utiliser des bibliothèques toutes faites et optimisées pour extraire les données de manière simple.

avant de rentrer dans le test

    // Control si le submit a ete presse
     if(strstr(urlRequest, "/postindex"))
     {
       // QUEL SONT LES CODES QUE DOIS-JE UTILISER POUR RECUPERER LA VARIABLE DU FORM ?
     }

imprimez ce qu'il y a dans urlRequest

Bonjour,

Ce que vous demandez n'est pas vraiment simple.
Il y a plusieurs choses à mettre au point dans l'ordre, sinon tout va bouger en même temps et vous n'y arriverez pas :

  • faire une page html qui fonctionne. Copier votre html dans un fichier, lui donner un nom en .htm et ouvrir avec votre navigateur. Mettre la page au point. Vous pouvez vérifier s'il y a des erreurs avec l'affichage du code source de la page, sur Mozilla Outils/Développement web/code source de la page,
  • pour le retour d'informations, commencez par une requête GET, plus simple à traiter qu'une POST,
  • quand vous cliquez sur le bouton, le navigateur affiche une erreur (normal il n'a pas de réponse à sa requête), mais il vous donne une information très importante, à savoir le contenu de la requête, schématiquement, pour chaque élément du form : =,
  • sur l'ESP, la première chose à faire est d'imprimer la requête reçue sur le moniteur série pour vérifier que l'on a bien ce que l'on attend
  • Ensuite, sur votre ESP, il vous faudra extraire de la requête les éléments communiqués par le navigateur.

Voici un exemple pour que vous compreniez comment cela marche.
D'abord, votre page (un peu) retravaillée :

<!DOCTYPE html>
<html>
<body>
<form action='postindex.htm'>
Select sensor 1 sensitivity for Your Plant
<select name='S01'>
 <option value='0'>NONE</option>
 <option value='1'>Mint</option>
 <option value='2'>Parsley</option>
 <option value='3' selected>Basil</option>
 <option value='4'>Coriander</option>
 <option value='5'>Dill</option>
 <option value='6'>Sage</option>
 <option value='7'>rosemary</option>	
</select>


<button name='B01' type='submit' value ='53'>
Texte</button>
</form>
</body>
</html>

J'ai rajouté une selection par défaut sur le basilic (basil).
Et voici la requête qu'elle va envoyer à l'ESP :

GET /postindex.htm?S01=3&B01=53 HTTP/1.1
Host: <Ip du serveur>
User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:52.0) Gecko/20100101 Firefox/52.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: fr,fr-FR;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://<Ip du serveur>/
Connection: keep-alive
Upgrade-Insecure-Requests: 1

La partie utile de la requête est sur la première ligne : postindex.htm?S01=3&B01=1
Ici l'élément "S01" vaut "3" et le "B01" vaut "53".

C'est cela qu'il vous faut traiter pour récupérer les infos.

Pour bien comprendre, modifiez le code html et regardez ce que renvoie le navigateur. Jouez avec la page.

J'espère que cela vous a mis sur la voie,

Bonne bidouille

MicroQuettas

PS : 1 html accepte les apostrophes ' ou les guillemets ". Les apostrophes sont plus faciles à gérer en C,
2 regardez un cours HTML pour la mise en page et les fonctions des boutons, sélecteurs etc.

3 on peut faire autrement, par ex. avec un script JS. J'ai répondu avec du html simple.

J'ai changé mon code, ça marche déjà mieux :slight_smile:
je reçois comme requête:

GET /postindex.htm?S01=1&S02=0&S03=3&S04=5&BT01=53 HTTP/1.1
Host: 192.168.1.3
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.119 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,/;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9,fr;q=0.7

Il reste a récupérer les données, comment faire ?

J'ai 2 autres questions

  1. le if (strcmp(urlRequest, "/favicon.ico")) sert a quoi? Est-il nécessaire?

  2. Mes html ne prennent pas en compte les css attaché, si je lance les html stocker sur mon pc dans le browser ça marche.
    Comment faire ?

avez vous testé ce qu'il y aura dans urlRequest?

si d'aventure ça ressemblait à /postindex.htm[color=red]?[/color]S01=1[color=red]&[/color]S02=0[color=red]&[/color]S03=3[color=red]&[/color]S04=5[color=red]&[/color]BT01=53 ce serait pas mal :slight_smile:

pour analyser le contenu d'une c-string (tableau de caractère se terminant par '\0' ) vous pouvez utiliser les fonctions traditionnelles C qui sont dans ces librairies stdlib.h et string.h. Un bon départ serait de regarder strtok() car vous avez de jolis délimiteurs dans votre buffer

J-M-L:
avez vous testé ce qu'il y aura dans urlRequest?

Que je dis pas de bêtise, le code qui a affiché le résultat dans e moniteur série est le suivant

while (client.connected())
{
if (client.available())
{
// on lit toute la trame HTTP, ici sans se soucier de la requête
char c = client.read();
Serial.print(c);

qui est bien avant le

if(strstr(urlRequest, "/postindex"))

Pour voir ce que le urlRequest contient je devrais ajouter du code dans le if ?
c'est bien ca? :confused:
Quel code mettre pour voir si cela marche?

Le code affiche tout ce que vous recevez - ce n’est pas forcément ce qu’il y a dans la variable.... pourquoi ne pas l’imprimer juste avant le test (histoire que si elle n’était pas bonne vous aillez une indication sur quoi faire ensuite....vu qu’il manque plein de code dans ce que vous avez posté on ne sait pas ce que vous avez saboté dans le code que vous avez emprunté :)) )
Sinon pour votre question sur favicon.ico c’est parce que souvent les navigateurs demandent en plus de leur requête le favicon (petite icône qui s’affiche dans la barre url) et vous ne voulez pas régénérer la réponse pour cela

Bonjour,

En complément de la réponse de J-M-L, sur les fichier css : si vous ne voulez pas vous embêter avec des fichiers séparés qu'il vous faudra servir, vous pouvez aussi incorporer le css directement dans l'entête de la page, comme cela :

<!DOCTYPE html>
<html>
<head>
<link rel='icon' href='data:,'>
<title>S'affiche dans la barre URL</title>
<style type='text/css'>
 /* Votre css ici */
</style>
</head>
<body>
<form action='postindex.htm'>
Select sensor 1 sensitivity for Your Plant
<select name='S01'>
 <option value='0'>NONE</option>
 <option value='1'>Mint</option>
 <option value='2'>Parsley</option>
 <option value='3' selected>Basil</option>
 <option value='4'>Coriander</option>
 <option value='5'>Dill</option>
 <option value='6'>Sage</option>
 <option value='7'>rosemary</option>	
</select>


<button name='B01' type='submit' value ='53'>
Texte</button>
</form>
</body>
</html>

Les puristes vont froncer les sourcils, mais c'est simple et ça marche.

Concernant la favicon, la ligne dans l'entête de la page calme les
demandes de certains navigateurs, mais pas de tous...

Pour le traitement des infos, faites comme indiqué par J-M-L. Petit conseil, plus les names et values retournés par les éléments html seront simples et structurés, plus ce sera facile.

Bonne bidouille,

MicroQuettas

PS : dans les css, les commentaires suivent la syntaxe du C (/* */) et pas celle du html (<!-- ->)...

Merci a vous pour les explications :slight_smile:

J-M-L:
Le code affiche tout ce que vous recevez - ce n’est pas forcément ce qu’il y a dans la variable.... pourquoi ne pas l’imprimer juste avant le test (histoire que si elle n’était pas bonne vous aillez une indication sur quoi faire ensuite

C'est ou exactement avant le test? a quel emplacement?

J-M-L:
vu qu’il manque plein de code dans ce que vous avez posté on ne sait pas ce que vous avez saboté dans le code que vous avez emprunté :)) )

Mon code est posté au #1, juste que j'ai mis le if avant le favicon, aucun problème de le mettre après le favicon.

Si j'ai bien compris, il faut récupérer la tram avec mes variable dans un String puis extraire mes variable, c'est bien ça?
Comment recevoir la trame spécifique dans un string?

En écrivant le post enfaîte le urlRequest c'est le string_c avec la trame, donc utiliser strtok() pour les extraire ?
C'est bien ça?

Ça avance déjà bien grâce a vous :slight_smile:

J'ai fais un petit changement, la trame http que je recois :

GET /config.html?S01=1&S02=5&S03=0&S04=7&BT01=Submit HTTP/1.1

grace a ce code je separe les S01,S02;S03 et S04

char *s1 = strtok(urlRequest,"?");
s1 = strtok(NULL,"&");
char *s2 = strtok(NULL,"&");
char *s3 = strtok(NULL,"&");
char *s4 = strtok(NULL,"&");
Serial.println(s1);
Serial.println(s2);
Serial.println(s3);
Serial.println(s4);

Je reçois comme résultat dans le moniteur série

S01=1
S02=5
S03=0
S04=7

pour extraire chaque numero en INT j'ai utiliser le code suivant pour chaqu'un

s1 = strtok(s1,"=");
s1 = strtok(NULL,"=");
int PlantS1 = atoi(s1);

Voila ce que j'ai réussi a faire :slight_smile:
Mon code est correct ?

C’est ça ! Bravo

  • vous devriez vérifier que c’est bien S1 ou S2 comme nom de variable

Oui c'est bien ça , cela marche impeccable.

Je trouve un autre problème,
j'ai ajouter un fichier json pour sauvegarder les données reçu après le submit, puis dans le setup la partie du chargement des données.
Je me suis basé sur l'exemple du configfile, je test d'abord avec une variable par la suite si ça marchera j'ajouterais les autres.
Mon Code Json

La sauvegarde marche, ça enregistre bien dans le fichier json, quand je fais un reset pour voir si le chargement marche, la je reçois un message d'erreur dans le moniteur série Exception code error 29 . :frowning:

J'ai essayer de faire des recherches sur le net, je n'ai rien trouver de compréhensible comment le résoudre.

J'espère grâce a votre aide je pourrais résoudre ce problème :slight_smile:

Avec votre erreur vous n’avez pas en plus un dump de la stack?

—> utilisez le Esp Exception Decoder pour voir ce que ça dit

Bonjour,

L'exception 29 c'est :

Region Protection or MMU | Yes |
| 29 | StoreProhibitedCause | A store referenced a page mapped with an attribute that does not permit stores

Cela se produit, par ex. quand on essaie d'écrire dans la mémoire programme.

Pour trouver l'endroit où se produit l'exception, vous pouvez aussi procéder "à la papa", en mettant des traces :

Serial.println("Tnn"); /* nn = numéros pour repérer la trace qui a déclenché */

pour cerner le problème.

Bonne bidouille,

MicroQuettas

Le code que je met dans le setup

 if (!loadConfig()) 
 {Serial.println("Failed to load config");}
 else 
 {Serial.println("Config loaded");}

le code du loadConfig

le message d'erreur

Exception (29):
epc1=0x40207aa5 epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000000 depc=0x00000000

ctx: cont
sp: 3ffefa30 end: 3ffefd30 offset: 01a0

stack>>>
3ffefbd0: 00000018 00000001 3fff14ec 40207a17
3ffefbe0: 3ffe8740 3ffefbf0 000000c8 00000018
3ffefbf0: 3ffefbe0 3ffefbf8 00000000 3fff14ec
3ffefc00: 00000002 3fff14fb 3fff1570 40203a9c
3ffefc10: 00000000 00000000 3ffefc26 3ffefc20
3ffefc20: 0000001e 017c0429 feefeffe feefeffe
3ffefc30: 00100000 00002000 00100000 00000100
3ffefc40: feefeffe feefeffe feefeffe 00000020
3ffefc50: 00000001 000000fc 3fff1570 40202568
3ffefc60: 3ffefca0 00000000 3fff1634 3fff18f4
3ffefc70: feefeffe feefeffe feefeffe 00000578
3ffefc80: 000000b4 3fff1570 3fff156c 4020a435
3ffefc90: 00000578 4020aec8 3ffeecd0 401004d8
3ffefca0: 4020a5b4 4020a678 4020a7bc 002fb000
3ffefcb0: 00100000 00001000 3ffe8958 00000000
3ffefcc0: 000003e8 00002fb0 3fff14ac 3fff069c
3ffefcd0: 3ffefbe0 3fff1504 3fff14ff 3ffeec0a
3ffefce0: 00000000 3fff1570 3fff156c 4020a47f
3ffefcf0: feefeffe 3ffeecd0 3ffeecd0 3ffeecfc
3ffefd00: 3fffdad0 3ffeecd0 3ffeecd0 40207b6b
3ffefd10: feefeffe 00000000 3ffeecf4 40209964
3ffefd20: feefeffe feefeffe 3ffeed10 40100718
<<<stack<<<

ets Jan 8 2013,rst cause:2, boot mode:(3,6)

load 0x4010f000, len 1384, room 16
tail 8
chksum 0x2d
csum 0x2d
v3de0c112
~ld

Le resultat du decoder

Exception 29: StoreProhibited: A store referenced a page mapped with an attribute that does not permit stores
Decoding 15 results
0x40207aa5: loadConfig() at C:\Users\SA\AppData\Local\Temp\arduino_build_924738\sketch/config_json_file.h line 30
0x40207a17: get_impl at C:\Users\SA\Documents\Arduino_arduino-1.8.5\libraries\libraries\ArduinoJson\src/ArduinoJson/JsonObject.hpp line 310
: (inlined by) get at C:\Users\SA\Documents\Arduino_arduino-1.8.5\libraries\libraries\ArduinoJson\src/ArduinoJson/JsonObject.hpp line 180
: (inlined by) as at C:\Users\SA\Documents\Arduino_arduino-1.8.5\libraries\libraries\ArduinoJson\src/ArduinoJson/JsonObjectSubscript.hpp line 61
: (inlined by) operator char at C:\Users\SA\Documents\Arduino_arduino-1.8.5\libraries\libraries\ArduinoJson\src/ArduinoJson/Deserialization/../JsonVariantCasts.hpp line 49
: (inlined by) loadConfig() at C:\Users\SA\AppData\Local\Temp\arduino_build_924738\sketch/config_json_file.h line 30
0x40203a9c: spiffs_obj_lu_scan at C:\Users\SA\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266\spiffs/spiffs_nucleus.c line 941
0x40202568: SPIFFS_mount at C:\Users\SA\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266\spiffs/spiffs_hydrogen.c line 980
0x4020a435: SPIFFSImpl::_tryMount() at C:\Users\SA\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/spiffs_api.h line 240
0x4020aec8: SPIFFSImpl::_check_cb(spiffs_check_type, spiffs_check_report, unsigned int, unsigned int) at C:\Users\SA\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/spiffs_api.h line 242
0x401004d8: malloc at C:\Users\SA\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266\umm_malloc/umm_malloc.c line 1664
0x4020a5b4: spiffs_hal_read(unsigned int, unsigned int, unsigned char*) at C:\Users\SA\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/spiffs_hal.cpp line 45
0x4020a678: spiffs_hal_write(unsigned int, unsigned int, unsigned char*) at C:\Users\SA\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/spiffs_hal.cpp line 102
0x4020a7bc: spiffs_hal_erase(unsigned int, unsigned int) at C:\Users\SA\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/spiffs_hal.cpp line 168
0x4020a47f: SPIFFSImpl::begin() at C:\Users\SA\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/spiffs_api.h line 124
0x40207b6b: setup at C:\Users\SA\AppData\Local\Temp\arduino_modified_sketch_764301/EspIrrigationPlants.ino line 133
0x40209964: loop_wrapper at C:\Users\SA\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/core_esp8266_main.cpp line 56
0x40100718: cont_norm at C:\Users\SA\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/cont.S line 109

postez votre code sur le forum, c'est ch*nt d'aller sur d'autres sites

changez ça

 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);
...

en

char* buf = (char *) malloc(size+1); // +1 for a trailing '\0'
if (buf == NULL) { 
    // not enough memory handle as you see fit
    return;
}
configFile.readBytes(buf, size);
buf[size] = '\0';

StaticJsonBuffer<200> jsonBuffer;  // you understand that 200 is going to be your buffer size... you tested againt 1024 as max above
 JsonObject& json = jsonBuffer.parseObject(buf);
 if (!json.success())
 {
  Serial.println("Failed to parse config file");
  return false;
 }
...

bien sûr comme j'ai fait un malloc il faudra faire un free() sur bug quand il ne sert plus

J-M-L:
postez votre code sur le forum, c'est ch*nt d'aller sur d'autres sites

Désolö j'ai pense que le code sera plus lisible grâce au couleur.

J'ai modifier mon code je reçois toujours un message d'erreur

Exception 29: StoreProhibited: A store referenced a page mapped with an attribute that does not permit stores
Decoding 14 results
0x40207ab2: loadConfig() at C:\Users\SA\AppData\Local\Temp\arduino_build_924738\sketch/config_json_file.h line 45
0x40207a1c: get_impl at C:\Users\SA\Documents\Arduino_arduino-1.8.5\libraries\libraries\ArduinoJson\src/ArduinoJson/JsonObject.hpp line 310
: (inlined by) get at C:\Users\SA\Documents\Arduino_arduino-1.8.5\libraries\libraries\ArduinoJson\src/ArduinoJson/JsonObject.hpp line 180
: (inlined by) as at C:\Users\SA\Documents\Arduino_arduino-1.8.5\libraries\libraries\ArduinoJson\src/ArduinoJson/JsonObjectSubscript.hpp line 61
: (inlined by) operator char at C:\Users\SA\Documents\Arduino_arduino-1.8.5\libraries\libraries\ArduinoJson\src/ArduinoJson/Deserialization/../JsonVariantCasts.hpp line 49
: (inlined by) loadConfig() at C:\Users\SA\AppData\Local\Temp\arduino_build_924738\sketch/config_json_file.h line 45
0x40202568: SPIFFS_mount at C:\Users\SA\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266\spiffs/spiffs_hydrogen.c line 980
0x4020a43d: SPIFFSImpl::_tryMount() at C:\Users\SA\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/spiffs_api.h line 240
0x4020aed0: SPIFFSImpl::_check_cb(spiffs_check_type, spiffs_check_report, unsigned int, unsigned int) at C:\Users\SA\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/spiffs_api.h line 242
0x401004d8: malloc at C:\Users\SA\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266\umm_malloc/umm_malloc.c line 1664
0x4020a5bc: spiffs_hal_read(unsigned int, unsigned int, unsigned char*) at C:\Users\SA\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/spiffs_hal.cpp line 45
0x4020a680: spiffs_hal_write(unsigned int, unsigned int, unsigned char*) at C:\Users\SA\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/spiffs_hal.cpp line 102
0x4020a7c4: spiffs_hal_erase(unsigned int, unsigned int) at C:\Users\SA\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/spiffs_hal.cpp line 168
0x4020a40a: SPIFFSImpl::_tryMount() at C:\Users\SA\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/spiffs_api.h line 226
0x40207b6f: setup at C:\Users\SA\AppData\Local\Temp\arduino_modified_sketch_415053/EspIrrigationPlants.ino line 132
0x4020996c: loop_wrapper at C:\Users\SA\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/core_esp8266_main.cpp line 56
0x40100718: cont_norm at C:\Users\SA\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/cont.S line 109

Il est gros comment votre Json ?