本文作者:icy

ArduinoJson:轻量高效的C++ JSON库

icy 昨天 17 抢沙发
ArduinoJson:轻量高效的C++ JSON库摘要: ArduinoJson:轻量高效的C++ JSON库 项目概述 ArduinoJson 是一个专门为嵌入式系统和物联网设备设计的轻量级JSON库,由Benoît Blanchon开...

ArduinoJson:轻量高效的C++ JSON库

ArduinoJson:轻量高效的C++ JSON库

项目概述

ArduinoJson 是一个专门为嵌入式系统和物联网设备设计的轻量级JSON库,由Benoît Blanchon开发维护。虽然名字中包含”Arduino”,但这个库实际上支持多种平台,包括ESP8266、ESP32、STM32等嵌入式系统,甚至可以在标准的C++项目中使用。

核心特性

1. 内存效率极高

  • 支持静态内存分配,避免动态内存碎片
  • 可配置的缓冲区大小,适应资源受限环境
  • 零动态内存分配选项

2. 易于使用

  • 直观的API设计,类似现代C++的语法
  • 完整的文档和丰富的示例
  • 支持流式API和DOM两种解析方式

3. 跨平台兼容

  • 支持Arduino所有版本
  • 兼容C++11及以上标准
  • 无外部依赖

安装方式

Arduino IDE

  1. 打开Arduino IDE
  2. 转到 工具 → 管理库
  3. 搜索”ArduinoJson”
  4. 点击安装

PlatformIO

text
lib_deps = 
    bblanchon/ArduinoJson@^6.21.0

手动安装

从GitHub下载源码,复制到项目目录中。

基础使用示例

示例1:解析JSON数据

text
#include <ArduinoJson.h>

void parseJsonExample() {
    const char* json = "{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}";
    
    StaticJsonDocument<200> doc;
    DeserializationError error = deserializeJson(doc, json);
    
    if (error) {
        Serial.print("解析失败: ");
        Serial.println(error.c_str());
        return;
    }
    
    const char* sensor = doc["sensor"];
    long time = doc["time"];
    float latitude = doc["data"][0];
    float longitude = doc["data"][1];
    
    Serial.print("传感器: ");
    Serial.println(sensor);
    Serial.print("时间: ");
    Serial.println(time);
    Serial.print("位置: ");
    Serial.print(latitude, 6);
    Serial.print(", ");
    Serial.println(longitude, 6);
}

示例2:生成JSON数据

text
#include <ArduinoJson.h>

void createJsonExample() {
    StaticJsonDocument<200> doc;
    
    doc["device"] = "ESP32";
    doc["status"] = "online";
    doc["temperature"] = 25.5;
    doc["humidity"] = 60;
    
    JsonArray data = doc.createNestedArray("sensors");
    data.add("DHT22");
    data.add("BMP280");
    data.add("MQ135");
    
    serializeJson(doc, Serial);
    // 输出: {"device":"ESP32","status":"online","temperature":25.5,"humidity":60,"sensors":["DHT22","BMP280","MQ135"]}
}

示例3:HTTP API客户端

text
#include <ArduinoJson.h>
#include <WiFi.h>
#include <HTTPClient.h>

void fetchWeatherData() {
    HTTPClient http;
    http.begin("http://api.openweathermap.org/data/2.5/weather?q=London&appid=YOUR_API_KEY");
    
    int httpCode = http.GET();
    
    if (httpCode == HTTP_CODE_OK) {
        String payload = http.getString();
        
        DynamicJsonDocument doc(1024);
        deserializeJson(doc, payload);
        
        float temp = doc["main"]["temp"];
        int humidity = doc["main"]["humidity"];
        const char* description = doc["weather"][0]["description"];
        
        Serial.print("温度: ");
        Serial.println(temp);
        Serial.print("湿度: ");
        Serial.println(humidity);
        Serial.print("天气: ");
        Serial.println(description);
    }
    
    http.end();
}

示例4:配置文件管理

text
#include <ArduinoJson.h>
#include <SPIFFS.h>

bool loadConfig() {
    File configFile = SPIFFS.open("/config.json", "r");
    if (!configFile) {
        return false;
    }
    
    size_t size = configFile.size();
    std::unique_ptr<char[]> buf(new char[size]);
    configFile.readBytes(buf.get(), size);
    
    StaticJsonDocument<512> doc;
    DeserializationError error = deserializeJson(doc, buf.get());
    
    if (error) {
        return false;
    }
    
    const char* ssid = doc["wifi"]["ssid"];
    const char* password = doc["wifi"]["password"];
    int port = doc["server"]["port"];
    
    // 使用配置...
    return true;
}

bool saveConfig() {
    StaticJsonDocument<512> doc;
    
    doc["wifi"]["ssid"] = "MyNetwork";
    doc["wifi"]["password"] = "MyPassword";
    doc["server"]["port"] = 8080;
    doc["device"]["name"] = "LivingRoomSensor";
    
    File configFile = SPIFFS.open("/config.json", "w");
    if (!configFile) {
        return false;
    }
    
    serializeJson(doc, configFile);
    configFile.close();
    
    return true;
}

内存管理技巧

静态内存分配

text
// 预先分配固定大小的缓冲区
StaticJsonDocument<256> doc;

动态内存分配

text
// 根据JSON大小动态分配
DynamicJsonDocument doc(1024);

估算缓冲区大小

text
// 使用助手函数估算所需大小
const size_t capacity = JSON_OBJECT_SIZE(3) + JSON_ARRAY_SIZE(2) + 60;
StaticJsonDocument<capacity> doc;

性能优化建议

  1. 选择合适的文档类型

    • 小文档使用 StaticJsonDocument
    • 大文档或不确定大小时使用 DynamicJsonDocument
  2. 重用文档对象

    text
    StaticJsonDocument<200> doc;
    // 重复使用同一个文档对象
    
  3. 使用流式解析

    text
    WiFiClient client;
    JsonDocument doc;
    deserializeJson(doc, client);
    

常见问题解决

问题1:缓冲区不足

症状:解析失败,返回 NoMemory 错误 解决:增加缓冲区大小或使用动态分配

问题2:JSON格式错误

症状:解析失败,返回 InvalidInput 错误 解决:验证JSON格式,使用在线JSON验证工具

问题3:内存碎片

症状:长时间运行后内存不足 解决:使用静态分配或定期重启设备

最佳实践

  1. 始终检查解析错误
  2. 合理估算缓冲区大小
  3. 在嵌入式系统中优先使用静态分配
  4. 使用 const 引用避免不必要的复制
  5. 定期更新到最新版本

总结

ArduinoJson 是嵌入式系统处理JSON数据的绝佳选择,它平衡了功能性和资源消耗,提供了简单易用的API。无论是物联网设备的数据传输,还是配置文件的读写,ArduinoJson 都能提供可靠高效的解决方案。其活跃的社区和持续的更新维护,使其成为嵌入式开发者的首选JSON库之一。

通过合理的内存管理和正确的使用模式,ArduinoJson 可以在资源受限的环境中稳定运行,为物联网应用提供强大的数据交换能力。

ArduinoJson_20260203201135.zip
类型:压缩文件|已下载:0|下载方式:免费下载
立即下载
文章版权及转载声明

作者:icy本文地址:https://zelig.cn/2026/03/301.html发布于 昨天
文章转载或复制请以超链接形式并注明出处软角落-SoftNook

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏

阅读
分享

发表评论

快捷回复:

验证码

评论列表 (暂无评论,17人围观)参与讨论

还没有评论,来说两句吧...