Analysieren Sie JSON mit arduino, um die LED einzuschalten

18

Hallo, ich versuche, JSON-Antworten vom Webserver in meinem Arduino zu analysieren, um ein LED-Licht ein- und auszuschalten. Ich verwende das sich wiederholende Beispiel für einen WLAN-Client, um eine Abrufanforderung an meinen Server zu senden:

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

Hier ist, was ich von der seriellen Schnittstelle zurück gedruckt bekomme

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

Wie analysiere ich den JSON-Teil dieser Antwort nur, damit ich damit meine LED steuern kann?

Vielen Dank

user1424508
quelle

Antworten:

11

Mir sind einige JSON-Parsing-Bibliotheken für Arduino bekannt.

Ich habe noch nie eines davon verwendet, aber ich habe in einem Projekt, an dem ich arbeite, ein einfaches JSON-Parsen durchgeführt, damit ich Ihnen zeigen kann, wie ich das gemacht habe.

HINWEIS: Ich lese serielle Daten mithilfe der Software-Serienbibliothek. Sie müssen diesen Code ändern, damit er für Sie funktioniert. Dies funktioniert nur mit sehr einfachen JSON-Zeichenfolgen. Es ist sehr begrenzt, aber wenn das alles ist, was Sie analysieren, dann wird es funktionieren.

Beispiel für eine JSON-Antwort vom Server:

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

Lesen Sie zunächst nur Daten zwischen geschweiften Klammern.

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

Dieser Code liest die Daten byteweise und beginnt, sobald er eine offene Klammer erhält, sie zu speichern response. Wenn es eine schließende Klammer bekommt, endet es. Hier ist also eine klare Einschränkung: Sie können nur einen Satz öffnender / schließender Klammern in Ihrer Zeichenfolge haben.

Sobald ich den String habe, benutze indexOfund substringextrahiere ich relevante Informationen:

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

Dieser Code setzt startauf den Anfang von id":"+ 5 Zeichen in der Zeichenfolge. Es ist +5, weil es so lang id":"ist. So startPunkte TEST1in dem JSON - String. In meinem System wird die ID immer 5 Zeichen lang sein, also ist das Ende start + 5. Ich benutze dann, um das substringzu extrahieren.

Nochmals, bevor mich jemand für diese schreckliche Lösung abstimmt: Wenn Sie genau wissen, womit Sie arbeiten und die Einschränkungen dieses Codes verstehen, ist dies keine schlechte Lösung. Es ist eine Lösung, die den Job erledigt.

Sachleen
quelle
Das von Ihnen angegebene JSON-Beispiel sieht nicht wie "gutes" JSON aus, z. B. sollten numerische Werte normalerweise nicht als Zeichenfolgen in Anführungszeichen gesetzt werden.
Jfpoilpret
+1 für die Liste der potenziell verwendbaren Bibliotheken für JSON. Ich bin überrascht, dass keine Bibliothek auf einem Callback-Funktionsansatz basiert, der beim Parsen aufgerufen werden würde (speichereffizienter).
Jfpoilpret
Zumindest bist du dir bewusst, dass dein Codebeispiel schrecklich ist :-) Natürlich wird es erledigt, aber es ist nicht lesbar (von jemand anderem und sogar von dir selbst in 6 Monaten) und daher nicht wartbar.
jfpoilpret
@jfpoilpret Ich habe nicht genügend Speicherplatz auf dem Chip, daher musste ich an einigen Stellen Abstriche machen. Zumindest ist es stark kommentiert.
Sachleen
Ich verstehe; aber ich frage mich, ob die StringVerwendung die Gedächtnissituation nicht verschlimmert (ja, Stringin Arduino ist mein Haustier ärgerlich).
Jfpoilpret
7

Ich habe eine Klasse programmiert, die char für char das JSON-Dokument erhält. Es werden nur einige Bytes für die bekannte JSON-Struktur unter Verwendung einer Zustandsmaschine und der von Ihnen benötigten Ergebnisse im Speicher gespeichert. Sie können also die Klasse nach den gewünschten Ergebnissen abfragen und JSON verarbeiten.

Es ist ideal für Ihren Zweck. Ich habe eine Verbindung zu einem Wetterdienst hergestellt, der einen JSON zurückgibt:

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;

Überprüfen Sie diesen Blogeintrag, den ich gerade geschrieben habe: http://web.biicode.com/blog/big-json-on-arduino .

Der Quellcode ist hier in Biicode.

Lasot
quelle
2

Ich habe einen Parser für den PIC geschrieben, der nur sehr wenig RAM verwendet, da er direkt mit Zeichenzeigern zusammenarbeitet und keine Baumstruktur erstellt. Wenn Sie nach Element N einer Liste fragen, erhalten Sie einen tatsächlichen Zeiger auf die direkte JSON-Datei direkt am Anfang von Element N der Liste. Dann können Sie fragen, für welche Art von Objekt der Zeiger steht. Es ist fehlerhaft und unterstützt keine Floats. Ich glaube, es gibt noch ein paar andere Einschränkungen (vor langer Zeit), aber alles auf github: https://github.com / EternityForest / OpenFortune-fortune-like-text-generator Sie müssen in libfortune suchen, das Teil der C-Version ist.

EternityForest
quelle
1

Ich habe eine einfache JSON-RPC-Bibliothek (zusätzlich zu aJson) mit dem Beispiel geschrieben, wie eine LED mit einem JSON-RPC-Prozeduraufruf eingeschaltet wird:

Meir Tseitlin
quelle
2
Können Sie Ihrer Antwort weitere Informationen hinzufügen, falls sich der Link zum Code / zur Dokumentation ändert ...
sachleen