ArduinoVN
Đăng nhập Tham gia
Thư viện Code /u/linucat /16/05/2026

Thư viện ArduinoJson: tạo & parse JSON trên Arduino/ESP32

Thảo luận

ArduinoJson là thư viện JSON cho Arduino mạnh và phổ biến nhất, do Benoît Blanchon viết. Bạn dùng nó mỗi khi ESP32 nói chuyện với API HTTP, MQTT, hay đọc cấu hình từ SD card. Bài này hướng dẫn từ v6/v7 API mới, gồm tạo, parse, lưu vào file, và các lỗi memory thường gặp.

1. Cài đặt

Library Manager → tìm "ArduinoJson" by Benoit Blanchon. Chọn phiên bản 7.x mới nhất (API gọn hơn v6).

#include 

2. Tạo JSON — Serialize

JsonDocument doc;
doc["device"] = "esp32-sensor-01";
doc["temp"] = 25.4;
doc["hum"] = 67;
doc["online"] = true;

JsonArray relays = doc["relays"].to();
relays.add(0);
relays.add(1);
relays.add(0);

String output;
serializeJson(doc, output);
Serial.println(output);
// {"device":"esp32-sensor-01","temp":25.4,"hum":67,"online":true,"relays":[0,1,0]}

Hoặc xuất đẹp có thụt lề:

serializeJsonPretty(doc, Serial);

3. Parse JSON — Deserialize

const char* json = "{\"temp\":25.5,\"hum\":60,\"name\":\"phong-khach\"}";

JsonDocument doc;
DeserializationError err = deserializeJson(doc, json);
if (err) {
  Serial.print("JSON loi: "); Serial.println(err.c_str());
  return;
}

float t = doc["temp"];
int h = doc["hum"];
const char* name = doc["name"];
Serial.println(t);
Serial.println(name);

4. v7 vs v6 — khác biệt

v6 yêu cầu khai báo kích thước trước: StaticJsonDocument<256> hoặc DynamicJsonDocument(1024). v7 bỏ hết — chỉ cần JsonDocument doc;. Memory được cấp phát từ heap theo nhu cầu.

Nếu dùng v6 cũ, ước tính kích thước bằng ArduinoJson Assistant online.

5. Đọc mảng và đối tượng lồng nhau

const char* j = "{\"users\":[{\"id\":1,\"name\":\"An\"},{\"id\":2,\"name\":\"Binh\"}]}";
JsonDocument doc;
deserializeJson(doc, j);

for (JsonObject u : doc["users"].as()) {
  int id = u["id"];
  const char* name = u["name"];
  Serial.print(id); Serial.print(" "); Serial.println(name);
}

6. Parse trực tiếp từ Stream (WiFiClient, File)

Tiết kiệm RAM cực mạnh khi đọc HTTP response hoặc file SD lớn:

HTTPClient http;
http.begin("https://api.example.com/data");
int code = http.GET();
if (code == 200) {
  JsonDocument doc;
  deserializeJson(doc, http.getStream());   // stream trực tiếp
  // ...
}
http.end();
File f = SD.open("/config.json");
JsonDocument doc;
deserializeJson(doc, f);
f.close();

7. Filter — chỉ lấy field cần thiết

API trả về JSON 50KB nhưng bạn chỉ cần 3 field — dùng filter để giảm RAM:

JsonDocument filter;
filter["name"] = true;
filter["temp"] = true;

JsonDocument doc;
deserializeJson(doc, stream, DeserializationOption::Filter(filter));

8. Kiểm tra field tồn tại

if (doc["optional"].is()) {
  int v = doc["optional"];
}
// hoặc fallback:
int v = doc["optional"] | 0;   // 0 nếu thiếu

9. Memory — lỗi #1 với ArduinoJson

  • JSON quá lớn → NoMemory. Trên Uno (2KB RAM) chỉ xử lý được JSON nhỏ. Lên ESP32 (320KB RAM) thoải mái.
  • Trả về const char* từ JsonDocument là pointer vào buffer trong doc. Khi doc bị huỷ (ra khỏi scope), pointer thành dangling. Nếu cần giữ, copy sang String:
    String name = doc["name"].as();
  • Không bao giờ strcpy() từ const char* JSON sang buffer mà không kiểm tra strlen.

10. Bảng nhanh các API hay dùng

HàmVai trò
deserializeJson(doc, src)Parse từ String/char*/Stream/File
serializeJson(doc, dst)Xuất compact
serializeJsonPretty(doc, dst)Xuất có thụt lề
doc.to<JsonArray>()Khởi tạo mảng
doc["k"].is<T>()Check kiểu
doc.size()Số phần tử (object/array)
doc.memoryUsage()RAM đã dùng (v6) / không có v7

Liên quan

Dùng cùng PubSubClient: subscribe/publish MQTT để truyền JSON qua MQTT. Hoặc xem dự án ESP32 gửi data lên ThingSpeak.

Thảo luận (0)

Đăng nhập để tham gia thảo luận.
Chưa có bình luận nào. Hãy là người đầu tiên!