mirror of
				https://github.com/eledio-devices/thirdparty-ArduinoJson.git
				synced 2025-10-31 16:14:11 +01:00 
			
		
		
		
	Moved documentation to the wiki
This commit is contained in:
		| @@ -35,8 +35,6 @@ Quick start | |||||||
|     double latitude    = root["data"][0]; |     double latitude    = root["data"][0]; | ||||||
|     double longitude   = root["data"][1]; |     double longitude   = root["data"][1]; | ||||||
|  |  | ||||||
| [See complete guide](/doc/Decoding JSON.md) |  | ||||||
|  |  | ||||||
| #### Encoding / Generating | #### Encoding / Generating | ||||||
|     |     | ||||||
|     StaticJsonBuffer<200> jsonBuffer; |     StaticJsonBuffer<200> jsonBuffer; | ||||||
| @@ -53,7 +51,11 @@ Quick start | |||||||
|     // This prints: |     // This prints: | ||||||
|     // {"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]} |     // {"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]} | ||||||
|  |  | ||||||
| [See complete guide](/doc/Encoding JSON.md) |  | ||||||
|  | Documentation | ||||||
|  | ------------- | ||||||
|  |  | ||||||
|  | The documentation is available online in the [Arduino JSON wiki](https://github.com/bblanchon/ArduinoJson/wiki)  | ||||||
|  |  | ||||||
| Testimonials | Testimonials | ||||||
| ------------ | ------------ | ||||||
|   | |||||||
| @@ -1,102 +0,0 @@ | |||||||
| Avoiding common pitfalls in Arduino JSON |  | ||||||
| ======================================== |  | ||||||
|  |  | ||||||
| As `StaticJsonBuffer` is the corner stone of this library, you'll see that every pitfall listed here are related to a wrong understanding of the memory model. |  | ||||||
|  |  | ||||||
| Make sure you read [Arduino JSON memory model](Memory model.md) before going further. |  | ||||||
|  |  | ||||||
| ## 1. Make `StaticJsonBuffer` big enough |  | ||||||
|  |  | ||||||
| By design, the library has no way to tell you why `parseArray()` or `parseObject()` failed. |  | ||||||
|  |  | ||||||
| There are basically two reasons why they may fail: |  | ||||||
|  |  | ||||||
| 1. the JSON string is invalid, |  | ||||||
| 2. the JSON string contains more values that the buffer can store. |  | ||||||
|  |  | ||||||
| So, if you are sure the JSON string is correct and you still can't parse it, you should try to increase the size of the `StaticJsonBuffer`. |  | ||||||
|  |  | ||||||
| ## 2. Make sure everything fits in memory |  | ||||||
|  |  | ||||||
| You may go into unpredictable trouble if you allocate more memory than your processor really has. |  | ||||||
| It's a very common issue in embedded development. |  | ||||||
|  |  | ||||||
| To diagnose this, look at every big objects in you code and sum their size to check that they fit in RAM. |  | ||||||
|  |  | ||||||
| For example, don't do this: |  | ||||||
|  |  | ||||||
|     char json[1024];                // 1 KB |  | ||||||
|     StaticJsonBuffer<512> buffer;   // 514 B |  | ||||||
|  |  | ||||||
| because it may be too big for a processor with only 2 KB: you need free memory to store other variables and the call stack. |  | ||||||
|  |  | ||||||
| That is why an 8-bit processor is not able to parse long and complex JSON strings. |  | ||||||
|  |  | ||||||
| ## 3. Keep the `StaticJsonBuffer` in memory long enough |  | ||||||
|  |  | ||||||
| Remember that `StaticJsonBuffer`'s function return references. |  | ||||||
| References don't contain data, they are just pointer to the actual. |  | ||||||
| So they can only work if the actual data is in memory. |  | ||||||
|  |  | ||||||
| For example, don't do this: |  | ||||||
|  |  | ||||||
|     JsonArray& getArray(char* json) |  | ||||||
|     { |  | ||||||
|         StaticJsonBuffer<200> buffer; |  | ||||||
|         return buffer.parseArray(json);  |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| because the local variable `buffer` will be *removed* from memory when the function `parseArray()` returns, and the `JsonArray&` will point to an invalid location. |  | ||||||
|  |  | ||||||
| ## 4. Don't reuse the same `StaticJsonBuffer` |  | ||||||
|  |  | ||||||
| During is lifetime a `StaticJsonBuffer` growth until it's discarded. If you try to reuse the same instance several time, it will rapidly get full. |  | ||||||
|  |  | ||||||
| For this reason, you should not use a global variable for your `StaticJsonBuffer`. I don't think there is any scenario in which a global `StaticJsonBuffer` would be a valid option. |  | ||||||
|  |  | ||||||
| The best practice is to declare it in a local scope, so that it's discarded as soon as possible. My advice it to declare it in a function which unique role is to handle the JSON serialization. |  | ||||||
|  |  | ||||||
| ## 5. Keep the JSON string in memory long enough |  | ||||||
|  |  | ||||||
| The library never make memory duplication. |  | ||||||
| This has an important implication on string values, it means that the library will return pointer to chunks of the string. |  | ||||||
|  |  | ||||||
| For instance, let's imagine that you parse `["hello","world"]`, like this: |  | ||||||
|  |  | ||||||
|     char[] json = "[\"hello\",\"world\"]"; |  | ||||||
|     StaticJsonBuffer<32> buffer; |  | ||||||
|     JsonArray& array = buffer.parseArray(json); |  | ||||||
|  |  | ||||||
|     const char* first = array[0]; |  | ||||||
|     const char* second = array[1]; |  | ||||||
|  |  | ||||||
| In that case, both `first` and `second` are pointers to the content of the original string `json`. |  | ||||||
| So this will only work if `json` is still in memory. |  | ||||||
|  |  | ||||||
| ## 6. JSON string is altered |  | ||||||
|  |  | ||||||
| If you read carefully the previous section, you may have come to the conclusion that the JSON parser modifies the JSON string. |  | ||||||
|  |  | ||||||
| Indeed, the parser modifies the string for two reasons: |  | ||||||
|  |  | ||||||
| 1. it inserts `\0` to terminate substrings, |  | ||||||
| 2. it translate escaped characters like `\n` or `\t`. |  | ||||||
|  |  | ||||||
| Most of the time this wont be an issue, but there are some corner cases that can be problematic. |  | ||||||
|  |  | ||||||
| Let take the example bellow: |  | ||||||
|  |  | ||||||
|     char[] json = "[\"hello\",\"world\"]"; |  | ||||||
|     StaticJsonBuffer<32> buffer; |  | ||||||
|     JsonArray& array = buffer.parseArray(json); |  | ||||||
|  |  | ||||||
| If you replace it by: |  | ||||||
|  |  | ||||||
|     char* json = "[\"hello\",\"world\"]"; |  | ||||||
|     StaticJsonBuffer<32> buffer; |  | ||||||
|     JsonArray& array = buffer.parseArray(json); |  | ||||||
|  |  | ||||||
| Depending on your platform, you may have an exception because the parser tries to write at a location that is read-only. |  | ||||||
| In the first case `char json[]` declares an array of `char` initialized to the specified string. |  | ||||||
| In the second case `char* json` declares a pointer to a read-only string, in fact it should be a `const char*` instead of a `char*`. |  | ||||||
|  |  | ||||||
| @@ -1,15 +0,0 @@ | |||||||
| Contributing to Arduino JSON |  | ||||||
| ============================ |  | ||||||
|  |  | ||||||
| If you want to contribute to the project, please: |  | ||||||
|  |  | ||||||
| 1. Use GitHub pull request feature |  | ||||||
| 2. Follow the coding conventions |  | ||||||
| 3. Write tests |  | ||||||
|  |  | ||||||
| About the coding conventions: I try to follow the [Google C++ Style Guide](http://google-styleguide.googlecode.com/svn/trunk/cppguide.html) with few variations to match the Arduino conventions. |  | ||||||
|  |  | ||||||
| I use [ClangFormat](http://clang.llvm.org/docs/ClangFormat.html) to format the code for me. |  | ||||||
| I use [CppLint](http://google-styleguide.googlecode.com/svn/trunk/cpplint/cpplint.py) to detect non-compliant stuff. |  | ||||||
|  |  | ||||||
| You should have a look at the `scripts/` folder as it contains a few helpers scripts. |  | ||||||
| @@ -1,148 +0,0 @@ | |||||||
| Decoding JSON with Arduino JSON |  | ||||||
| =============================== |  | ||||||
|  |  | ||||||
| Before writing any code, don't forget to include the header: |  | ||||||
|  |  | ||||||
|     #include <ArduinoJson.h> |  | ||||||
|  |  | ||||||
| For instructions on how to install the library, please read [Using the library with Arduino](Using the library with Arduino.md) or [Using the library without Arduino](Using the library without Arduino.md). |  | ||||||
|  |  | ||||||
| ## Example |  | ||||||
|  |  | ||||||
| Here an example that parse the string `{"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]}`: |  | ||||||
|  |  | ||||||
|     char json[] = "{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}"; |  | ||||||
|      |  | ||||||
|     // |  | ||||||
|     // Step 1: Reserve memory space |  | ||||||
|     // |  | ||||||
|     StaticJsonBuffer<200> jsonBuffer; |  | ||||||
|      |  | ||||||
|     // |  | ||||||
|     // Step 2: Deserialize the JSON string |  | ||||||
|     // |  | ||||||
|     JsonObject& root = jsonBuffer.parseObject(json); |  | ||||||
|  |  | ||||||
|     if (!root.success()) |  | ||||||
|     { |  | ||||||
|       Serial.println("parseObject() failed"); |  | ||||||
|       return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     // |  | ||||||
|     // Step 3: Retrieve the values |  | ||||||
|     // |  | ||||||
|     const char* sensor    = root["sensor"]; |  | ||||||
|     long        time      = root["time"]; |  | ||||||
|     double      latitude  = root["data"][0]; |  | ||||||
|     double      longitude = root["data"][1]; |  | ||||||
|  |  | ||||||
| ## Step 1: Reserve memory space |  | ||||||
|  |  | ||||||
| Arduino JSON uses a preallocated memory pool to store the object tree, this is done by the `StaticJsonBuffer`. |  | ||||||
|  |  | ||||||
| Before continuing please read the page [Arduino JSON memory model](Memory model.md) that explains everything you need to know about `StaticJsonBuffer`. |  | ||||||
|  |  | ||||||
| ## Step 2: Parse the JSON string |  | ||||||
|  |  | ||||||
| You invoke the JSON parser through the instance of `StaticJsonBuffer`. |  | ||||||
| It exposes two functions for parsing JSON: |  | ||||||
|  |  | ||||||
| 1. `parseArray()` that returns a reference to a `JsonArray` |  | ||||||
| 2. `parseObject()` that returns a reference to a `JsonObject` |  | ||||||
|  |  | ||||||
| Let's see an example. |  | ||||||
| Say we want to parse `{"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]}`, it's an object so we call `parseObject()` as follows: |  | ||||||
|  |  | ||||||
|     char json[] = "{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}"; |  | ||||||
|  |  | ||||||
|     JsonObject& root = jsonBuffer.parseObject(json); |  | ||||||
|  |  | ||||||
| As you can see `parseObject()` takes a `char*` as a parameter. |  | ||||||
| Be careful, it's not a `const char*`, the memory must be writable. |  | ||||||
| Indeed, the parser will modify the string in two cases: |  | ||||||
|  |  | ||||||
| 1. to insert string endings (character `\0`), |  | ||||||
| 2. to translate escaped characters (like `\n` or `\t`). |  | ||||||
|  |  | ||||||
| Another thing that you must keep in mind is that the string (`char json[]` in the example above) must stay in memory during the whole parsing process. |  | ||||||
| That is because the in memory object tree will store pointer to chunks of the string, so as to avoid any memory duplication.  |  | ||||||
|  |  | ||||||
| Now, to check if the parsing was successful, you can call `JsonObject::success()`: |  | ||||||
|  |  | ||||||
|     if (!root.success()) |  | ||||||
|     { |  | ||||||
|         // Parsing fail |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| The result can be `false` for tree reasons: |  | ||||||
|  |  | ||||||
| 1. the JSON string is invalid, |  | ||||||
| 2. the JSON string doesn't represent an object, |  | ||||||
| 3. the `StaticJsonBuffer` is too small. |  | ||||||
|  |  | ||||||
| We just saw how to parse an object, there is nothing more to say for arrays, the procedure is exactly the same. |  | ||||||
|  |  | ||||||
| ## Step 3: Retrieve the values |  | ||||||
|  |  | ||||||
| Now that the object or array is in memory, you can extract the data very easily. |  | ||||||
|  |  | ||||||
| In this section, we'll see how to do it with a `JsonObject`. |  | ||||||
| Once again, there is nothing more to say about arrays, `JsonArray` works exactly the same as `JsonObject`. |  | ||||||
|  |  | ||||||
| #### Subscript operator |  | ||||||
|  |  | ||||||
| The simplest way is to use the subscript operator of `JsonObject`: |  | ||||||
|      |  | ||||||
|     const char* sensor = root["sensor"]; |  | ||||||
|     long time = root["time"]; |  | ||||||
|  |  | ||||||
| You can chain the subscript operator if you have nested arrays or objects: |  | ||||||
|  |  | ||||||
|     double latitude  = root["data"][0]; |  | ||||||
|     double longitude = root["data"][1]; |  | ||||||
|  |  | ||||||
| But alternatively, you can get a reference to the nested array: |  | ||||||
|  |  | ||||||
|     JsonArray& nestedArray = root["data"]; |  | ||||||
|  |  | ||||||
| #### Casting values |  | ||||||
|  |  | ||||||
| In the previous examples, the values were implicitly casted to the target type. |  | ||||||
| You can also do this explicitly |  | ||||||
|  |  | ||||||
|     const char* sensor = root["sensor"].asString(); |  | ||||||
|     long time = root["time"].as<long>(); |  | ||||||
|     JsonArray& nestedArray = root["data"].asArray(); |  | ||||||
|  |  | ||||||
| If the actual value doesn't match the target type, a default value will be return: |  | ||||||
|  |  | ||||||
| 1. `false` for boolean values |  | ||||||
| 2. `0` for integer values |  | ||||||
| 3. `NULL` for string values |  | ||||||
| 4. `JsonArray::invalid()` for nested arrays |  | ||||||
| 5. `JsonObject::invalid()` for nested object |  | ||||||
|  |  | ||||||
| #### Check values |  | ||||||
|  |  | ||||||
| If you want to know if some value is present, call `containsKey()`: |  | ||||||
|  |  | ||||||
|     if (root.contains("extra")) |  | ||||||
|     { |  | ||||||
|         // root["extra"] is valid |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| If you want to check the type value has a certain type, call `is<T>()`: |  | ||||||
|  |  | ||||||
|     if (root["extra"].is<JsonArray&>()) |  | ||||||
|     { |  | ||||||
|         // root["extra"] is an array |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| You can also iterate through the key-value pairs of the object: |  | ||||||
|  |  | ||||||
|     for (JsonObject::itertor it=root.begin(); it!=root.end(); ++it) |  | ||||||
|     { |  | ||||||
|       Serial.println(it->key); |  | ||||||
|       Serial.println(i->value.asString()); |  | ||||||
|     } |  | ||||||
| @@ -1,140 +0,0 @@ | |||||||
| Encoding JSON with Arduino JSON |  | ||||||
| =============================== |  | ||||||
|  |  | ||||||
| Before writing any code, don't forget to include the header: |  | ||||||
|  |  | ||||||
|     #include <ArduinoJson.h> |  | ||||||
|  |  | ||||||
| For instructions on how to install the library, please read [Using the library with Arduino](Using the library with Arduino.md) or [Using the library without Arduino](Using the library without Arduino.md). |  | ||||||
|  |  | ||||||
| ## Example |  | ||||||
|  |  | ||||||
| Here is an example to generate `{"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]}` |  | ||||||
|  |  | ||||||
|     // |  | ||||||
|     // Step 1: Reserve memory space |  | ||||||
|     // |  | ||||||
|     StaticJsonBuffer<200> jsonBuffer; |  | ||||||
|  |  | ||||||
|     // |  | ||||||
|     // Step 2: Build object tree in memory |  | ||||||
|     // |  | ||||||
|     JsonObject& root = jsonBuffer.createObject(); |  | ||||||
|     root["sensor"] = "gps"; |  | ||||||
|     root["time"] = 1351824120; |  | ||||||
|  |  | ||||||
|     JsonArray& data = root.createNestedArray("data"); |  | ||||||
|     data.add(48.756080, 6);  // 6 is the number of decimals to print |  | ||||||
|     data.add(2.302038, 6);   // if not specified, 2 digits are printed |  | ||||||
|  |  | ||||||
|     // |  | ||||||
|     // Step 3: Generate the JSON string |  | ||||||
|     // |  | ||||||
|     root.printTo(Serial); |  | ||||||
|  |  | ||||||
| ## Step 1: Reserve memory space |  | ||||||
|  |  | ||||||
| Arduino JSON uses a preallocated memory pool to store the object tree, this is done by the `StaticJsonBuffer`. |  | ||||||
|  |  | ||||||
| Before continuing please read the page [Arduino JSON memory model](Memory model.md) that explains everything you need to know about `StaticJsonBuffer`. |  | ||||||
|  |  | ||||||
| ## Step 2: Build object tree in memory |  | ||||||
|  |  | ||||||
| Now that you have enough memory hold by the `StaticJsonBuffer`, you can use it to build your in-memory representation of the JSON string. |  | ||||||
|  |  | ||||||
| #### Arrays |  | ||||||
|  |  | ||||||
| You create an array like this: |  | ||||||
|  |  | ||||||
|     JsonArray& array = jsonBuffer.createArray(); |  | ||||||
|  |  | ||||||
| Don't forget the `&` after `JsonArray`, it needs to be a reference to the array. |  | ||||||
|  |  | ||||||
| Then you can add strings, integer, booleans, etc: |  | ||||||
|  |  | ||||||
|     array.add("bazinga!"); |  | ||||||
|     array.add(42); |  | ||||||
|     array.add(true); |  | ||||||
|  |  | ||||||
| There are two syntaxes for floating point values: |  | ||||||
|  |  | ||||||
| 	array.add(3.1415, 4);  // 4 digits: "3.1415" |  | ||||||
|     array.add(3.1415);	   // 2 digits: "3.14" |  | ||||||
|  |  | ||||||
| > ##### About floating point precision |  | ||||||
| > The overload of `add()` with 2 parameters allows you to specify the number of decimals to save in the JSON string. |  | ||||||
| > When you use the overload with one parameter, you use the default number of decimals which is 2. |  | ||||||
| > Note that this behavior is the exact same as Arduino's `Print::print(double,int);` which is implemented by `Serial`, so you may already be familiar with this behavior. |  | ||||||
|  |  | ||||||
| You can add a nested array or object if you have a reference to it. |  | ||||||
| Or simpler, you can create nested array or nested objects from the array: |  | ||||||
|  |  | ||||||
|     JsonArray&  nestedArray  = array.createNestedArray(); |  | ||||||
|     JsonObject& nestedObject = array.createNestedObject(); |  | ||||||
|  |  | ||||||
| #### Objects |  | ||||||
|  |  | ||||||
| You create an object like this: |  | ||||||
|  |  | ||||||
|     JsonObject& object = jsonBuffer.createObject(); |  | ||||||
|  |  | ||||||
| Again, don't forget the `&` after `JsonObject`, it needs to be a reference to the object. |  | ||||||
|  |  | ||||||
| Then you can add strings, integer, booleans, etc: |  | ||||||
|  |  | ||||||
|     object["key1"] = "bazinga!"; |  | ||||||
|     object["key2"] = 42; |  | ||||||
|     object["key3"] = true; |  | ||||||
|  |  | ||||||
| As for the arrays, there are two syntaxes for the floating point values: |  | ||||||
|  |  | ||||||
| 	object["key4"].set(3.1415, 4);  // 4 digits "3.1415" |  | ||||||
|     object["key5"] = 3.1415;	    // default: 2 digits "3.14" |  | ||||||
|  |  | ||||||
| You can add a nested array or object if you have a reference to it. |  | ||||||
| Or simpler, you can create nested array or nested objects from the object: |  | ||||||
|  |  | ||||||
|     JsonArray&  nestedArray  = object.createNestedArray("key6"); |  | ||||||
|     JsonObject& nestedObject = object.createNestedObject("key7"); |  | ||||||
|  |  | ||||||
| > ##### Other JsonObject functions |  | ||||||
| > * `object.add(key, value)` is a synonym for `object[key] = value` |  | ||||||
| > * `object.containsKey(key)` returns `true` is the `key` is present in `object` |  | ||||||
| > * `object.remove(key)` removes the `value` associated with `key` |  | ||||||
|  |  | ||||||
| ## Step 3: Generate the JSON string |  | ||||||
|  |  | ||||||
| There are two ways tho get the resulting JSON string. |  | ||||||
|  |  | ||||||
| Depending on your project, you may need to dump the string in a classic `char[]` or send it to a `Print` implementation like `Serial` or `EthernetClient `. |  | ||||||
|  |  | ||||||
| Both ways are the easy way :-) |  | ||||||
|  |  | ||||||
| #### Use a classic `char[]` |  | ||||||
|  |  | ||||||
| Whether you have a `JsonArray&` or a `JsonObject&`, simply call `printTo()` with the destination buffer, like so: |  | ||||||
|  |  | ||||||
| 	char buffer[256]; |  | ||||||
|     array.printTo(buffer, sizeof(buffer)); |  | ||||||
|  |  | ||||||
| > ##### Want an indented output? |  | ||||||
| > By default the generated JSON is as small as possible. It contains no extra space, nor line break. |  | ||||||
| > But if you want an indented, more readable output, you can. |  | ||||||
| > Simply call `prettyPrintTo` instead of `printTo()`: |  | ||||||
| >  |  | ||||||
| >     array.prettyPrintTo(buffer, sizeof(buffer)); |  | ||||||
|  |  | ||||||
| #### Send to a `Print` implementation |  | ||||||
|  |  | ||||||
| It's very likely that the generated JSON will end up in a stream like `Serial` or `EthernetClient `, so you can save some time and memory by doing this: |  | ||||||
|  |  | ||||||
|     array.printTo(Serial); |  | ||||||
|  |  | ||||||
| And, of course if you need an indented JSON string: |  | ||||||
|  |  | ||||||
|     array.prettyPrintTo(Serial); |  | ||||||
|  |  | ||||||
| > ##### About the Print interface |  | ||||||
| > The library is designed to send the JSON string to an implementation of the `Print` interface that is part of Arduino. |  | ||||||
| > In the example above we used `Serial`, but they are many other implementations that would work as well, including: `HardwareSerial`,  `SoftwareSerial`, `LiquidCrystal`, `EthernetClient`, `WiFiClient`, `Wire`... |  | ||||||
| > When you use this library out of the Arduino environment, it will use it's own implementation of `Print` and everything will be the same. |  | ||||||
| @@ -1,58 +0,0 @@ | |||||||
| Arduino JSON memory model |  | ||||||
| ========================= |  | ||||||
|  |  | ||||||
| ## Fixed memory allocation |  | ||||||
|  |  | ||||||
| ### Introducing `StaticJsonBuffer` |  | ||||||
|  |  | ||||||
| Arduino JSON uses a preallocated memory pool to store the object tree, this is done by the `StaticJsonBuffer` class. |  | ||||||
|  |  | ||||||
| Before using any function of the library you need to create a `StaticJsonBuffer`. Then you can use this instance to create arrays and objects, or parse a JSON string. |  | ||||||
|  |  | ||||||
| `StaticJsonBuffer` has a template parameter that determines its capacity. For example, the following line create a `StaticJsonBuffer` with a capacity of 200 bytes: |  | ||||||
|  |  | ||||||
|     StaticJsonBuffer<200> jsonBuffer; |  | ||||||
|  |  | ||||||
| The bigger the buffer is, the more complex the object tree can be, but also the more memory you need. |  | ||||||
|  |  | ||||||
| ### How to determine the buffer size? |  | ||||||
|  |  | ||||||
| So the big question you should have in mind right now is *How can I determine the size?*. |  | ||||||
|  |  | ||||||
| There are basically two approaches here: |  | ||||||
|  |  | ||||||
| 1. either you can predict the content of the object tree, |  | ||||||
| 2. or, you know how much memory is available. |  | ||||||
|  |  | ||||||
| In the first case, you know some constraints on the object tree. For instance, let's say that your know in advance (and by that I mean "at compilation time") that you want to generate an object with 3 values, one of them being an array with 2 values, like the following: |  | ||||||
|  |  | ||||||
|     {"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]} |  | ||||||
|  |  | ||||||
| To determine the memory usage of this object tree, you use the two macros `JSON_ARRAY_SIZE(n)` and `JSON_OBJECT_SIZE(n)`, both take the number of elements as an argument. |  | ||||||
| For the example above, it would be: |  | ||||||
|  |  | ||||||
|     const int BUFFER_SIZE = JSON_OBJECT_SIZE(3) + JSON_ARRAY_SIZE(2); |  | ||||||
|     StaticJsonBuffer<BUFFER_SIZE> jsonBuffer; |  | ||||||
|  |  | ||||||
| In the second case, let's say you dynamically generate a JSON object tree of a random complexity so you can't put a limit based on that. But on the other hand, you don't want your program to crash because the object tree doesn't fit in memory. |  | ||||||
| The solution here is to determine how much memory is available, or in other words how much memory you can afford for the JSON object tree. |  | ||||||
|  |  | ||||||
| ### Why choosing fixed allocation? |  | ||||||
|  |  | ||||||
| This fixed allocation approach may seem a bit strange, especially if your a desktop application developer used to dynamic allocation, but it make a lot of sense in an embedded context: |  | ||||||
|  |  | ||||||
| 1. the code is smaller |  | ||||||
| 2. it uses less memory |  | ||||||
| 3. it doesn't create memory fragmentation |  | ||||||
| 4. it predictable |  | ||||||
|  |  | ||||||
| Don't forget that the memory is "freed" as soon as the `StaticJsonBuffer` is out of scope, like any other variable. It only hold the memory for a short amount of time. |  | ||||||
|  |  | ||||||
| ## Memory usage |  | ||||||
|  |  | ||||||
| #### Object size for 8-bit AVR |  | ||||||
|  |  | ||||||
| | Type                    | Size       | |  | ||||||
| |-------------------------|------------| |  | ||||||
| | JsonArray of N element  | 4 + 8 * N  | |  | ||||||
| | JsonObject of N element | 4 + 10 * N | |  | ||||||
| @@ -1,80 +0,0 @@ | |||||||
| Migrating code written for Arduino JSON v3 to v4 |  | ||||||
| ================================================ |  | ||||||
|  |  | ||||||
| Arduino JSON v4 was a major rewrite of the library, and the API changed significantly. |  | ||||||
|  |  | ||||||
| ## Includes |  | ||||||
|  |  | ||||||
| Arduino JSON v3 had two include files: |  | ||||||
|  |  | ||||||
|     #include <JsonParser.h> |  | ||||||
|     #include <JsonGenerator.h> |  | ||||||
|  |  | ||||||
| Arduino JSON v4 only has one: |  | ||||||
|  |  | ||||||
| 	#include <ArduinoJson.h> |  | ||||||
|  |  | ||||||
| ## Namespaces |  | ||||||
|  |  | ||||||
| Arduino JSON v3 had two namespaces: |  | ||||||
|  |  | ||||||
| 	using namespace ArduinoJson::Parser; |  | ||||||
| 	using namespace ArduinoJson::Generator; |  | ||||||
|  |  | ||||||
| Arduino JSON v4 doesn't require the `using namespace` statement. |  | ||||||
| It has a namespace but the `using namespace` is done in the header file. |  | ||||||
|  |  | ||||||
| ## StaticJsonBuffer |  | ||||||
|  |  | ||||||
| Arduino JSON v3 had different memory allocation models for the parser: |  | ||||||
|  |  | ||||||
| 	JsonParser<16> parser; // 16 being the capacity in "tokens" |  | ||||||
|  |  | ||||||
| and for the generator: |  | ||||||
|  |  | ||||||
| 	JsonArray<4> array; // 4 being the number of element |  | ||||||
| 	JsonObject<4> object; |  | ||||||
|  |  | ||||||
| Arduino JSON v4 only has one memory allocation model: |  | ||||||
|  |  | ||||||
| 	StaticJsonBuffer<128> buffer; // 128 being the capacity in bytes |  | ||||||
|  |  | ||||||
| ## Return values for the parser |  | ||||||
|  |  | ||||||
| Arduino JSON v3 returned value types: |  | ||||||
|  |  | ||||||
| 	JsonArray array = parser.parseArray(json); |  | ||||||
| 	JsonObject object = parser.parseObject(json); |  | ||||||
|  |  | ||||||
| Arduino JSON v4 returns references types: |  | ||||||
|  |  | ||||||
| 	JsonArray& array = buffer.parseArray(json); |  | ||||||
| 	JsonObject& object = buffer.parseObject(json); |  | ||||||
|  |  | ||||||
| Everything else is compatible |  | ||||||
|  |  | ||||||
| ## Creating arrays and objects |  | ||||||
|  |  | ||||||
| Arduino JSON v3 allowed to create `JsonArray` and `JsonObject` directly: |  | ||||||
|  |  | ||||||
| 	JsonArray<4> array; |  | ||||||
| 	JsonObject<4> object; |  | ||||||
|  |  | ||||||
| Arduino JSON v4 requires that you use a `StaticJsonBuffer` for that: |  | ||||||
|  |  | ||||||
| 	JsonArray& array = buffer.createArray(); |  | ||||||
| 	JsonObject& object = buffer.createObject(); |  | ||||||
|  |  | ||||||
| Note: you don't have to specify the capacity anymore. |  | ||||||
|  |  | ||||||
| ## Printable interface |  | ||||||
|  |  | ||||||
| Arduino JSON v3 used to implement the Printable interface, which allowed statements like: |  | ||||||
|  |  | ||||||
|     Serial.print(array); |  | ||||||
|  |  | ||||||
| But Arduino JSON v4 doesn't, instead you need to write this: |  | ||||||
|  |  | ||||||
| 	array.printTo(Serial); |  | ||||||
|  |  | ||||||
| Note: there was a good reason for removing that feature, and it's reducing the size of `JsonArray` and `JsonObject`. |  | ||||||
| @@ -1,30 +0,0 @@ | |||||||
| Using the library with Arduino |  | ||||||
| ============================== |  | ||||||
|  |  | ||||||
| This library is primarily design to be used with the Arduino IDE and therefore has a simplified setup procedure for that environment. |  | ||||||
| If you don't use the Arduino IDE, please read [Using the library without Arduino](Using the library without Arduino.md). |  | ||||||
|  |  | ||||||
| ## Install the library |  | ||||||
|  |  | ||||||
| [Download the zip package](https://github.com/bblanchon/ArduinoJson/releases) and extract it to: |  | ||||||
|  |  | ||||||
|     <your Arduino Sketch folder>/libraries/ArduinoJson |  | ||||||
|  |  | ||||||
| Then restart the Arduino IDE. |  | ||||||
|  |  | ||||||
| ## Run the examples sketches |  | ||||||
|  |  | ||||||
| Click `File` / `Example` / `ArduinoJson`. |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| ## Use the library in your sketches |  | ||||||
|  |  | ||||||
| Just add the following line at the top of your program: |  | ||||||
|  |  | ||||||
|     #include <ArduinoJson.h> |  | ||||||
|  |  | ||||||
| Then follow the instructions: |  | ||||||
|  |  | ||||||
| 1. [Parsing JSON](Parsin JSON.md) |  | ||||||
| 2. [Generating JSON](Generating JSON.md) |  | ||||||
| @@ -1,37 +0,0 @@ | |||||||
| Using the library without Arduino |  | ||||||
| ================================= |  | ||||||
|  |  | ||||||
| This library is primarily design to be used with the Arduino IDE and therefore has a simplified setup procedure for that environment. |  | ||||||
| If you use the Arduino IDE, please read [Using the library with Arduino](Using the library with Arduino.md). |  | ||||||
|  |  | ||||||
| However, it can be used without Arduino IDE with very little effort. |  | ||||||
|  |  | ||||||
| ## Compiling the library |  | ||||||
|  |  | ||||||
| Step 1: Download source code: |  | ||||||
|  |  | ||||||
|     git clone https://github.com/bblanchon/ArduinoJson.git |  | ||||||
|  |  | ||||||
| Step 2: Generate the `Makefile` for your environment |  | ||||||
|  |  | ||||||
|     cd ArduinoJson |  | ||||||
|     cmake . |  | ||||||
|  |  | ||||||
| Step 3: Build |  | ||||||
|  |  | ||||||
| 	make |  | ||||||
|  |  | ||||||
| ## File paths |  | ||||||
|  |  | ||||||
| Assuming you installed the library into `<arduino-json>`, you need to add: |  | ||||||
|  |  | ||||||
| 1. `<arduino-json>/include` to your include path |  | ||||||
| 2. `<arduino-json>/lib` to your library path |  | ||||||
|  |  | ||||||
|  |  | ||||||
| ---------- |  | ||||||
|  |  | ||||||
| You are now ready to follow the instructions: |  | ||||||
|  |  | ||||||
| 1. [Parsing JSON](Parsin JSON.md) |  | ||||||
| 2. [Generating JSON](Generating JSON.md) |  | ||||||
		Reference in New Issue
	
	Block a user