Analizza JSON con arduino per accendere il LED


18

Ciao, sto provando ad analizzare il resposne JSON dal server web nel mio arduino per accendere e spegnere una luce a LED. Sto usando l'esempio di ripetizione del client wifi per fare una richiesta get al mio server:

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

Ecco cosa mi viene stampato dalla porta seriale

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

Come posso analizzare la parte JSON di questa risposta solo in modo da poterla utilizzare per controllare il mio LED?

Grazie

Risposte:


11

Sono a conoscenza di alcune librerie di analisi JSON per Arduino.

Non ho mai usato nessuno di questi, ma ho fatto una semplice analisi JSON in un progetto a cui sto lavorando, quindi ti mostrerò come ho fatto.

NOTA: sto leggendo i dati seriali utilizzando la libreria seriale del software. Dovrai modificare questo codice in modo che funzioni per te. Funzionerà solo su stringhe JSON molto semplici. È molto limitato, ma se è tutto ciò che stai analizzando, funzionerà.

Esempio di risposta JSON dal server:

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

Innanzitutto, leggi solo i dati tra parentesi graffe.

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

Questo codice legge i dati un byte alla volta e una volta ottenuto un controvento aperto, inizia a salvarli response. Quando riceve una parentesi graffa di chiusura, la termina. Quindi ecco una chiara limitazione, puoi avere solo un set di parentesi graffe di apertura / chiusura nella tua stringa.

Una volta che ho la stringa, uso indexOfe substringper estrarre le informazioni rilevanti:

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

Questo codice imposta startl'inizio di id":"+ 5 caratteri nella stringa. È +5 perché è così id":". Quindi startpunta a TEST1nella stringa JSON. Nel mio sistema, l'ID sarà sempre lungo 5 caratteri, quindi fine è start + 5. Poi lo uso substringper estrarlo.

Ancora una volta, prima che qualcuno inizi a votarmi per questa orribile soluzione: se sai esattamente con cosa stai lavorando e comprendi i limiti di questo codice, allora questa non è una cattiva soluzione. È una soluzione che porta a termine il lavoro.


L'esempio JSON fornito non sembra un JSON "buono", ad esempio i valori numerici non devono essere normalmente indicati come stringhe.
jfpoilpret,

+1 per l'elenco di librerie potenzialmente utilizzabili per JSON. Sono sorpreso che nessuna libreria si basi su un approccio con funzione di callback, che verrebbe chiamato durante l'analisi (molto più efficiente in termini di memoria).
jfpoilpret,

Almeno sei consapevole del fatto che il tuo esempio di codice è orribile :-) Certo che fa il lavoro, ma non è leggibile (da qualcun altro e nemmeno da solo in 6 mesi) e quindi non mantenibile.
jfpoilpret,

@jfpoilpret Ho esaurito la memoria del chip, quindi ho dovuto tagliare angoli in alcuni punti. Almeno è fortemente commentato.
sachleen,

Capisco; ma mi chiedo se l' Stringuso non peggiori la situazione della memoria (sì, Stringin Arduino c'è la mia pipì per animali domestici).
jfpoilpret,

7

Ho programmato una lezione che riceverà a caratteri il documento JSON. Memorizzerà solo pochi byte per la struttura JSON nota utilizzando una macchina a stati e i risultati necessari. Quindi è possibile eseguire una query sulla classe per i risultati desiderati ed elaborare JSON.

È l'ideale per il tuo scopo. Ho usato per la connessione a un servizio meteo che restituisce 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;

Controlla questo post sul blog che ho appena scritto: http://web.biicode.com/blog/big-json-on-arduino .

Il codice sorgente è qui in Biicode.


2

Ho scritto un parser per il PIC che ha un utilizzo di ram molto basso perché funziona direttamente con i puntatori char e non costruisce una struttura ad albero. Se chiedi di ottenere l'elemento N di un elenco, ti dà un puntatore effettivo nel file JSON diretto proprio all'inizio dell'elemento N dell'elenco. Quindi puoi chiedere quale tipo di oggetto rappresenta il puntatore, ecc. È difettoso e non supporta i float e penso che abbia alcune altre limitazioni (molto tempo fa) ma è tutto su github: https://github.com / EternityForest / OpenFortune-fortune-like-text-generator Dovrai cercare in libfortune che fa parte della versione C.


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.