声明:此文章由 AI 生成,内容不保证正确。

使用ArduinoJson库的完整指南

ArduinoJson是一个功能强大且高效的库,用于在Arduino和其他嵌入式平台上解析、生成和操作JSON数据。本文将指导您如何安装、配置和使用ArduinoJson库。


目录

  1. 安装ArduinoJson库
  2. JSON基础
  3. 创建和操作JSON对象
  4. 解析JSON数据
  5. 生成JSON数据
  6. 内存管理与优化
  7. 常见问题与解决方法
  8. 代码示例

安装ArduinoJson库

1. 使用Arduino IDE的库管理器

  1. 打开Arduino IDE。
  2. 点击菜单栏中的工具 -> 管理库
  3. 在搜索框中输入ArduinoJson
  4. 找到ArduinoJson库,点击安装按钮。

2. 手动安装

  1. ArduinoJson的GitHub仓库下载最新版本的库。
  2. 解压下载的文件。
  3. 将解压后的文件夹复制到Arduino的libraries目录中(通常位于Arduino/libraries)。
  4. 重启Arduino IDE。

JSON基础

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,广泛用于数据通信。以下是JSON的基本结构:

  • 键值对"key": "value"
  • 数组[value1, value2, value3]
  • 嵌套对象{"key": {"subkey": "subvalue"}}

示例:

1
2
3
4
5
{
"sensor": "gps",
"time": 1351824120,
"data": [48.756080, 2.302038]
}

创建和操作JSON对象

1. 创建JSON对象

使用JsonDocument类创建和操作JSON对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <ArduinoJson.h>

void setup() {
// 初始化串口
Serial.begin(9600);

// 创建一个动态JSON文档
JsonDocument doc;

// 添加键值对
doc["sensor"] = "gps";
doc["time"] = 1351824120;

// 添加数组
JsonArray data = doc.createNestedArray("data");
data.add(48.756080);
data.add(2.302038);

// 打印JSON对象
serializeJson(doc, Serial);
}

输出:

1
{"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]}

2. 修改JSON对象

可以直接通过键名修改JSON对象的值:

1
2
doc["sensor"] = "temperature";
doc["data"][0] = 25.5;

解析JSON数据

1. 从字符串解析JSON

使用deserializeJson函数解析JSON字符串。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <ArduinoJson.h>

void setup() {
Serial.begin(9600);

// 定义JSON输入字符串
String input = "{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}";

// 创建JSON文档
JsonDocument doc;

// 解析JSON字符串
DeserializationError error = deserializeJson(doc, input);

// 检查解析是否成功
if (error) {
Serial.print("解析错误: ");
Serial.println(error.c_str());
return;
}

// 提取数据
const char* sensor = doc["sensor"];
long time = doc["time"];
double latitude = doc["data"][0];
double longitude = doc["data"][1];

// 打印解析结果
Serial.println(sensor);
Serial.println(time);
Serial.println(latitude);
Serial.println(longitude);
}

生成JSON数据

1. 生成紧凑格式的JSON

使用serializeJson生成紧凑格式的JSON字符串。

1
2
3
String output;
serializeJson(doc, output);
Serial.println(output);

2. 生成美化格式的JSON

使用serializeJsonPretty生成美化格式的JSON字符串。

1
2
3
String output;
serializeJsonPretty(doc, output);
Serial.println(output);

内存管理与优化

1. 使用StaticJsonDocument

StaticJsonDocument用于分配固定大小的内存缓冲区,适合资源受限的单片机。

1
StaticJsonDocument<200> doc;  // 分配200字节的缓冲区

2. 使用serialized()优化字符串存储

使用serialized()可以避免复制字符串内容,从而减少内存使用。

1
doc["sensor"] = serialized("gps");

3. 清理内存

在完成JSON操作后,调用doc.clear()释放内存。

1
doc.clear();

常见问题与解决方法

1. 解析失败

  • 问题deserializeJson返回错误。
  • 解决方法:检查输入的JSON字符串是否格式正确,确保没有多余的逗号或缺少引号。

2. 内存不足

  • 问题:程序运行时出现内存不足错误。
  • 解决方法
    • 使用StaticJsonDocument手动分配固定大小的缓冲区。
    • 减少JSON对象的大小,移除不必要的数据。

3. StringJsonDocument的交互问题

  • 问题:使用String作为键或值时,内存使用增加。
  • 解决方法:尽量避免使用String,改用char*serialized()

参考资料


#以下是一个完整的Arduino代码示例,展示如何从串口接收JSON数据,解析其中的参数ab,并将它们保存到变量中。我们将使用ArduinoJson库来解析JSON数据。


代码示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include <ArduinoJson.h>

// 定义变量a和b
int a = 0;
int b = 0;

void setup() {
// 初始化串口
Serial.begin(9600);
while (!Serial) {
; // 等待串口初始化完成(仅适用于某些开发板)
}

Serial.println("请输入JSON数据,例如:{\"a\":10,\"b\":20}");
}

void loop() {
// 检查是否有数据可读
if (Serial.available() > 0) {
// 读取串口数据
String input = Serial.readStringUntil('\n');
input.trim(); // 去除多余的空格或换行符

// 创建JSON文档
StaticJsonDocument<200> doc; // 分配200字节的缓冲区

// 解析JSON数据
DeserializationError error = deserializeJson(doc, input);

// 检查解析是否成功
if (error) {
Serial.print("解析错误: ");
Serial.println(error.c_str());
return;
}

// 提取参数a和b
if (doc.containsKey("a") && doc.containsKey("b")) {
a = doc["a"]; // 提取参数a
b = doc["b"]; // 提取参数b

// 打印提取的值
Serial.print("成功解析: a = ");
Serial.print(a);
Serial.print(", b = ");
Serial.println(b);
} else {
Serial.println("JSON中缺少参数a或b");
}
}
}

代码解析

1. 初始化串口

1
2
3
4
Serial.begin(9600);
while (!Serial) {
; // 等待串口初始化完成(仅适用于某些开发板)
}
  • Serial.begin(9600):设置串口波特率为9600。
  • while (!Serial):等待串口初始化完成,适用于某些需要手动连接串口的开发板(如Arduino Leonardo)。

2. 定义变量

1
2
int a = 0;
int b = 0;
  • 定义两个整数变量ab,用于存储从JSON中提取的值。

3. 检查串口数据

1
2
3
4
if (Serial.available() > 0) {
String input = Serial.readStringUntil('\n');
input.trim();
}
  • Serial.available():检查串口是否有数据可读。
  • Serial.readStringUntil('\n'):读取串口数据,直到遇到换行符\n
  • input.trim():去除输入字符串中的多余空格或换行符。

4. 解析JSON数据

1
2
StaticJsonDocument<200> doc;
DeserializationError error = deserializeJson(doc, input);
  • StaticJsonDocument<200>:分配200字节的固定大小缓冲区,用于存储JSON数据。
  • deserializeJson(doc, input):解析输入的JSON字符串。

5. 检查解析结果

1
2
3
4
5
if (error) {
Serial.print("解析错误: ");
Serial.println(error.c_str());
return;
}
  • 如果解析失败,deserializeJson会返回一个错误对象。通过error.c_str()可以获取错误信息。

6. 提取参数

1
2
3
4
5
6
7
8
9
10
if (doc.containsKey("a") && doc.containsKey("b")) {
a = doc["a"];
b = doc["b"];
Serial.print("成功解析: a = ");
Serial.print(a);
Serial.print(", b = ");
Serial.println(b);
} else {
Serial.println("JSON中缺少参数a或b");
}
  • doc.containsKey("a"):检查JSON对象中是否包含键"a"
  • doc["a"]:提取键"a"对应的值。
  • 如果JSON中缺少"a""b",则输出错误信息。

运行示例

输入

通过串口监视器发送以下JSON数据:

1
{"a":10,"b":20}

输出

串口监视器将显示:

1
成功解析: a = 10, b = 20

注意事项

  1. JSON格式

    • 输入的JSON数据必须是有效的JSON格式。例如,键和值需要用双引号包裹,键值对之间用逗号分隔。
    • 示例:
      1
      {"a":10,"b":20}
  2. 内存分配

    • StaticJsonDocument<200>的大小需要根据JSON数据的复杂度调整。如果JSON数据较大,可以增加缓冲区大小,例如StaticJsonDocument<512>
  3. 错误处理

    • 如果输入的JSON格式不正确,程序会输出解析错误信息。
    • 如果JSON中缺少"a""b",程序会提示缺少参数。
  4. 串口监视器设置

    • 确保串口监视器的波特率与代码中的Serial.begin(9600)一致。
    • 在发送JSON数据时,确保末尾包含换行符\n

扩展功能

  1. 支持浮点数

    • 如果ab是浮点数,可以将变量类型改为float
      1
      2
      float a = 0.0;
      float b = 0.0;
  2. 动态JSON文档

    • 如果JSON数据大小不确定,可以使用DynamicJsonDocument
      1
      DynamicJsonDocument doc(200); // 动态分配200字节的缓冲区
  3. 处理嵌套JSON

    • 如果JSON数据包含嵌套结构,例如:
      1
      {"data":{"a":10,"b":20}}
      可以通过以下方式提取:
      1
      2
      a = doc["data"]["a"];
      b = doc["data"]["b"];

希望这个示例对您有帮助!如果有任何问题,请随时提问。