Parse JSON dengan arduino untuk menyalakan LED

18

Hai, saya sedang mencoba untuk mem-parse JSON resposne dari server web di Arduino saya untuk menghidupkan dan mematikan lampu LED. Saya menggunakan contoh berulang klien wifi untuk mengajukan permintaan ke server saya:

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

Inilah yang saya dapatkan dicetak kembali dari port serial

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

Bagaimana saya mem-parsing bagian JSON dari respons ini hanya agar saya dapat menggunakannya untuk mengontrol LED saya?

Terima kasih

pengguna1424508
sumber

Jawaban:

11

Saya mengetahui beberapa parsing JSON untuk Arduino.

Saya tidak pernah menggunakan ini tetapi saya melakukan beberapa JSON sederhana parsing dalam proyek yang sedang saya kerjakan jadi saya akan menunjukkan kepada Anda bagaimana saya melakukannya.

CATATAN: Saya membaca data serial menggunakan pustaka serial perangkat lunak. Anda harus mengubah kode ini agar bekerja untuk Anda. Ini hanya akan bekerja pada string JSON yang sangat sederhana. Ini sangat terbatas tetapi jika hanya itu yang Anda parsing maka itu akan berhasil.

Contoh respons JSON dari server:

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

Pertama, hanya baca data antara kurung kurawal.

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

Kode ini membaca data satu byte pada satu waktu dan setelah mendapat tanda kurung terbuka, ia mulai menyimpannya response. Ketika mendapat penjepit penutup, itu mengakhirinya. Jadi, inilah batasan yang jelas, Anda hanya dapat memiliki satu set kawat pembuka / penutup pada string Anda.

Setelah saya memiliki string, saya menggunakan indexOfdan substringuntuk mengekstrak informasi yang relevan:

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

Kode ini diset startke awal id":"+ 5 karakter dalam string. Ini +5 karena itu berapa lama id":". Jadi startmenunjuk ke TEST1dalam string JSON. Dalam sistem saya, ID akan selalu sepanjang 5 karakter, jadi pada akhirnya start + 5. Saya kemudian gunakan substringuntuk mengekstraknya.

Sekali lagi, sebelum ada yang mulai memilih saya untuk solusi mengerikan ini: jika Anda tahu persis apa yang Anda kerjakan, dan memahami keterbatasan kode ini, maka ini bukan solusi yang buruk. Ini solusi yang menyelesaikan pekerjaan.

sachleen
sumber
Contoh JSON yang Anda berikan tidak terlihat seperti JSON "baik", misalnya nilai numerik biasanya tidak dikutip sebagai string.
jfpoilpret
+1 untuk daftar pustaka JSON yang berpotensi dapat digunakan. Saya terkejut tidak ada perpustakaan yang didasarkan pada pendekatan fungsi callback, yang akan dipanggil selama parsing (jauh lebih efisien dari segi memori).
jfpoilpret
Setidaknya Anda sadar bahwa contoh kode Anda mengerikan :-) Tentu saja itu menyelesaikan pekerjaan, tetapi tidak dapat dibaca (oleh orang lain dan bahkan oleh Anda sendiri dalam 6 bulan) dan karenanya tidak dapat dipertahankan.
jfpoilpret
@ jfpoilpret Saya kehabisan memori pada chip jadi saya harus mengambil jalan pintas di beberapa tempat. Setidaknya itu sangat dikomentari.
sachleen
Saya mengerti; tapi saya bertanya-tanya apakah Stringpenggunaannya tidak membuat situasi memori lebih buruk (ya, Stringdi Arduino adalah kesayangan saya).
jfpoilpret
7

Saya telah memprogram kelas yang akan menerima char dengan char dokumen JSON. Ini hanya akan menyimpan dalam memori beberapa byte untuk struktur JSON yang diketahui menggunakan mesin negara dan hasil yang Anda butuhkan. Jadi, Anda dapat meminta kelas untuk hasil yang Anda inginkan dan akan memproses JSON.

Ideal untuk tujuan Anda. Saya telah menggunakan untuk menghubungkan ke layanan cuaca yang mengembalikan 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;

Periksa posting blog ini yang baru saja saya tulis: http://web.biicode.com/blog/big-json-on-arduino .

Kode sumber ada di sini di Biicode.

lasote
sumber
2

Saya menulis parser untuk PIC yang menggunakan ram sangat rendah karena ia bekerja langsung dengan pointer char dan tidak membangun struktur pohon. Jika Anda meminta untuk mendapatkan item N dari daftar, itu memberi Anda pointer aktual ke file JSON langsung tepat di awal item N dari daftar. Kemudian Anda dapat menanyakan jenis objek yang diwakili oleh pointer, dll. Ini buggy dan tidak mendukung float dan saya pikir memiliki beberapa batasan lain (sudah lama sekali) tetapi semuanya ada di github: https://github.com / EternityForest / OpenFortune-fortune-like-text-generator Anda harus mencari di libfortune yang merupakan bagian dari versi C.

EternityForest
sumber