C++ Json库ArduinoJson介绍及使用说明

介绍与下载

  • ArduinoJson是一个纯由C++编写的Json库,支持大部分常用的Json数据操作;
  • ArduinoJson比较小巧(目前v6.9.1版本文件约160K左右大小),只有一个.h文件,使用时只需引用它即可;
    也可以下载zip文件,然后在Arduino IDE中选择: 项目 > 加载库 > 添加 .ZIP 库
  • 虽然小巧但官方页面一点不含糊,排版合理,资料详细,还提供了一个非常方便的工具;
  • 虽然名字里有Arduino但并非只能用在Arduino里,可以用于所有支持C++的地方;
  • ArduinoJson基于MIT开源协议,也就是说它是可以免费的;
  • 官方主页:https://arduinojson.org/
  • GitHub项目地址:https://github.com/bblanchon/ArduinoJson

下载方式可以见下图:
在这里插入图片描述

使用方法与演示

本文编写时ArduinoJson更新到v6.9.1版,这里也以v6.9.1版做说明。

反序列化(Deserialization,解析数据)

反序列化步骤如下:

  • 引用ArduinoJson库;
  • 声明JsonDocument对象;
  • 尝试反序列化json字符串到JsonDocument对象;
  • 根据需求取用数据;

使用下面代码进行测试:

#include "ArduinoJson-v6.9.1.h" //引用ArduinoJson库
// #include "ArduinoJson.h" //也可以将文件名改为ArduinoJson.h然后这样引用

//声明一个json数据
char myJson[] = "{\"myChar\":\"hello\",\"myArray\":[13,14],\"myObject\":{\"myFloat\":3.1415926}}";

void setup()
{
    Serial.begin(115200);
    Serial.println();

    StaticJsonDocument<200> doc; //声明一个JsonDocument对象
    // DynamicJsonDocument doc(200); //声明一个JsonDocument对象

    DeserializationError error = deserializeJson(doc, myJson); //反序列化JSON数据

    // if (error.c_str() == "OK") //检查反序列化是否成功
    if (!error) //检查反序列化是否成功
    {
        //读取json节点
        const char *myC = doc["myChar"]; //等同于const char *myC = doc["myChar"].as<char*>();
        int myN0 = doc["myArray"][0]; //等同于int myN0 = doc["myArray"][0].as<int>();
        int myN1 = doc["myArray"][1]; //等同于int myN1 = doc["myArray"][1].as<int>();
        float myF = doc["myObject"]["myFloat"]; //等同于float myF = doc["myObject"]["myFloat"].as<float>();

        Serial.println(myC);
        Serial.println(myN0);
        Serial.println(myN1);
        Serial.println(myF);
        // Serial.println(myF, n); //n指定输出小数位数
    }
}

void loop()
{
}

在这里插入图片描述

序列化(Serialization,创建数据)

序列化步骤如下:

  • 引用ArduinoJson库;
  • 声明JsonDocument对象;
  • JsonDocument对象中添加数据;
  • 序列化处理JsonDocument对象使成为json字符串;

使用下面代码进行测试:

#include "ArduinoJson-v6.9.1.h" //引用ArduinoJson库
// #include "ArduinoJson.h" //也可以将文件名改为ArduinoJson.h然后这样引用

void setup()
{
    Serial.begin(115200);
    Serial.println();

    StaticJsonDocument<200> doc; //声明一个JsonDocument对象
    // DynamicJsonDocument doc(200); //声明一个JsonDocument对象

    doc["myChar"] = "hello"; //添加一个字符串对象节点

    JsonArray myA = doc.createNestedArray("myArray"); //添加一个数组节点
    myA.add(true);                                    //使用add方式添加数据到JsonArray
    myA.add(false);

    JsonObject myO = doc.createNestedObject("myObject"); //添加一个对象节点
    myO["myNumber"] = 1234567890;                        //使用[]添加数据到JsonObject

    serializeJson(doc, Serial); //序列化JSON数据(压缩形式),并从Serial输出
    // 以下三行输出结果同上面一行
    // char myDoc[measureJson(doc) + 1];
    // serializeJson(doc, myDoc, measureJson(doc) + 1);
    // Serial.println(myDoc);

    Serial.println();
    Serial.println();

    serializeJsonPretty(doc, Serial); //序列化JSON数据(展开形式),并从Serial输出
    // 以下三行输出结果同上面一行
    // char myDocP[measureJsonPretty(doc) + 1];
    // serializeJsonPretty(doc, myDocP, measureJsonPretty(doc) + 1);
    // Serial.println(myDocP);
}

void loop()
{
}

在这里插入图片描述

API简单介绍

对象

JsonDocument

  • 使用StaticJsonDocument<size> doc;DynamicJsonDocument doc(size);方式声明JsonDocument对象;
  • 使用StaticJsonDocument<size> doc;方式声明的对象将存储在栈内存中,推荐size不大于1K时使用该方式;
  • 使用DynamicJsonDocument doc(size);方式声明的对象将存储在堆内存中,推荐size大于1K时使用该方式;
  • size大小可以根据JsonDocument对象含有的节点数与值和数据长度计算得出,最保险的话可以根据json字符串(压缩形式)的长度len取值,size = len (8bit)size = len*2 (32bit)size = len*4 (64bit)
  • JsonDocument对象可以是JsonArrayJsonObjectJsonVariant三类引用类型;

JsonDocument对象的部分方法如下:

  • as<T>()
    显式转换数据类型,如果类型不符合则根据类型返回0或空值;

This function returns a default value if the cast is not possible. The default value is:

  • 0 for numerical types
  • NULL for const char*
  • A null reference for JsonArray and JsonObject.
  • is<T>()
    判断是否为为某类型;
  • add()
    向数组添加数据,添加成功返回true,失败返回false;
  • clear()
    清除并释放内存;
  • createNestedArray()
    创建数组,括号中可以输入数组的键名称,创建成功则返回数组指针,失败则返回空值;
  • createNestedObject()
    创建对象,括号中可以输入对象的键名称,创建成功则返回对象指针,失败则返回空值;
  • operator[]
    返回值定的值,如果该键不存在则根据类型返回0或空值;
  • isNull()
    返回是否为空,空返回true,非空返回false;
  • to<T>()
    清空并转换为指定类型;

JsonVariant

JsonVariant是JsonDocument的引用类型,可以表示任何json支持的数据类型,拥有的方法大部分和JsonDocument相同,下面是部分新增的方法:

  • set()
    设置对象的值,设置成功返回ture,失败返回false;
  • 重载了运算符==!=<<=>>=

引用类型在参数传递使用时拥有更好的性能(毕竟只是引用而已),可以参考下面代码:

#include "ArduinoJson-v6.9.1.h" //引用ArduinoJson库

//声明一个json数据
char myJson[] = "{\"myChar\":\"hello\",\"myArray\":[13,14],\"myObject\":{\"myFloat\":3.1415926}}";

void parmPass(JsonVariant parm)
{
    const char *myC = parm["myChar"];
    int myN0 = parm["myArray"][0];
    int myN1 = parm["myArray"][1];
    float myF = parm["myObject"]["myFloat"];

    Serial.println(myC);
    Serial.println(myN0);
    Serial.println(myN1);
    Serial.println(myF);
}

void setup()
{
    Serial.begin(115200);
    Serial.println();

    StaticJsonDocument<200> doc; //声明一个JsonDocument对象
    DeserializationError error = deserializeJson(doc, myJson); //反序列化JSON数据
    if (!error) //检查反序列化是否成功
    {
        parmPass(doc.as<JsonVariant>()); //将参数传递后打印输出
    }
}

void loop()
{
}

JsonObject

JsonObject使用基本同JsonVariant,部分方法如下:

  • containsKey()
    测试对象中是否存在某个键,输入参数为键名称,如果存在返回true,不存在返回false;
  • remove()
    移除某个键值对,输入参数为键名称,如果该键值对不存在则不进行操作;
  • size()
    返回对象所包含键值对数量;
  • 没有add()方法;

JsonArray

JsonArray使用基本同JsonObject,部分不同如下;

  • 没有containsKey()方法;
  • add()方法;

序列化与反序列化

  • deserializeJson()
    该方法可以反序列化数据(将字符串解析为json);
    输入参数分别为JsonDocument对象、原始字符串、字符串长度(可选),嵌套深度(可选);
    返回DeserializationError类型错误,取值分别为:
    Ok序列化成功;
    IncompleteInput输入不完整;
    InvalidInput输入无效;
    NoMemoryJsonDocument对象空间不足;
    NotSupported出现不支持的数据类型;
    TooDeep嵌套层数太深;

  • serializeJson()
    该方法可以序列化数据(将JsonDocument对象转换为字符串,压缩形式);
    输入参数分别为JsonDocument对象、目标字符串(或者print到某接口)、字符串长度(可选);
    返回写入字节数;

  • serializeJsonPretty()
    该方法可以序列化数据(将JsonDocument对象转换为字符串,展开形式,其他同上);

  • measureJson()
    计算serializeJson()生成文档大小,不包含停止符;

  • measureJsonPretty()
    计算serializeJsonPretty()生成文档大小,不包含停止符;

其它

  • json最大嵌套层数
    ArduinoJson库中定义了ARDUINOJSON_DEFAULT_NESTING_LIMIT,该参数表示json最大嵌套层数,可以在库文件中更改该值以改变全局最大嵌套层数;
    也可以使用下面方法临时改变最大嵌套层数:
deserializeJson(doc, input, DeserializationOption::NestingLimit(20));
  • ArduinoJson库版本
    ArduinoJson库中定义了版本信息,相关定义如下:
#define ARDUINOJSON_VERSION "6.9.1"
#define ARDUINOJSON_VERSION_MAJOR 6
#define ARDUINOJSON_VERSION_MINOR 9
#define ARDUINOJSON_VERSION_REVISION 1

使用ArduinoJson助手生成代码

ArduinoJson使用太麻烦?JsonDocument该取多大不清楚?没关系使用ArduinoJson Assistant完美解决上述问题,自动生成代码,复制即可使用:
在这里插入图片描述

其他说明

  • ArduinoJson v6.7开始JsonDocument必须指定大小,如果想要使用动态长度的话请自行参考使用v6.7以前版本;
  • 字符串使用char[]形式很多时候可以提供更好的性能,因为JsonDocument在处理该类型时只引用它,而在使用其他类型时会将内容拷贝至JsonDocument;

总结

ArduinoJson的介绍与使用主要就是上面那些了,更加详细的内容可以参考官网Documentation页中各项内容。

  • 96
    点赞
  • 183
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Naisu Xu

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

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

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

打赏作者

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

抵扣说明:

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

余额充值