Phân tích JSON với arduino để bật đèn LED


18

Xin chào, tôi đang cố phân tích cú pháp JSON từ máy chủ web trong arduino của mình để bật và tắt đèn LED. Tôi đang sử dụng ví dụ lặp lại ứng dụng khách wifi để thực hiện yêu cầu nhận đến máy chủ của mình:

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

Đây là những gì tôi nhận được in lại từ cổng nối tiếp

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

Làm cách nào để phân tích phần JSON của phản hồi này để tôi có thể sử dụng nó để điều khiển đèn LED của mình?

Cảm ơn

Câu trả lời:


11

Tôi biết một vài thư viện phân tích cú pháp JSON cho Arduino.

Tôi chưa bao giờ sử dụng bất kỳ thứ nào trong số này nhưng tôi đã thực hiện một số phân tích cú pháp JSON đơn giản trong một dự án tôi đang thực hiện vì vậy tôi sẽ chỉ cho bạn cách tôi đã làm điều đó.

LƯU Ý: Tôi đang đọc dữ liệu nối tiếp bằng thư viện nối tiếp phần mềm. Bạn sẽ cần thay đổi mã này để làm việc cho bạn. Điều này sẽ chỉ hoạt động trên các chuỗi JSON rất đơn giản. Nó rất hạn chế nhưng nếu đó là tất cả những gì bạn đang phân tích thì nó sẽ hoạt động.

Ví dụ về phản hồi JSON từ máy chủ:

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

Đầu tiên, chỉ đọc dữ liệu giữa các dấu ngoặc nhọn.

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

Mã này đọc dữ liệu một byte mỗi lần và một khi nó có được một dấu ngoặc mở, nó bắt đầu lưu nó vào response. Khi nó có được một cú đúp kết thúc, nó kết thúc nó. Vì vậy, đây là một giới hạn rõ ràng, bạn chỉ có thể có một bộ dấu ngoặc đóng / mở trong chuỗi của mình.

Khi tôi có chuỗi, tôi sử dụng indexOfsubstringtrích xuất thông tin liên quan:

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

Mã này đặt startở đầu id":"+ 5 ký tự trong chuỗi. Đó là +5 vì đó là bao lâu id":". Vì vậy, starttrỏ đến TEST1trong chuỗi JSON. Trong hệ thống của tôi, ID luôn dài 5 ký tự nên cuối cùng là vậy start + 5. Sau đó tôi sử dụng substringđể giải nén điều đó.

Một lần nữa, trước khi bất cứ ai bắt đầu bỏ phiếu cho tôi về giải pháp khủng khiếp này: nếu bạn biết chính xác những gì bạn đang làm việc và hiểu những hạn chế của mã này, thì đây không phải là một giải pháp tồi. Đó là một giải pháp hoàn thành công việc.


Ví dụ JSON mà bạn đưa ra không giống như JSON "tốt", ví dụ: các giá trị số thường không được trích dẫn dưới dạng chuỗi.
jfpoilpret

+1 cho danh sách các thư viện có khả năng sử dụng cho JSON. Tôi ngạc nhiên không có thư viện dựa trên cách tiếp cận chức năng gọi lại, nó sẽ được gọi trong quá trình phân tích cú pháp (bộ nhớ hiệu quả hơn nhiều).
jfpoilpret

Ít nhất bạn có ý thức rằng mẫu mã của bạn thật kinh khủng :-) Tất nhiên nó hoàn thành công việc, nhưng nó không thể đọc được (bởi người khác thậm chí là chính bạn trong 6 tháng) và do đó không thể duy trì được.
jfpoilpret

@jfpoilpret Tôi hết bộ nhớ trên chip nên tôi phải cắt góc ở một số nơi. Ít nhất là nó nhận xét rất nhiều.
sachleen

Tôi hiểu; nhưng tôi tự hỏi nếu Stringviệc sử dụng không làm cho tình trạng bộ nhớ tồi tệ hơn (vâng, Stringtrong Arduino là tiểu thư thú cưng của tôi).
jfpoilpret

7

Tôi đã lập trình một lớp sẽ nhận char bằng tài liệu JSON. Nó chỉ lưu trữ trong bộ nhớ một vài byte cho cấu trúc JSON đã biết bằng cách sử dụng máy trạng thái và kết quả bạn cần. Vì vậy, bạn có thể truy vấn lớp cho kết quả bạn muốn và sẽ xử lý JSON.

Lý tưởng của nó cho mục đích của bạn. Tôi đã sử dụng để kết nối với dịch vụ thời tiết trả về 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;

Kiểm tra bài đăng trên blog này tôi vừa viết: http://web.biicode.com/blog/big-json-on-arduino .

Mã nguồn ở đây trong Biicode.


2

Tôi đã viết một trình phân tích cú pháp cho PIC có mức sử dụng ram rất thấp vì nó hoạt động trực tiếp với các con trỏ char và không xây dựng cấu trúc cây. Nếu bạn yêu cầu lấy mục N của danh sách, nó sẽ cung cấp cho bạn một con trỏ thực vào tệp JSON trực tiếp ngay khi bắt đầu mục N của danh sách. Sau đó, bạn có thể hỏi con trỏ đại diện cho loại đối tượng nào, v.v ... Đó là lỗi và không hỗ trợ nổi và tôi nghĩ có một vài hạn chế khác (cách đây một thời gian dài) nhưng tất cả đều có trên github: https://github.com / EternityForest / OpenFortune-fortune-like-text-Generator Bạn sẽ cần xem xét sự bất hạnh là một phần của phiên bản C.


1

Tôi đã viết một thư viện JSON-RPC đơn giản (trên đầu aJson) với ví dụ về cách bật đèn led với lệnh gọi thủ tục JSON-RPC:


2
Bạn có thể thêm một số thông tin vào câu trả lời của mình trong trường hợp liên kết đến mã / tài liệu thay đổi ...
sachleen 16/07/14
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.