Analyser JSON avec Arduino pour allumer la LED

18

Salut, j'essaie d'analyser la resposne JSON du serveur Web dans mon arduino afin d'allumer et d'éteindre une lumière LED. J'utilise l'exemple répétitif du client wifi pour faire une requête get à mon serveur:

http://arduino.cc/en/Tutorial/WiFiWebClientRepeating

Voici ce que je récupère du port série

connecting...
HTTP/1.1 200 OK
Date: Sun, 06 Apr 2014 01:14:37 GMT
Server: Apache
X-Powered-By: PHP/5.5.10
Cache-Control: no-cache
X-Frame-Options: SAMEORIGIN
Set-Cookie: expires=Sun, 06-Apr-2014 03:14:37 GMT; Max-Age=7200; path=/; httponly
Connection: close
Transfer-Encoding: chunked
Content-Type: application/json

19
{"lightstatus":"on"}
0

Comment analyser la partie JSON de cette réponse uniquement afin de pouvoir l'utiliser pour contrôler ma LED?

Merci

user1424508
la source

Réponses:

11

Je connais quelques bibliothèques d'analyse JSON pour Arduino.

Je n'en ai jamais utilisé, mais j'ai fait une analyse JSON simple dans un projet sur lequel je travaille, je vais donc vous montrer comment j'ai fait cela.

REMARQUE: je lis les données série à l'aide de la bibliothèque série du logiciel. Vous devrez modifier ce code pour qu'il fonctionne pour vous. Cela ne fonctionnera que sur des chaînes JSON très simples. C'est très limité, mais si c'est tout ce que vous analysez, cela fonctionnera.

Exemple de réponse JSON du serveur:

{"id":"TEST1","lat":"38.56050207","lng":"-121.42158374","total":"3","available":"2"}

Tout d'abord, lisez uniquement les données entre accolades.

String response = "";
bool begin = false;
while (SIM900.available() || !begin) {

    char in = SIM900.read();

    if (in == '{') {
        begin = true;
    }

    if (begin) response += (in);

    if (in == '}') {
        break;
    }

    delay(1);
}

Ce code lit les données un octet à la fois et une fois qu'il reçoit une accolade ouverte, il commence à les enregistrer response. Quand il obtient un corset de fermeture, il le termine. Voici donc une limitation claire, vous ne pouvez avoir qu'un seul ensemble d'accolades d'ouverture / fermeture dans votre chaîne.

Une fois que j'ai la chaîne, j'utilise indexOfet substringpour extraire les informations pertinentes:

start = response.indexOf("id\":\"") + 5;
end = start + 5;
nodeId = response.substring(start, end);

Ce code définit startau début de id":"+ 5 caractères dans la chaîne. C'est +5 parce que c'est combien de temps id":". Ainsi , les startpoints à TEST1la chaîne JSON. Dans mon système, l'ID comportera toujours 5 caractères, la fin l'est donc start + 5. J'utilise ensuite substringpour extraire cela.

Encore une fois, avant que quelqu'un ne me vote pour cette horrible solution: si vous savez exactement avec quoi vous travaillez et comprenez les limites de ce code, ce n'est pas une mauvaise solution. C'est une solution qui fait le travail.

sachleen
la source
L'exemple JSON que vous donnez ne ressemble pas à un "bon" JSON, par exemple, les valeurs numériques ne doivent normalement pas être citées sous forme de chaînes.
jfpoilpret
+1 pour la liste des bibliothèques potentiellement utilisables pour JSON. Je suis surpris qu'aucune bibliothèque ne soit basée sur une approche de fonction de rappel, qui serait appelée pendant l'analyse (beaucoup plus efficace en mémoire).
jfpoilpret
Au moins, vous êtes conscient que votre exemple de code est horrible :-) Bien sûr, il fait le travail, mais il n'est pas lisible (par quelqu'un d'autre et même par vous-même en 6 mois) et donc non maintenable.
jfpoilpret
@jfpoilpret Je n'ai plus de mémoire sur la puce, j'ai donc dû faire des économies à certains endroits. Au moins, c'est fortement commenté.
sachleen
Je comprends; mais je me demande si l' Stringutilisation n'aggrave pas la situation de la mémoire (oui, Stringen Arduino est ma bête noire).
jfpoilpret
7

J'ai programmé une classe qui recevra caractère par caractère le document JSON. Il ne stockera en mémoire que quelques octets pour la structure JSON connue en utilisant une machine d'état et les résultats dont vous avez besoin. Vous pouvez donc interroger la classe pour obtenir les résultats souhaités et traiter le JSON.

Son idéal pour votre but. J'ai utilisé pour me connecter à un service météo qui renvoie un json:

static const char* queries[] = { "list.0.deg", "list.0.weather.0.main"};
StreamJsonReader jsonreader(queries, 2); // 2 queries    
while(char c  =  read()){
      jsonreader.process_char(c);
}

cout << jsonreader.results[0] << endl;
cout << jsonreader.results[1] << endl;

Consultez ce billet de blog que je viens d'écrire: http://web.biicode.com/blog/big-json-on-arduino .

Le code source est ici en Biicode.

lasote
la source
2

J'ai écrit un analyseur pour le PIC qui utilise très peu de RAM car il fonctionne directement avec les pointeurs char et ne construit pas une structure arborescente. Si vous demandez à obtenir l'élément N d'une liste, cela vous donne un pointeur réel dans le fichier JSON direct juste au début de l'élément N de la liste. Ensuite , vous pouvez demander à quel type d'objet représente le pointeur, etc. Il est boguée et ne supporte pas les flotteurs et je pense a quelques autres limitations (TWAS il y a longtemps) , mais il est tout sur github: https://github.com / EternityForest / OpenFortune-fortune-like-text-generator Vous devrez regarder dans libfortune qui fait partie de la version C.

EternityForest
la source