Arduino网络编程实战-JSON数据解析与序列化

JSON数据解析与序列化

JSON(JavaScript Object Notation)是一种开放的标准文件格式和数据交换格式,它使用人类可读的文本来存储和传输由属性-值对和数组(或其他可序列化值)组成的数据对象。 它是一种常见的数据格式,在电子数据交换中具有多种用途,包括带有服务器的 Web 应用程序。

JSON 是一种独立于语言的数据格式。 它源自 JavaScript,但许多现代编程语言都包含生成和解析 JSON 格式数据的代码。 JSON 文件名使用扩展名 .json。当数据从服务器发送到网页时,通常使用 JSON。JSON是“自我描述的”并且易于理解。

ArduinoJson库为嵌入式系统提供了高性能的JSON数据序列化和反序列化支持

1、JSON文档对象创建

ArduinoJson 使用固定的内存分配,允许在 RAM 很少的设备上工作。

1)将数据存储在Stack中

1
2
StaticJsonDocument<256> doc;

2)将数据储存在Heap中

1
2
DynamicJsonDocument doc(2048);

2、序列化

ArduinoJson 原生支持多种输出类型:

1)串口输出

1
2
3
4
5
6
7
8
9
10
11
12
13
// 动态JSON文档对象
DynamicJsonDocument doc(1024);

doc["sensor"] = "gps";
doc["time"] = 1351824120;
doc["data"][0] = 48.756080;
doc["data"][1] = 2.302038;

// 将文档序列化到串口输出
serializeJson(doc, Serial);
// This prints:
// {"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]}

2)输出到以太网连接

1
2
serializeJson(doc, ethernetClient);

3)WiFi连接

1
2
serializeJson(doc, wifiClient);

4)自定义输出

要使用不受支持的输出类型,您必须从 Print 或 std::ostream 派生一个类; 再次,重量级的解决方案。 在这里,ArduinoJson 6.13.0 也允许使用自定义类来调整库的输出类型。

与自定义阅读器类一样,自定义编写器类不需要继承任何东西; 它只需要实现两个功能。 如下所示:

1
2
3
4
5
6
7
struct CustomWriter {
// Writes one byte, returns the number of bytes written (0 or 1)
size\_t write(uint8\_t c);
// Writes several bytes, returns the number of bytes written
size\_t write(const uint8\_t \*buffer, size\_t length);
};

结构签名模仿了 Arduino Print 类的虚函数。 同样,它们不需要是虚拟的,因为 ArduinoJson 在编译时解析名称。

可以将此类的实例传递给序列化函数:

3、反序列化(解析)

ArduinoJson 原生支持多种输入类型:

同时,ArduinoJson库也支持从自定Reader读取数据解析。

1)从字符串解析

1
2
3
4
5
6
7
8
9
10
11
char json[] = "{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}";

DynamicJsonDocument doc(1024);
// 反序列化
deserializeJson(doc, json);

const char\* sensor = doc["sensor"];
long time = doc["time"];
double latitude = doc["data"][0];
double longitude = doc["data"][1];

2)从串口输入中解析

1
2
deserializeJson(doc, Serial);

3)从以太网连接中解析

1
2
deserializeJson(doc, ethernetClient);

4)从WiFi连接中解析

1
2
deserializeJson(doc, wifiClient);

5)从自定义Reader中解析

ArduinoJson 6.13.0 提供了一个轻量级的解决方案:自定义阅读器类。 这个类不必继承任何东西; 它只需要实现两个具有正确签名的成员函数。如下所示:

1
2
3
4
5
6
7
struct CustomReader {
// Reads one byte, or returns -1
int read();
// Reads several bytes, returns the number of bytes read.
size\_t readBytes(char\* buffer, size\_t length);
};

这两个函数的灵感来自 Arduino 的 Stream 类中的虚函数。 然而,在这种情况下,函数不需要是虚拟的,因为 ArduinoJson 使用静态调度来调用它们。

因此可以将此类的实例传递给反序列化函数:

4、数据读取与设置

ArduinoJSON支持真观的数据读取与设置:

1)数据读取

1
2
3
const char\* city = doc["city"];
double temp = doc["weather"]["temp"];

2)数据设置

1
2
3
doc["city"] = "Paris";
doc["weather"]["temp"] = 21.2;

文章来源: https://iotsmart.blog.csdn.net/article/details/122905165