使用arduino解析JSON以打开LED


18

嗨,我正在尝试从arduino中的Web服务器解析JSON响应,以便打开和关闭LED灯。我正在使用wifi客户端重复示例向服务器发出get请求:

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部分,以便可以使用它来控制我的LED?

谢谢

Answers:


11

我知道一些Arduino的JSON解析库。

我从来没有使用过这些方法,但是我在正在研究的项目中做了一些简单的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。当它得到一个大括号时,它就结束了。因此,这是一个明显的限制,您的弦中只能有一组开/关括号。

有了字符串后,我将使用indexOfsubstring提取相关信息:

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

此代码设置startid":"字符串中+ 5个字符的开头。+5,因为那是多长时间id":"。因此start指向TEST1JSON字符串。在我的系统中,ID的长度始终为5个字符,因此end为start + 5。然后substring,我将其提取出来。

再一次,在有人开始投票赞成我这个可怕的解决方案之前:如果您确切地知道您正在使用什么,并且了解此代码的局限性,那么这并不是一个糟糕的解决方案。这是完成任务的解决方案。


您提供的JSON示例看起来不像“好” JSON,例如,通常不应将数字值引为字符串。
jfpoilpret 2014年

+1表示JSON可能可用的库列表。令我惊讶的是,没有一个库基于回调函数方法,该方法在解析期间会被调用(在内存方面效率更高)。
jfpoilpret 2014年

至少您意识到您的代码示例太可怕了:-)当然可以完成工作,但是它不可读(其他人甚至在6个月内就无法理解),因此无法维护。
jfpoilpret 2014年

@jfpoilpret我的芯片内存不足,因此我不得不在某些地方偷工减料。至少有很多评论。
sachleen 2014年

我明白; 但是我想知道String使用率是否不会使内存情况恶化(是的,String在Arduino中是我的宠儿)。
jfpoilpret 2014年

7

我编写了一个类,该类将按字符接收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

源代码是这里的比科德。


2

我为PIC编写了一个解析器,它的ram使用率非常低,因为它直接与char指针一起使用,并且不构建树结构。如果您要求获取列表的项目N,则它会在列表的项目N的开头为您提供指向直接JSON文件的实际指针。然后,您可以问指针代表什么类型的对象,等等。它有错误,不支持浮点数,我认为还有其他一些限制(很久以前是这样),但都在github上:https : //github.com / EternityForest / OpenFortune-fortune-like-text-generator 您需要查看libfortune,它是C版本的一部分。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.