【ESP32_8266_WiFi (十)】JSON解析

JSON解析

解析JSON格式信息是一个较为繁琐的工作,因此我们将借助解析Arduino – ESP8266平台中解析JSON格式信息的第三方库——ArduionJson库。该库是目前最受好评的解析JSON信息第三方库。其基本信息如下:

作者:BENOIT BLANCHON
官网:https://arduinojson.org/
GitHub: https://github.com/bblanchon/ArduinoJson
下载地址:太极创客网站下载页Arduino / ESP8266-NodeMCU第三方库下载部分


1 单一对象JSON解析

在以下示例中,您将会看到如何使用ESP8266配合ArduinoJson库来解析只有一个对象的简单JSON信息。该信息如下:

{
  "name": "taichi-maker",
  "number": 1
}

以下是该示例程序

/**********************************************************************
项目名称/Project          : 零基础入门学用物联网
程序名称/Program name     : arduinojosn_1_object
团队/Team                : 太极创客团队 / Taichi-Maker (www.taichi-maker.com)
作者/Author              : CYNO朔
日期/Date(YYYYMMDD)     : 20200424
程序目的/Purpose          : 
此程序用于演示如何使用arduinojson库解析以下json信息。该json包含一个对象,
对象中有一个数据。
{
  "name": "taichi-maker",
  "number": 1
}
-----------------------------------------------------------------------
本示例程序为太极创客团队制作的《零基础入门学用物联网》中示例程序。
该教程为对物联网开发感兴趣的朋友所设计和制作。如需了解更多该教程的信息,请参考以下网页:
http://www.taichi-maker.com/homepage/esp8266-nodemcu-iot/
***********************************************************************/
#include <ArduinoJson.h>
 
void setup() {
  Serial.begin(9600);
  Serial.println("");
 
  // 重点1:DynamicJsonDocument对象
  const size_t capacity = JSON_OBJECT_SIZE(2) + 30;
  DynamicJsonDocument doc(capacity);
 
  // 重点2:即将解析的json文件
  String json = "{\"name\":\"taichi-maker\",\"number\":1}";
  
  // 重点3:反序列化数据
  deserializeJson(doc, json);
 
  // 重点4:获取解析后的数据信息
  String nameStr = doc["name"].as<String>();
  int numberInt = doc["number"].as<int>();
 
  // 通过串口监视器输出解析后的数据信息
  Serial.print("nameStr = ");Serial.println(nameStr);
  Serial.print("numberInt = ");Serial.println(numberInt);
}
 
void loop() {}

语句讲解
重点1:

const size_t capacity = JSON_OBJECT_SIZE(2) + 30;
DynamicJsonDocument doc(capacity);

这里我们建立了DynamicJsonDocument对象,该对象名称为doc。在建立该对象时需要提供一个参数,也就是括号中的参数capacity。这个capacity参数的作用是告诉ESP8266我们所建立的DynamicJsonDocument对象将要占用多大的内存空间。这个空间大小是由语句const size_t capacity = JSON_OBJECT_SIZE(2) + 30;计算出来的。在这里我们回顾一下需要解析的JSON信息内容如下所示:

{
  "name": "taichi-maker",
  "number": 1
}

我们可以看到,以上JSON信息中包含一个对象,该对象含有两个数据。因此在计算DynamicJsonDocument对象占用空间大小时,使用了JSON_OBJECT_SIZE(2)这条指令。其中指令括号中的2即代表对象包含有两个数据。

我们再看一个例子,假设我们即将解析的JSON如下:

{
  "name": "taichi-maker",
  "url": "www.taichi-maker.com",
  "number": 1
}

以上JSON对象中包含有3个数据。在计算解析它所需要占用的内存大小时,我们将要使用语句:const size_t capacity = JSON_OBJECT_SIZE(3) + 60;

讲到这里可能细心的朋友已经发现了,在以上语句中除了JSON_OBJECT_SIZE指令以外还使用+ 60来额外增加数值。这些额外增加的数值是由于ArduinoJson库在解析信息时,需要额外的空间来复制JSON信息。但是具体这个额外增加的数值是多少呢,请您先把这个问题留在心里,后面我们会给您做讲解。


重点2:

String json = "{\"name\":\"taichi-maker\",\"number\":1}";

这条语句的作用是建立字符串变量,改变里用于存储需要解析的JSON信息。


重点3:

deserializeJson(doc, json);

这部分语句的作用是使用deserializeJson来对JSON文件进行解析。其中第一个参数是我们重点1讲解的DynamicJsonDocument对象,第二个参数是重点2讲解的json字符串


重点4:

String nameStr = doc["name"].as();
int numberInt = doc["number"].as();

这两条语句用于获取解析后的JSON信息,其中doc["name"].as将会返回“name”的值。这条语句中.as将会让“name”的值以字符串的形式返回。
另一条语句中doc["number"].as()自然就是以整数形式来返回”number”的数据值。


2 JSON数组解析

以下示例演示了如何使用ArduinoJson库解析一个JSON数组信息。该信息如下:

[
  {
    "name": "taichi-maker"
  },
  {
    "website": "www.taichi-maker.com"
  }
]

以下是示例程序内容

/**********************************************************************
项目名称/Project          : 零基础入门学用物联网
程序名称/Program name     : arduinojosn_2_array
团队/Team                : 太极创客团队 / Taichi-Maker (www.taichi-maker.com)
作者/Author              : CYNO朔
日期/Date(YYYYMMDD)     : 20200424
程序目的/Purpose          : 
此程序用于演示如何使用arduinojson库解析以下json信息,该json包含一个数组,
数组有两个元素,每个元素都是一个对象,每一个对象都有一个数据。
[
  {
    "name": "taichi-maker"
  },
  {
    "website": "www.taichi-maker.com"
  }
]
-----------------------------------------------------------------------
本示例程序为太极创客团队制作的《零基础入门学用物联网》中示例程序。
该教程为对物联网开发感兴趣的朋友所设计和制作。如需了解更多该教程的信息,请参考以下网页:
http://www.taichi-maker.com/homepage/esp8266-nodemcu-iot/
***********************************************************************/
#include <ArduinoJson.h>
 
void setup() {
  Serial.begin(9600);
 
  // 重点1:DynamicJsonDocument对象
  const size_t capacity = JSON_ARRAY_SIZE(2) + 2*JSON_OBJECT_SIZE(1) + 60;
  DynamicJsonDocument doc(capacity);
  
  // 重点2:即将解析的json文件
  String json = "[{\"name\":\"taichi-maker\"},{\"website\":\"www.taichi-maker.com\"}]";
 
  // 重点3:反序列化数据
  deserializeJson(doc, json);
 
 
  String nameStr = doc[0]["name"].as<String>();
  String websiteStr = doc[1]["website"].as<String>();
 
  // 通过串口监视器输出解析后的数据信息
  Serial.print("nameStr = ");Serial.println(nameStr);
  Serial.print("websiteStr = ");Serial.println(websiteStr);
}
 
void loop() {}

语句讲解
重点1:

DynamicJsonDocument doc(capacity);

与以上示例相同,这里我们建立了DynamicJsonDocument对象,该对象名称为doc。doc对象的capacity参数用于设置解析JSON所需要的内存大小。这个空间大小是由语句const size_t capacity = JSON_ARRAY_SIZE(2) + 2*JSON_OBJECT_SIZE(1) + 60;计算出来的。在这里我们同样回顾一下需要解析的JSON信息内容:

[
  {
    "name": "taichi-maker"
  },
  {
    "website": "www.taichi-maker.com"
  }

我们可以看到,以上JSON信息是一个数组,该数组含有两个元素。因此,我们在计算capacity时首先使用了语句JSON_ARRAY_SIZE(2)来获得含有两个元素的数组所占用内存的大小。

另外,这两个数组元素都是含有一个数据的对象。因此,我们在计算capacity时使用了语句2*JSON_OBJECT_SIZE(1)。其中JSON_OBJECT_SIZE(1)可以获得含有一个数据的对象大小,我们将它乘以2是因为这里有两个含有一个数据的对象。

在计算capacity的时候,我们还在计算的最后增加60。这么做是由于ArduinoJson库在解析信息时,需要额外的空间来复制JSON信息。

计算capacity可以使用ArduinoJson官网的在线工具。您可以点击这里打开该工具页面。如您需要了解该工具的具体使用方法,欢迎您收看太极创客团队制作的《零基础入门学用物联网》教程,您可以点击这里打开具体介绍该工具使用方法的教程页面


重点2:

String json = "[{\"name\":\"taichi-maker\"},{\"website\":\"www.taichi-maker.com\"}]";

这条语句的作用是建立字符串变量,改变里用于存储需要解析的JSON信息。


重点3:

deserializeJson(doc, json);

这部分语句的作用是使用deserializeJson来对JSON文件进行解析。其中第一个参数是我们重点1讲解的DynamicJsonDocument对象,第二个参数是重点2讲解的json字符串


3 使用ArduinoJson官网在线工具解析JSON信息

ArduinoJson官网提供了在线工具可帮助我们自动生成JSON解析代码。该工具网址如下:
https://arduinojson.org/v6/assistant/

如需了解如何使用ArduinoJson官网在线工具来自动生成解析代码,请参考《零基础入门学用物联网教程》的基础知识篇中3-4 ESP8266-NodeMCU网络客户端部分的视频教程讲解。

以下是借助ArduinoJson官网在线工具生成的JSON解析代码。

/**********************************************************************
项目名称/Project          : 零基础入门学用物联网
程序名称/Program name     : arduinojson_3_assistant_demo
团队/Team                : 太极创客团队 / Taichi-Maker (www.taichi-maker.com)
作者/Author              : CYNO朔
日期/Date(YYYYMMDD)     : 20200514
程序目的/Purpose          : 
本实例用于演示如何使用ArduinoJson Assistant在线工具生成JSON解析代码。
 
步骤详解:
1. 使用Serial.begin指令启动串口通讯(此操作用于通过串口监视器检查解析结果)
2. 将需要解析的JSON数据文件复制粘贴到ArduinoJson Assistant在线工具
   https://arduinojson.org/v6/assistant/
3. 将Parsing代码复制粘贴到IDE中
4. 从Parsing代码中找到需要解析的数据所对应的const char*
5. 利用as函数需要解析的数据const char*转换为需要的格式
6. 为了代码精简,可删除无需解析的数据所对应的parsing代码部分
 
此代码解析的JSON:
{
  "results": [
    {
      "location": {
        "name": "Beijing",
        "country": "CN"
      },
      "now": {
        "text": "Clear",
        "code": "1",
        "temperature": "3"
      },
      "last_update": "2020-03-01T20:10:00+08:00"
    }
  ]
}
***********************************************************************/
#include <ArduinoJson.h>
void setup() {
  Serial.begin(9600);
  const size_t capacity = JSON_ARRAY_SIZE(1) + JSON_OBJECT_SIZE(1) + JSON_OBJECT_SIZE(2) + 2*JSON_OBJECT_SIZE(3) + 130;
  DynamicJsonDocument doc(capacity);
  
  const char* json = "{\"results\":[{\"location\":{\"name\":\"Beijing\",\"country\":\"CN\"},\"now\":{\"text\":\"Clear\",\"code\":\"1\",\"temperature\":\"3\"},\"last_update\":\"2020-03-01T20:10:00+08:00\"}]}";
  
  deserializeJson(doc, json);
  
  JsonObject results_0 = doc["results"][0];
  
  const char* results_0_location_name = results_0["location"]["name"]; // "Beijing"
  const char* results_0_location_country = results_0["location"]["country"]; // "CN"
  
  JsonObject results_0_now = results_0["now"];
  const char* results_0_now_text = results_0_now["text"]; // "Clear"
  const char* results_0_now_code = results_0_now["code"]; // "1"
  const char* results_0_now_temperature = results_0_now["temperature"]; // "3"
  
  const char* results_0_last_update = results_0["last_update"]; // "2020-03-01T20:10:00+08:00"  
 
  String location_name_String = results_0["location"]["name"].as<String>();
  int now_temperature_int = results_0_now["temperature"].as<int>();
 
  Serial.println(location_name_String);
  Serial.println(now_temperature_int);
}
 
void loop() {
}

4 ESP8266闪存存储的JSON解析

我们在开发物联网项目时,可能需要ESP8266解析比较大型的JSON信息。如果这些大型JSON信息存储再程序中,将会占用大量系统动态内存,严重的甚至会出现系统控制程序空间不足问题。因此,我们需要将大型JSON文件存储在ESP8266的闪存系统中。以下示例程序演示如何使用ESP8266读取并且解析存储在闪存中的JSON。

在测试以下示例程序前,请首先将以下zip文件下载并且解压缩。解压缩后您将会得到一个JSON文件,该文件含有ESP8266连接WiFi的信息。请根据您的WiFi环境进行相应调整再将文件上传到ESP8266的闪存根目录下。

如果您不清楚如何实现这一操作,请参考《零基础入门学用物联网》教程的ESP8266 NodeMCU 闪存文件系统(SPIFFS)部分。

接下来请将以下示例程序上传给ESP8266。程序上传后,ESP8266将会尝试从SPIFFS闪存文件系统中读取连接WiFi所需要的JSON文件,并且对该文件进行解析然后将解析后的WiFi连接信息应用于程序中,从而实现ESP8266的联网操作。

/**********************************************************************
项目名称/Project          : 零基础入门学用物联网
程序名称/Program name     : arduinojson_spiffs_parse
团队/Team                : 太极创客团队 / Taichi-Maker (www.taichi-maker.com)
作者/Author              : CYNO朔
日期/Date(YYYYMMDD)     : 20200303
程序目的/Purpose          : 
演示如何利用arduinojson库分析SPIFFS系统中的config.json文件内容。
 
在测试以下示例程序前,请首先将以下zip文件下载并且解压缩。
解压缩后您将会得到一个JSON文件,该文件含有ESP8266连接WiFi的信息。
请根据您的WiFi环境进行相应调整再将文件上传到ESP8266的闪存根目录下。
 
http://www.taichi-maker.com/wp-content/uploads/2020/04/config.zip
 
ESP8266将会尝试从SPIFFS闪存文件系统中读取连接WiFi所需要的JSON文件,
并且对该文件进行解析然后将解析后的WiFi连接信息应用于程序中,从而实现ESP8266的联网操作。
 
如果您不清楚如何实现这一操作,请参考《零基础入门学用物联网》教程的ESP8266 NodeMCU 闪存文件系统(SPIFFS)</a>部分。
http://www.taichi-maker.com/homepage/esp8266-nodemcu-iot/iot-c/spiffs/
***********************************************************************/
#include <ArduinoJson.h>
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <FS.h>  
 
// 建立ESP8266WiFiMulti对象
ESP8266WiFiMulti wifiMulti;   
        
void setup(){
  Serial.begin(9600);          
  Serial.println("");
  
  // 启动闪存文件系统
  if(SPIFFS.begin()){                      
    Serial.println("SPIFFS Started.");
  } else {
    Serial.println("SPIFFS Failed to Start.");
  }
 
  // 建立DynamicJsonDocument对象
  const size_t capacity = JSON_OBJECT_SIZE(1) + JSON_OBJECT_SIZE(2) + 60;
  DynamicJsonDocument doc(capacity);
 
  // 从闪存文件系统中读取即将解析的json文件
  File file = SPIFFS.open("/config.json", "r"); 
 
  // 反序列化数据
  deserializeJson(doc, file);
 
  // 获取解析后的数据信息
  const char* wifi_ssid = doc["wifi"]["ssid"]; // "taichimaker"
  const char* wifi_password = doc["wifi"]["password"]; // "12345678"
 
  // 尝试联网
  wifiMulti.addAP(wifi_ssid, wifi_password);
  wifiMulti.addAP("ssid_from_AP_2", "your_password_for_AP_2"); 
  wifiMulti.addAP("ssid_from_AP_3", "your_password_for_AP_3");
  Serial.println("Connecting ..."); 
 
  int i = 0;  
  while (wifiMulti.run() != WL_CONNECTED) { // 尝试进行wifi连接。
    delay(1000);
    Serial.print(i++); Serial.print(' ');
  }
  
  // WiFi连接成功后将通过串口监视器输出连接成功信息 
  Serial.println("");
  Serial.print("Connected to ");
  Serial.println(WiFi.SSID());              // WiFi名称
  Serial.print("IP address:\t");
  Serial.println(WiFi.localIP());           // IP
}
 
void loop(){}

内容来自 -----> 太极创客
详情可见太极创客官网,内有Arduino、ESP32等详细教程
http://www.taichi-maker.com

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Eiker_3169

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值