Разбор JSON с Arduino, чтобы включить светодиод

18

Привет я пытаюсь разобрать JSON Resposne от веб-сервера в моем Arduino, чтобы включить и выключить светодиод. Я использую пример повторения клиента Wi-Fi, чтобы сделать запрос на получение моего сервера:

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

Вот что я получаю обратно из последовательного порта

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

Как мне проанализировать JSON-часть этого ответа только для того, чтобы я мог использовать его для управления своим светодиодом?

Благодарность

user1424508
источник

Ответы:

11

Мне известно о нескольких библиотеках JSON для Arduino.

Я никогда не использовал ничего из этого, но я выполнил простой анализ JSON в проекте, над которым я работаю, поэтому я покажу вам, как я это сделал.

ПРИМЕЧАНИЕ: я читаю последовательные данные, используя программную библиотеку последовательных программ Вам нужно изменить этот код, чтобы работать на вас. Это будет работать только на очень простых строках JSON. Это очень ограничено, но если это все, что вы анализируете, то это сработает.

Пример ответа JSON от сервера:

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

Во-первых, только читать данные между фигурными скобками.

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

Этот код читает данные по одному байту за раз, и как только он получает открытую скобку, он начинает сохранять их в response. Когда он получает закрывающую скобку, он заканчивает это. Итак, вот четкое ограничение: в вашей строке может быть только один набор открывающих / закрывающих скобок.

Получив строку, я использую indexOfи substringдля извлечения соответствующей информации:

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

Этот код устанавливает startначало id":"+ 5 символов в строке. Это +5, потому что так долго id":". Так startуказывает на TEST1в строке JSON. В моей системе идентификатор всегда будет длиной 5 символов, так что конец есть start + 5. Затем я использую, substringчтобы извлечь это.

Опять же, прежде чем кто-то начнет голосовать за меня за это ужасное решение: если вы точно знаете, с чем работаете, и понимаете ограничения этого кода, то это не плохое решение. Это решение, которое выполняет свою работу.

sachleen
источник
Приведенный вами пример JSON не похож на «хороший» JSON, например, числовые значения обычно не должны заключаться в кавычки в виде строк.
jfpoilpret
+1 за список потенциально используемых библиотек для JSON. Я удивлен, что ни одна библиотека не основана на подходе функции обратного вызова, который вызывался бы во время синтаксического анализа (гораздо более эффективный в отношении памяти).
jfpoilpret
По крайней мере, вы понимаете, что ваш пример кода ужасен :-) Конечно, он выполняет свою работу, но он не читается (кем-то другим, даже самим за 6 месяцев) и, следовательно, не поддерживается.
jfpoilpret
@jfpoilpret У меня недостаточно памяти на чипе, поэтому в некоторых местах пришлось срезать углы. По крайней мере, это сильно прокомментировано.
Сахлин
Я понимаю; но мне интересно, если Stringиспользование не ухудшает ситуацию с памятью (да, Stringв Arduino моя любимая мозоль).
Jfpoilpret
7

Я запрограммировал класс, который будет получать char by char документ JSON. Он сохранит в памяти только несколько байтов для известной структуры JSON, используя конечный автомат и результаты, которые вам нужны. Таким образом, вы можете запросить у класса необходимые результаты и обработать JSON.

Это идеально подходит для ваших целей. Я использовал для подключения к службе погоды, которая возвращает 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;

Посмотрите этот пост в блоге, который я только что написал: http://web.biicode.com/blog/big-json-on-arduino .

Исходный код здесь, в Biicode.

lasote
источник
2

Я написал парсер для PIC, который использует очень мало оперативной памяти, потому что он работает напрямую с указателями на символы и не создает древовидную структуру. Если вы просите получить элемент N списка, он дает вам фактический указатель на прямой файл JSON в начале элемента N списка. Затем вы можете спросить, какой тип объекта представляет указатель и т. Д. Он глючит и не поддерживает float, и я думаю, что имеет несколько других ограничений (это было давно), но все это на github: https://github.com / EternityForest / OpenFortune-fortune-like-text-generator Вам нужно взглянуть на libfortune, которая является частью C-версии.

EternityForest
источник
1

Я написал простую библиотеку JSON-RPC (поверх aJson) с примером того, как включить светодиод с помощью вызова процедуры JSON-RPC:

Меир Цейтлин
источник
2
Можете ли вы добавить больше информации в свой ответ в случае изменения ссылки на код / ​​документацию ...
sachleen