一直以來,博主的事例代碼中都一直使用到JSON數據格式。而不少初學者一直對JSON格式有很大疑惑,因此博主特地分出一篇博文來重點講解Arduino平臺下的JSON庫——ArduinoJSON。
讀者須要注意一下幾點:git
#include <ArduinoJson.h>
廢話少說,請讀者認真如下乾貨內容。github
JSON對象描述:json
{ "motor": { "left": 100, "right": 20 }, "servo": { "servo_1": 90 } }
JSON對象語法說明:api
JSON數組描述:數組
{ "employees": [ { "firstName": "Bill", "lastName": "Gates" }, { "firstName": "George", "lastName": "Bush" }, { "firstName": "Thomas", "lastName": "Carter" } ] }
JSON數組語法說明:數據結構
重點:app
上面說到,ArduinoJson庫有兩個大版本 —— V5 和 V6。
不論是V5仍是V6版本,在編碼以前,請到Arduino IDE的管理庫去下載:
函數
請讀者按照本身的需求分別去下載不一樣版本(固然博主建議用新不用舊,畢竟通常新版本都是通過舊版本升級優化)。
不論是V5 仍是 V6版本,對於開發者來講有三個概念是共通的:工具
除了理解上面的三個概念,博主認爲讀者還必須注意如下兩點:oop
記住上面的黑體內容,接下來,咱們針對不一樣版本的ArduinoJson庫來說解使用以及注意事項。
假設讀者下載的V5版本的,那麼能夠參考 這裏 的API說明。讀者須要注意一下jsonBuffer,由於V5版本的json操做都是在它上面。
對於開發者來講,使用JSON無非就是編碼或者解碼,因此博主也會分出兩種狀況來說解。
首先咱們來看看V5版本經常使用的百度腦圖:
能夠看出,方法主要分爲三大類:
JsonBuffer做爲整個V5版本ArduinoJson庫的入口,負責處理整個json數據的內存管理以及構造解析工做,這是咱們須要首先重點關注的內容。
它包括兩個實現類:
對於一些內存使用比較緊缺的機器,博主建議儘可能用固定大小的StaticJsonBuffer(這個須要提早預知內容的大小,而這個內容大小能夠經過計算得來,請點 wiki 參考)。
那麼,咱們開發者可能會關心如下幾個常見問題:
1. 問題1,如何去肯定buffer的大小?
{"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]}
那麼經過JSON_OBJECT_SIZE(n)和JSON_ARRAY_SIZE(n)能夠計算出內存大小:
const int BUFFER_SIZE = JSON_OBJECT_SIZE(3) + JSON_ARRAY_SIZE(2); StaticJsonBuffer<BUFFER_SIZE> jsonBuffer;
固然咱們能夠藉助工具來幫咱們計算內存大小,具體能夠參考 ArduinoJson Assistant。
假設整個json數據結構是非固定的,開發者可使用DynamicJsonBuffer,能夠動態增加(動態增加就意味着可能會內存溢出,整個是須要開發者去考慮的),固然儘可能給DynamicJsonBuffer一個足夠大的初始值,能夠減小調用malloc()方法去分配內存。
json解析器根據輸入的內容會有不一樣的策略字符串。若是輸入的內容是可寫內容,好比 char* 或者 char[],解析器不會申請額外的內存空間,也就是「zero-copy」模式。若是輸入的內容是自讀內容,好比 const char* 或者 字符串 或者steam流,解析器會從新拷貝一份該字符串做爲可寫操做,這樣就意味着JsonBuffer大小可能和咱們預想的不同。因此,博主建議開發者儘可能是char* 或者 char[]。
2. StaticJsonBuffer 和 DynamicJsonBuffer的區別?
3. 如何去重用一個JsonBuffer?
// STEP1: parse input StaticJsonBuffer<200> jsonBuffer; JsonObject& inputObject = jsonBuffer.parseObject(inputJson); ...etc... // STEP2: generate output jsonBuffer.clear(); JsonObject& outputObject = jsonBuffer.createObject(); outputObject["hello"] = inputObject["world"];
看起來沒有什麼問題,但實際上有訪問錯誤,請看分析:
那麼要怎麼解決這個問題呢?有兩種解決方案:
// STEP1: parse input StaticJsonBuffer<400> jsonBuffer; JsonObject& inputObject = jsonBuffer.parseObject(inputJson); ...etc... // STEP2: generate output JsonObject& outputObject = jsonBuffer.createObject(); outputObject["hello"] = inputObject["world"];
// STEP1: parse input StaticJsonBuffer<200> jsonBuffer1; JsonObject& inputObject = jsonBuffer1.parseObject(inputJson); ...etc... // STEP2: generate output StaticJsonBuffer<200> jsonBuffer2; JsonObject& outputObject = jsonBuffer2.createObject(); outputObject["hello"] = inputObject["world"];
4. 爲何不要去用一個全局的JsonBuffer?
接下來,看看JsonBuffer的一些經常使用方法:
函數說明:
/** * 重置內存指針,複用內存空間,慎用 */ void clear();
例子說明:
StaticJsonBuffer<200> jb; JsonObject& obj1 = jb.parseObject(json1); // we can use obj1 here... jb.clear(); // now obj1 is dangling!!! // ...but we can reuse the JsonBuffer JsonObject& obj2 = jb.parseObject(json2);
注意:
函數說明:
/** * 建立空json數組,併爲它分配內存空間 * @return json數組地址 * @Note 若是分配失敗,會提示分配失敗 */ JsonArray& createArray();
例子說明:
StaticJsonBuffer<200> jsonBuffer; JsonArray& array = jsonBuffer.createArray(); array.add("hello"); array.add("world");
函數說明:
/** * 建立空json對象,併爲它分配內存空間 * @return json對象地址 * @Note 若是分配失敗,會提示分配失敗 */ JsonObject createObject();
例子說明:
StaticJsonBuffer<200> jsonBuffer; JsonObject& object = jsonBuffer.createObject(); object["hello"] = "world";
函數說明:
/** * 解析json(數組或者對象)字符串 * @param json json字符串 * @param nestingLimit json深度限制 * @return jsonVariant對象 * @Note 此方法用於不可預知json格式的前提下使用的 */ // The first overload, which accepts a modifiable array of chars, is the most efficient // since it allows the zero-copy feature. JsonVariant parse(char* json, uint8_t nestingLimit=10); // The following overloads, which accept read-only strings, require a bigger JsonBuffer // because parts of the JSON input has to be copied. JsonVariant parse(const char* json, uint8_t nestingLimit=10); JsonVariant parse(const String& json, uint8_t nestingLimit=10); JsonVariant parse(const std::string& json, uint8_t nestingLimit=10); JsonVariant parse(const __FlashStringHelper* json, uint8_t nestingLimit=10); // The two last overloads, which accept input streams, make copy of the input too. JsonVariant parse(Stream& json, uint8_t nestingLimit=10); JsonVariant parse(std::istream& json, uint8_t nestingLimit=10);
例子說明:
char json[] = "[\"hello\",\"world\"]"; StaticJsonBuffer<200> jsonBuffer; JsonVariant variant = jsonBuffer.parse(json); if (variant.is<JsonArray>()) // true in this example { JsonArray& array = variant; const char* hello = array[0]; const char* world = array[1]; }
函數說明:
/** * 解析json數組字符串 * @param json json字符串 * @param nestingLimit json深度限制 * @return jsonArray對象 * @Note 此方法用於預知json格式是jsonArray的前提下使用的 */ // The first overload, which accepts a modifiable array of chars, is the most efficient // since it allows the zero-copy feature. JsonArray& parseArray(char* json, uint8_t nestingLimit=10); // The following overloads, which accept read-only strings, require a bigger JsonBuffer // because parts of the JSON input has to be copied. JsonArray& parseArray(const char* json, uint8_t nestingLimit=10); JsonArray& parseArray(const String& json, uint8_t nestingLimit=10); JsonArray& parseArray(const std::string& json, uint8_t nestingLimit=10); JsonArray& parseArray(const __FlashStringHelper* json, uint8_t nestingLimit=10); // The two last overloads, which accept input streams, make copy of the input too. JsonArray& parseArray(Stream& json, uint8_t nestingLimit=10); JsonArray& parseArray(std::istream& json, uint8_t nestingLimit=10);
例子說明:
char json[] = "[\"hello\",\"world\"]"; StaticJsonBuffer<200> jsonBuffer; JsonArray& array = jsonBuffer.parseArray(json); const char* hello = array[0]; const char* world = array[1];
函數說明:
/** * 解析json對象字符串 * @param json json字符串 * @param nestingLimit json深度限制 * @return json對象 * @Note 此方法用於預知json格式是jsonObject的前提下使用的 */ // The first overload, which accepts a modifiable array of chars, is the most efficient // since it allows the zero-copy feature. JsonObject& parseObject(char* json, uint8_t nestingLimit=10); // The following overloads, which accept read-only strings, require a bigger JsonBuffer // because parts of the JSON input has to be copied. JsonObject& parseObject(const char* json, uint8_t nestingLimit=10); JsonObject& parseObject(const String& json, uint8_t nestingLimit=10); JsonObject& parseObject(const std::string& json, uint8_t nestingLimit=10); JsonObject& parseObject(const __FlashStringHelper* json, uint8_t nestingLimit=10); // The two last overloads, which accept input streams, make copy of the input too. JsonObject& parseObject(Stream& json, uint8_t nestingLimit=10); JsonObject& parseObject(std::istream& json, uint8_t nestingLimit=10);
例子說明:
char json[] = "{\"hello\":\"world\"}"; StaticJsonBuffer<200> jsonBuffer; JsonObject& object = jsonBuffer.parseObject(json); const char* world = object["hello"];
函數說明:
/** * JsonBuffer當前已用大小 * @return 當前已用大小 */ size_t size() const;
例子說明:
StaticJsonBuffer<200> jsonBuffer; Serial.println(jsonBuffer.size()); jsonBuffer.createObject(); Serial.println(jsonBuffer.size()); jsonBuffer.createArray(); Serial.println(jsonBuffer.size());
在8位單片機中會打印:
0 4 8
在JsonBuffer所構造出來的內存空間中,Json對象的入口就是JsonObject。
讓咱們看看它的經常使用操做方法:
函數說明:
/** * 返回一個迭代器,可用於對象中的全部鍵值對 * @return iterator iterator包括key和value */ JsonObject::iterator begin(); JsonObject::iterator end(); JsonObject::const_iterator begin() const; JsonObject::const_iterator end() const;
例子說明:
char json[] = "{\"first\":\"hello\",\"second\":\"world\"}"; DynamicJsonBuffer jsonBuffer; JsonObject& root = jsonBuffer.parseObject(json); // using C++11 syntax (preferred): for (auto kv : root) { Serial.println(kv.key); Serial.println(kv.value.as<char*>()); } // using C++98 syntax (for older compilers): for (JsonObject::iterator it=root.begin(); it!=root.end(); ++it) { Serial.println(it->key); Serial.println(it->value.as<char*>()); }
測試結果:
first hello second world
函數說明:
/** * 判斷對象是否包含某一個key * @param key key名字 * @return bool */ bool containsKey(const char* key) const; bool containsKey(const String& key) const; bool containsKey(const std::string& key) const; bool containsKey(const __FlashStringHelper& key) const;
例子說明:
StaticJsonBuffer<256> jsonBuffer; JsonObject& root = jsonBuffer.createObject(); root["city"] = "Paris"; bool hasCity = root.containsKey("city"); // true bool hasCountry = root.containsKey("country"); // false
注意:
if (root.containsKey("error")) { const char* error = root["error"] Serial.println(error); return; }
能夠改爲:
JsonVariant error = root["error"]; if (error.success()) { Serial.println(error.as<char*>()); return; }
或者更加簡單快速的方法:
const char* error = root["error"]; if (error) { Serial.println(error); return; }
函數說明:
/** * 在當前對象中添加子key,子value爲json數組 * @param key key名字 * @return JsonArray */ JsonArray& createNestedArray(const char* key) const; JsonArray& createNestedArray(char* key) const; // see Remarks JsonArray& createNestedArray(const String& key) const; // see Remarks JsonArray& createNestedArray(const std::string& key) const; // see Remarks JsonArray& createNestedArray(const __FlashStringHelper* key) const; // see Remarks
例子說明:
StaticJsonBuffer<256> jsonBuffer; JsonObject& root = jsonBuffer.createObject(); root["status"] = "on"; JsonArray& levels = root.createNestedArray("levels"); levels.add(10); levels.add(30); root.prettyPrintTo(Serial);
打印結果:
{ "status": "on", "levels": [ 10, 20 ] }
函數說明:
/** * 在當前對象中添加子key,子value爲json對象 * @param key key名字 * @return JsonObject對象 */ JsonObject& createNestedObject(const char* key) const; JsonObject& createNestedObject(char* key) const; // see Remarks JsonObject& createNestedObject(const String& key) const; // see Remarks JsonObject& createNestedObject(const std::string& key) const; // see Remarks JsonObject& createNestedObject(const __FlashStringHelper* key) const; // see Remarks
例子說明:
StaticJsonBuffer<256> jsonBuffer; JsonObject& root = jsonBuffer.createObject(); root["city"] = "Paris"; JsonObject& weather = root.createNestedObject("weather"); weather["temp"] = 14.2; weather["cond"] = "cloudy"; root.prettyPrintTo(Serial);
打印結果:
{ "city": "Paris", "weather": { "temp": 14.20, "cond": "cloudy" } }
函數說明:
/** * 獲取某一個key的值,T表示值類型 * @param key key名字 * @return 值 */ bool get<bool> (TString key) const; const char* get<const char*> (TString key) const; double get<double> (TString key) const; float get<float> (TString key) const; JsonVariant get<JsonVariant> (TString key) const; signed char get<signed char> (TString key) const; signed int get<signed int> (TString key) const; signed long get<signed long> (TString key) const; signed short get<signed short> (TString key) const; std::string get<std::string> (TString key) const; String get<String> (TString key) const; unsigned char get<unsigned char> (TString key) const; unsigned int get<unsigned int> (TString key) const; unsigned long get<unsigned long> (TString key) const; unsigned short get<unsigned short> (TString key) const;
例子說明:
char json[] = "{\"pi\":3.14}"; StaticJsonBuffer<256> jsonBuffer; JsonObject& object = jsonBuffer.parseObject(json); float pi = object.get<float>("pi"); // template version of get() const char* value2 = object.get<const char*>("toto"); // returns NULL
函數說明:
/** * 判斷某一個key的值是不是T類型 * @param key key名字 * @return bool * true 爲T類型 * false 不是T類型 */ bool is<bool> (TString key) const; bool is<const char*> (TString key) const; bool is<char*> (TString key) const; bool is<double> (TString key) const; bool is<float> (TString key) const; bool is<signed char> (TString key) const; bool is<signed int> (TString key) const; bool is<signed long> (TString key) const; bool is<signed short> (TString key) const; bool is<unsigned char> (TString key) const; bool is<unsigned int> (TString key) const; bool is<unsigned long> (TString key) const; bool is<unsigned short> (TString key) const; bool is<signed long long> (TString key) const; // <- may require ARDUINOJSON_USE_LONG_LONG bool is<unsigned long long>(TString key) const; // <- may require ARDUINOJSON_USE_LONG_LONG bool is<JsonArray> (TString key) const; bool is<JsonObject> (TString key) const;
例子說明:
char json[] = "{\"name\":\"toto\",\"pi\":3.14}"; StaticJsonBuffer<256> jsonBuffer; JsonObject& obj = jsonBuffer.parseObject(json); bool nameIsString = obj.is<char*>("name"); // <- true bool piIsFloat = obj.is<float>("pi"); // <- true // but we could also use JsonVariant.is<T>(), like that: nameIsString = obj["name"].is<char*>(); // <- true piIsFloat = obj["pi"].is<float>(); // <- true
函數說明:
/** * 計算當前對象經過printTo打印出來的長度 * @return size_t 長度值 * @Note 跟 JsonObject::printTo() 關聯,此方法一般用於http協議中的 Content-Length頭 */ size_t measureLength() const
例子說明:
// Send headers client.println("Content-Type: application/json"); client.print("Content-Length: "); client.println(root.measureLength()); // Terminate headers client.println(); // Send body root.printTo(client);
函數說明:
/** * 計算當前對象經過prettyPrintTo打印出來的長度 * @return size_t 長度值 * @Note 跟 JsonObject::prettyPrintTo() 關聯,此方法一般用於http協議中的 Content-Length頭 */ size_t measurePrettyLength() const
例子說明:
// Send headers client.println("Content-Type: application/json"); client.print("Content-Length: "); client.println(root.measurePrettyLength()); // Terminate headers client.println(); // Send body root.prettyPrintTo(client);
函數說明:
/** * 格式化輸出json字符串 * @param buffer 內容輸出到內存區 * @param size 內存區的大小 * @param Print 打印流 好比 Serial * @param String 打印到字符串 * @return 返回已寫大小 */ size_t prettyPrintTo(char* buffer, size_t size) const; size_t prettyPrintTo(char buffer[size]) const; size_t prettyPrintTo(Print &) const; size_t prettyPrintTo(String &) const; size_t prettyPrintTo(std::string &) const;
例子說明:
StaticJsonBuffer<200> jsonBuffer; JsonObject& object = jsonBuffer.createObject(); object["hello"] = "world"; object.prettyPrintTo(Serial);
打印結果:
{ "hello": "world" }
函數說明:
/** * 壓縮式輸出json字符串 * @param buffer 內容輸出到內存區 * @param size 內存區的大小 * @param Print 打印流 好比 Serial * @param String 打印到字符串 * @return 返回已寫大小 */ size_t printTo(char* buffer, size_t size) const; size_t printTo(char buffer[size]) const; size_t printTo(Print &) const; size_t printTo(String &) const; size_t printTo(std::string &) const;
例子說明:
StaticJsonBuffer<200> jsonBuffer; JsonObject& object = jsonBuffer.createObject(); object["hello"] = "world"; object.printTo(Serial);
打印結果:
{"hello":"world"}
注意:
函數說明:
/** * 移除特定key和value * @param key key名 */ void remove(const char* key); void remove(const String& key); void remove(const std::string& key); void remove(const __FlashStringHelper* key);
例子說明:
JsonObject& object = jsonBuffer.createObject(); object["A"] = 1; object["B"] = 2; object["C"] = 3; object.remove("B"); object.printTo(Serial);
打印結果:
{"A":1,"C":3}
注意:
函數說明:
/** * 設置特定key的值 * @param key key名 * @param value 值 * @return bool 是否設置成功 */ bool set(TString key, bool value); bool set(TString key, float value); bool set(TString key, double value); bool set(TString key, signed char value); bool set(TString key, signed long value); bool set(TString key, signed int value); bool set(TString key, signed short value); bool set(TString key, unsigned char value); bool set(TString key, unsigned long value); bool set(TString key, unsigned int value); bool set(TString key, unsigned short value); bool set(TString key, const char *value); bool set(TString key, char *value); // see Remarks bool set(TString key, const String &value); // see Remarks bool set(TString key, const std::string &value); // see Remarks bool set(TString key, const __FlashStringHelper* value); // see Remarks bool set(TString key, JsonArray &array); bool set(TString key, JsonObject &object); bool set(TString key, const JsonVariant &value);
例子說明:
StaticJsonBuffer<200> jsonBuffer; JsonObject& object = jsonBuffer.createObject(); object.set("hello","world"); object.printTo(Serial);
打印結果:
{"hello":"world"}
函數說明:
/** * 返回對象鍵值對的個數 * @return size_t 個數 */ size_t size() const;
例子說明:
JsonObject& object = jsonBuffer.createObject(); object["hello"] = "world"; Serial.println(object.size()); // 1
函數說明:
/** * get/set的快捷方式 */ JsonVariant& operator[](const char* key); JsonVariant& operator[](char* key); // see Remarks JsonVariant& operator[](const String& key); // see Remarks JsonVariant& operator[](const std::string& key); // see Remarks JsonVariant& operator[](const __FlashStringHelper* key); // see Remarks const JsonVariant& operator[](const char* key) const; const JsonVariant& operator[](const String& key) const; const JsonVariant& operator[](const std::string& key) const; const JsonVariant& operator[](const __FlashStringHelper* key) const;
例子說明:
JsonObject& object = jsonBuffer.createObject(); object["hello"] = "world"; const char* world = object["hello"];
函數說明:
/** * 判斷對象是不是有效(解析或者分配內存) * @return bool */ bool success() const;
例子說明:
//Example 1: parsing success: StaticJsonBuffer<200> jsonBuffer; JsonObject& object = jsonBuffer.parseObject("{\"hello\":\"world\"}"); Serial.println(object.success()); // true //Example 2: parsing failure: StaticJsonBuffer<200> jsonBuffer; JsonObject& object = jsonBuffer.parseObject("[\"hello\",\"world\"]"); Serial.println(object.success()); // false //Example 3: allocation success: StaticJsonBuffer<200> jsonBuffer; JsonObject& object = jsonBuffer.createObject(); Serial.println(object.success()); // true //Example 4: allocation failure: StaticJsonBuffer<1> jsonBuffer; JsonObject& object = jsonBuffer.createObject(); Serial.println(object.success()); // false
在JsonBuffer所構造出來的內存空間中,Json數組的入口就是JsonArray。
讓咱們看看它的經常使用操做方法:
函數說明:
/** * 往數組中加入value * @param value 值 * @return bool 是否添加成功,若是返回false通常都是jsonbuffer沒有足夠的空間 */ bool add(bool value); bool add(float value); bool add(double value); bool add(signed char value); bool add(signed long value); bool add(signed int value); bool add(signed short value); bool add(unsigned char value); bool add(unsigned long value); bool add(unsigned int value); bool add(unsigned short value); bool add(const char *value); bool add(char *value); // see Remarks bool add(const String &value); // see Remarks bool add(const std::string &value); // see Remarks bool add(const __FlashStringHelper *value); // see Remarks bool add(JsonArray &array); bool add(JsonObject &object); bool add(const JsonVariant &variant);
例子說明:
StaticJsonBuffer<200> jsonBuffer; JsonArray& array = jsonBuffer.createArray(); array.add("hello"); array.add(3.14156); array.printTo(Serial);
打印結果:
["hello",3.14156]
函數說明:
/** * 返回一個迭代器,可用於數組中的全部對象 * @return iterator */ JsonObject::iterator begin(); JsonObject::iterator end(); JsonObject::const_iterator begin() const; JsonObject::const_iterator end() const;
例子說明:
char json[] = "[\"one\",\"two\",\"three\"]"; DynamicJsonBuffer jsonBuffer; JsonArray& arr = jsonBuffer.parseArray(json); // using C++11 syntax (preferred): for (auto value : arr) { Serial.println(value.as<char*>()); } // using C++98 syntax (for older compilers): for (JsonArray::iterator it=arr.begin(); it!=arr.end(); ++it) { Serial.println(it->as<char*>()); }
打印結果:
one two three
函數說明:
/** * 把c數組轉成json數組 * @param array 數組 * @param len 數組大小 */ // 1D arrays JsonArray::copyFrom(T array[len]); JsonArray::copyFrom(T* array, size_t len); // 2D arrays JsonArray::copyFrom(T array[][]);
例子說明:
int values[] = {1, 2, 3}; StaticJsonBuffer<200> jsonBuffer; JsonArray& array = jsonBuffer.createArray(); array.copyFrom(values); array.printTo(Serial);
打印結果:
[1,2,3]
函數說明:
/** * 把json數組轉成c數組 * @param array 數組 */ JsonArray::copyTo(int array[]); JsonArray::copyTo(double array[]); JsonArray::copyTo(const char* array[]);
例子說明:
int values[3]; StaticJsonBuffer<200> jsonBuffer; JsonArray& array = jsonBuffer.parseArray("[1,2,3]"); array.copyTo(values);//如今values變成1,2,3
函數說明:
/** * 添加json數組 * @return JsonArray json數組 */ JsonArray& createNestedArray();
例子說明:
StaticJsonBuffer<200> jsonBuffer; JsonArray& array = jsonBuffer.createArray(); array.add("hello"); JsonArray& nested = array.createNestedArray(); nested.add("world"); array.printTo(Serial);
打印結果:
["hello",["world"]]
函數說明:
/** * 添加json對象 * @return JsonObject json對象 */ JsonObject& createNestedObject();
例子說明:
StaticJsonBuffer<200> jsonBuffer; JsonArray& array = jsonBuffer.createArray(); JsonObject& nested = array.createNestedObject(); nested["hello"] = "world"; array.printTo(Serial);
打印結果:
[{"hello":"world"}]
函數說明:
/** * 獲取具體index的值 * @param index 索引 * @return T 返回索引對應的值 */ bool get<bool> (size_t index) const; const char* get<const char*> (size_t index) const; const char* get<char*> (size_t index) const; double get<double> (size_t index) const; float get<float> (size_t index) const; signed char get<signed char> (size_t index) const; signed int get<signed int> (size_t index) const; signed long get<signed long> (size_t index) const; signed short get<signed short> (size_t index) const; unsigned char get<unsigned char> (size_t index) const; unsigned int get<unsigned int> (size_t index) const; unsigned long get<unsigned long> (size_t index) const; unsigned short get<unsigned short> (size_t index) const; JsonVariant get<JsonVariant> (size_t index) const; std::string get<std::string> (size_t index) const; String get<String> (size_t index) const;
例子說明:
char json[] = "[1,3.14]"; StaticJsonBuffer<256> jsonBuffer; JsonArray& array = jsonBuffer.parseArray(json); int value0 = array.get(0); // implicit cast of the JsonVariant float value1 = array.get<float>(1); // template version of get() const char* value2 = array.get(2); // returns NULL
注意:
函數說明:
/** * 判斷具體index的值是否爲T類型 * @return bool 是不是目標類型 */ bool is<bool> (size_t index) const; bool is<const char*> (size_t index) const; bool is<char*> (size_t index) const; bool is<double> (size_t index) const; bool is<float> (size_t index) const; bool is<signed char> (size_t index) const; bool is<signed int> (size_t index) const; bool is<signed long> (size_t index) const; bool is<signed short> (size_t index) const; bool is<unsigned char> (size_t index) const; bool is<unsigned int> (size_t index) const; bool is<unsigned long> (size_t index) const; bool is<unsigned short> (size_t index) const; bool is<signed long long> (size_t index) const; // <- may require ARDUINOJSON_USE_LONG_LONG bool is<unsigned long long>(size_t index) const; // <- may require ARDUINOJSON_USE_LONG_LONG bool is<JsonArray> (size_t index) const; bool is<JsonObject> (size_t index) const;
例子說明:
char json[] = "[\"pi\",3.14]"; StaticJsonBuffer<256> jsonBuffer; JsonArray& array = jsonBuffer.parseArray(json); bool firstIsString = array.is<char*>(0); // <- true bool secondIsFloat = array.is<float>(1); // <- true // but we could also use JsonVariant.is<T>(), like that: firstIsString = array[0].is<char*>(); // <- true secondIsFloat = array[1].is<float>(); // <- true
函數說明:
/** * 計算當前json數組經過printTo打印出來的長度 * @return size_t 長度值 * @Note 跟 JsonArray::printTo() 關聯,此方法一般用於http協議中的 Content-Length頭 */ size_t measureLength() const
例子說明:
// Send headers client.println("Content-Type: application/json"); client.print("Content-Length: "); client.println(root.measureLength()); // Terminate headers client.println(); // Send body root.printTo(client);
函數說明:
/** * 計算當前json數組經過prettyPrintTo打印出來的長度 * @return size_t 長度值 * @Note 跟 JsonArray::prettyPrintTo() 關聯,此方法一般用於http協議中的 Content-Length頭 */ size_t measurePrettyLength() const
例子說明:
// Send headers client.println("Content-Type: application/json"); client.print("Content-Length: "); client.println(root.measurePrettyLength()); // Terminate headers client.println(); // Send body root.prettyPrintTo(client);
函數說明:
/** * 格式化輸出json數組字符串 * @param buffer 內容輸出到內存區 * @param size 內存區的大小 * @param Print 打印流 好比 Serial * @param String 打印到字符串 * @return 返回已寫大小 */ size_t prettyPrintTo(char* buffer, size_t size) const; size_t prettyPrintTo(char buffer[size]) const; size_t prettyPrintTo(Print &) const; size_t prettyPrintTo(String &) const; size_t prettyPrintTo(std::string &) const;
例子說明:
StaticJsonBuffer<200> jsonBuffer; JsonArray& array = jsonBuffer.createArray(); array.add("hello"); array.add("world"); array.prettyPrintTo(Serial);
打印結果:
[ "hello", "world" ]
函數說明:
/** * 壓縮式輸出json數組字符串 * @param buffer 內容輸出到內存區 * @param size 內存區的大小 * @param Print 打印流 好比 Serial * @param String 打印到字符串 * @return 返回已寫大小 */ size_t printTo(char* buffer, size_t size) const; size_t printTo(char buffer[size]) const; size_t printTo(Print &) const; size_t printTo(String &) const; size_t printTo(std::string &) const;
例子說明:
StaticJsonBuffer<200> jsonBuffer; JsonArray& array = jsonBuffer.createArray(); array.add("hello"); array.add("world"); array.printTo(Serial);
打印結果:
["hello","world"]
注意:
函數說明:
/** * 移除某一個index位置的元素 * @param index 索引 */ void remove(size_t index);
例子說明:
JsonArray& array = jsonBuffer.createArray(); array.add("A"); array.add("B"); array.add("C"); array.remove(1); array.printTo(Serial);
打印結果:
["A","C"]
注意:
函數說明:
/** * 設置某一個index位置的值 * @param index 索引位置 * @param value 值 * @return bool 是否設置成功 */ bool set(size_t index, bool value); bool set(size_t index, double value); bool set(size_t index, float value); bool set(size_t index, signed char value); bool set(size_t index, signed int value); bool set(size_t index, signed long value); bool set(size_t index, signed short value); bool set(size_t index, unsigned char value); bool set(size_t index, unsigned int value); bool set(size_t index, unsigned long value); bool set(size_t index, unsigned short value); bool set(size_t index, const char *value); bool set(size_t index, char *value); // see Remarks bool set(size_t index, const std::string &value); // see Remarks bool set(size_t index, const String &value); // see Remarks bool set(size_t index, const __FlashStringHelper *value); // see Remarks bool set(size_t index, JsonArray &array); bool set(size_t index, JsonObject &object); bool set(size_t index, const JsonVariant &value);
例子說明:
StaticJsonBuffer<200> jsonBuffer; JsonArray& array = jsonBuffer.createArray(); // increase the size of the array array.add(666); array.add(666); // replace the values array.set(0, "hello"); array.add(1, 3.14156); // serialize array.printTo(Serial);
打印結果:
["hello",3.14156]
函數說明:
/** * 返回json數組元素的個數 * @return size_t 個數 */ size_t size() const;
例子說明:
JsonArray& array = jsonBuffer.createArray(); array.add("hello"); array.add("world"); Serial.println(array.size()); // 2
函數說明:
/** * get/set的快捷方式 */ JsonVariant& operator[](size_t index); const JsonVariant& operator[](size_t index) const;
例子說明:
JsonArray& array = jsonBuffer.createArray(); array.add(42); int value = array[0]; array[0] = 666;
函數說明:
/** * 判斷json數組是否成功分配內存或者解析 * @return bool */ bool success() const;
例子說明:
//Example 1: parsing success: StaticJsonBuffer<200> jsonBuffer; JsonArray& array = jsonBuffer.parseArray("[1,2]"); Serial.println(array.success()); // true //Example 2: parsing failure: StaticJsonBuffer<200> jsonBuffer; JsonArray& array = jsonBuffer.parseArray("{1,2}"); Serial.println(array.success()); // false //Example 3: allocation success: StaticJsonBuffer<200> jsonBuffer; JsonArray& array = jsonBuffer.createArray(); Serial.println(array.success()); // true //Example 4: allocation failure: StaticJsonBuffer<1> jsonBuffer; JsonArray& array = jsonBuffer.createArray(); Serial.println(array.success()); // false
講完理論知識,咱們開始用具體例子來驗證。
實驗材料:
例子代碼:
/** * 構造json例子 * @author 單片機菜鳥 * @date 2019/06/01 */ #include <ArduinoJson.h> void setup() { Serial.begin(115200); while (!Serial) continue; // Json對象對象樹的內存工具 靜態buffer // 200 是大小 若是這個Json對象更加複雜,那麼就須要根據須要去增長這個值. StaticJsonBuffer<200> jsonBuffer; // StaticJsonBuffer 在棧區分配內存 它也能夠被 DynamicJsonBuffer(內存在堆區分配) 代替 // DynamicJsonBuffer jsonBuffer; //建立最外層的json對象 —— root對象,頂節點 JsonObject& root = jsonBuffer.createObject(); //給最外層json對象添加屬性 root["sensor"] = "gps"; root["time"] = 1351824120; //在root對象中加入data數組 JsonArray& data = root.createNestedArray("data"); data.add(48.756080); data.add(2.302038); //在串口中打印,printTo方法不會格式化json root.printTo(Serial); // This prints: // {"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]} Serial.println(); //在串口中打印,prettyPrintTo方法會格式化json root.prettyPrintTo(Serial); // This prints: // { // "sensor": "gps", // "time": 1351824120, // "data": [ // 48.756080, // 2.302038 // ] // } } void loop() { // not used in this example }
運行結果:
實驗材料:
例子代碼:
/** * 解碼Json字符串 * @author 單片機菜鳥 * @date 2019/06/02 */ #include <ArduinoJson.h> void setup() { Serial.begin(115200); while (!Serial) continue; // Json對象對象樹的內存工具 靜態buffer // 200 是大小 若是這個Json對象更加複雜,那麼就須要根據須要去增長這個值. StaticJsonBuffer<200> jsonBuffer; // StaticJsonBuffer 在棧區分配內存 它也能夠被 DynamicJsonBuffer(內存在堆區分配) 代替 // DynamicJsonBuffer jsonBuffer; char json[] = "{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}"; JsonObject& root = jsonBuffer.parseObject(json); // Test if parsing succeeds. if (!root.success()) { Serial.println("parseObject() failed"); return; } // Fetch values. // // Most of the time, you can rely on the implicit casts. // In other case, you can do root["time"].as<long>(); const char* sensor = root["sensor"]; long time = root["time"]; double latitude = root["data"][0]; double longitude = root["data"][1]; // Print values. Serial.println(sensor); Serial.println(time); Serial.println(latitude, 6); Serial.println(longitude, 6); } void loop() { // not used in this example }
注意:
好比,若是開發者當前版本爲 5.13.2,那麼就會有:
#define ARDUINOJSON_VERSION "5.13.2" //完整版本號 #define ARDUINOJSON_VERSION_MAJOR 5 //大版本 #define ARDUINOJSON_VERSION_MINOR 13 //小版本 #define ARDUINOJSON_VERSION_REVISION 2 //小小版本
咱們能夠經過Serial打印版本號:
Serial.print("Using ArduinoJson version "); Serial.println(ARDUINOJSON_VERSION);
經過它,咱們能夠作一些事情,好比:
#ifndef ARDUINOJSON_VERSION #error ArduinoJson not found, please include ArduinoJson.h in your .ino file #endif
#if ARDUINOJSON_VERSION_MAJOR!=5 || ARDUINOJSON_VERSION_MINOR<13 #error ArduinoJson 5.13+ is required #endif
整體上,Json屬於一種數據交換格式,不會說太難。本篇屬於簡單介紹了ArduinoJson V5庫的使用,更加複雜的使用請直接去到ArduinoJson的主頁去查閱。