Benoit Blanchon
2017-02-18 15:54:51 +01:00
parent a28b037c55
commit 4c0d2937fc
11 changed files with 23 additions and 838 deletions

@@ -1 +1 @@
🚚 The API Reference has been moved to https://bblanchon.github.io/ArduinoJson/api/ 🚚
🚚 This page has been moved to https://bblanchon.github.io/ArduinoJson/api/ 🚚

@@ -1,143 +1 @@
As `StaticJsonBuffer` is the corner stone of this library, you'll see that every pitfall listed here is related to a wrong understanding of the memory model.
Make sure you read [Arduino JSON memory model](Memory model) 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`.
You can use the [ArduinoJson Assistant](https://bblanchon.github.io/ArduinoJson/assistant/) to compute the required size.
#### 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 `JsonBuffer`
During is lifetime a `JsonBuffer` growth until it's discarded. If you try to reuse the same instance several time, it will rapidly get full. This is true for both `DynamicJsonBuffer` and `StaticJsonBuffer`.
For this reason, **you should not use a global variable** for your `JsonBuffer`. I don't think there is any scenario in which a global `JsonBuffer` 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 is to declare it in a function whose unique role is to handle the JSON serialization.
See [FAQ: The first parsing succeeds, why does the next ones fail?](https://bblanchon.github.io/ArduinoJson/faq/the-first-parsing-succeeds-why-do-the-next-ones-fail)
#### 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. Do not assume that strings are copied
By default, ArduinoJson doesn't make copies of strings.
This allows it to work with full static memory allocation and ensure an efficient use of CPU cycles.
But this can have subtle consequences...
For instance the following code will not work as expected:
JsonArray& array = jsonBuffer.createArray();
for (int i=0; i<3; i++) {
char buffer[16];
sprintf(buffer, "iteration %d", i);
array.add(buffer);
}
array.printTo(Serial);
One will probably expect the following result:
["iteration 0","iteration 1","iteration 2"]
but the actual result would be:
["iteration 2","iteration 2","iteration 2"]
because the same memory area has been reuse for each iteration.
The simplest solution is to explicitly duplicate the strings in the `JsonBuffer`:
JsonArray& array = jsonBuffer.createArray();
for (int i=0; i<3; i++) {
char buffer[16];
sprintf(buffer, "iteration %d", 0);
array.add(jsonBuffer.strdup(buffer));
}
array.printTo(Serial);
The same principle applies to key and values of `JsonObject`.
Note: If you use `String` instead of a `const char*`, ArduinoJson calls `JsonBuffer::strdup()` implicitly.
#### 7. Make sure the string isn't read-only
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*`.
🚚 This page has been moved to https://bblanchon.github.io/ArduinoJson/doc/pitfalls/ 🚚

@@ -1,122 +1 @@
<!-- MarkdownTOC depth=3 autolink=true bracket=round lowercase_only_ascii=true -->
- [Arduino Library Manager doesn't list the latest versions of ArduinoJson](#arduino-library-manager-doesnt-list-the-latest-versions-of-arduinojson)
- [CodeBender](#codebender)
- [Arduino Zero, mkr1000 and all boards based on SAMD21](#arduino-zero-mkr1000-and-all-boards-based-on-samd21)
- [Warning: ignoring packed attribute because of unpacked non-POD field](#warning-ignoring-packed-attribute-because-of-unpacked-non-pod-field)
- [Error: undefined reference to `__cxa_guard_acquire` and `__cxa_guard_release`](#error-undefined-reference-to-cxaguardacquire-and-cxaguardrelease)
- [Adafruit WICED](#adafruit-wiced)
- [ESP32](#esp32)
- [Sloeber Arduino Eclipse Plugin](#sloeber-arduino-eclipse-plugin)
<!-- /MarkdownTOC -->
Despite the effort on writing portable code, there are compatibility issues with a few platform.
## Arduino Library Manager doesn't list the latest versions of ArduinoJson
This is a very common issue.
If ArduinoJson doesn't appear in Libray Manager, or if only old versions are listed, try to delete the local cache.
This will force the Libray Manager to download the library list from scratch.
For example, on Windows, you need to delete:
* `%LOCALAPPDATA%\Arduino15\library_index.json`
* `%LOCALAPPDATA%\Arduino15\library_index.json.tmp.gz`
You don't even need to close Arduino, just re-open the library manager.
## CodeBender
For some reason, it's not possible to use ArduinoJson with CodeBender.
See discussion here: http://feedback.codebender.cc/forums/280538-library-requests/suggestions/7238254-arduinojson-support
## Arduino Zero, mkr1000 and all boards based on SAMD21
There is a bug in [Arduino SAMD core](https://github.com/arduino/ArduinoCore-samd) that make `prettyPrintTo()` fail (issue [#327](https://github.com/bblanchon/ArduinoJson/issues/327))
It's been fixed on May 27th by [arduino/ArduinoCore-samd@8ef9bb3](https://github.com/arduino/ArduinoCore-samd/commit/8ef9bb3d7bd026b57a8568030d8992644c9b8de8) and [arduino/ArduinoCore-samd@8d0c167](https://github.com/arduino/ArduinoCore-samd/commit/8d0c1674628df1c2c7592f4fc17467c694f5a1be).
Unfortunately, version 1.6.6 only includes modifications up to May 19th, so the fix is not available through the Arduino Boards Manager.
I recommend to apply the modification manually or wait until the next release of the Arduino SAMD Core.
The files to change are [`USBCore.cpp`](https://github.com/arduino/ArduinoCore-samd/commit/8ef9bb3d7bd026b57a8568030d8992644c9b8de8) and [`CDC.cpp`](https://github.com/arduino/ArduinoCore-samd/commit/8d0c1674628df1c2c7592f4fc17467c694f5a1be).
They are located here on Windows:
```
%LOCALAPPDATA%\Arduino15\packages\arduino\hardware\samd\1.6.6\cores\arduino\USB
```
## Warning: ignoring packed attribute because of unpacked non-POD field
If you pass the flag `--fpack-struct` to the compiler, it will generate the following warning:
```
warning: ignoring packed attribute because of unpacked non-POD field
```
No solution has been found so far: you need to remove that flag if you want to get rid of that warning.
See issue [#255](https://github.com/bblanchon/ArduinoJson/issues/255)
## Error: undefined reference to `__cxa_guard_acquire` and `__cxa_guard_release`
You need to add the following flag:
> `-fno-threadsafe-statics`
> Do not emit the extra code to use the routines specified in the C++ ABI for thread-safe initialization of local statics. You can use this option to reduce code size slightly in code that doesn't need to be thread-safe.
See issue [#356](https://github.com/bblanchon/ArduinoJson/issues/356) and [#389](https://github.com/bblanchon/ArduinoJson/issues/389)
## Adafruit WICED
There is currently a bug in the Arduino Core for Adafruit WICED Feather causing the following error:
```
error: cannot convert 'err_t' to 'err_t (*)()
```
See issue [#404](https://github.com/bblanchon/ArduinoJson/issues/404)
## ESP32
There is currently a bug in the [Arduino Core for ESP32](https://github.com/espressif/arduino-esp32) causing the following error:
```
error: redefinition of 'struct ArduinoJson::Internals::StringFuncs<const char*>'
```
The solution is to disable `PROGMEM` support in ArduinoJson.
To do that, just add the following line at the top of your program:
```c++
#define ARDUINOJSON_ENABLE_PROGMEM 0
```
Then, you may have the following linker error:
```
undefined reference to__cxa_guard_release'
```
To solve this, you need to add `-fno-threadsafe-statics` in `platform.txt`.
See issue [#407](https://github.com/bblanchon/ArduinoJson/issues/407)
## Sloeber Arduino Eclipse Plugin
When compiling ArduinoJson within the Sloeber Arduino Eclipse Plugin, you may encounter the following error:
```
C:/Utilities/sloeber/arduinoPlugin/libraries/ArduinoJson/5.8.2/fuzzing/fuzzer.cpp:3:39: error: expected class-name before '{' token class memstream : public std::istream
```
You need to add the `fuzzin/` folder to the "Source Folder Exclusion Patterns", like on the pricture bellow:
![Source Folder Exclusion Patterns](https://cloud.githubusercontent.com/assets/1175841/22299097/2af90b14-e323-11e6-8b21-5f0f91055e60.png)
See issues [ArduinoJson #432](https://github.com/bblanchon/ArduinoJson/issues/432) and [Sloeber #642](https://github.com/Sloeber/arduino-eclipse-plugin/issues/642).
🚚 This page has been moved to https://bblanchon.github.io/ArduinoJson/faq/compilation-fails-device-crashes-nothing-on-serial-console/ 🚚

@@ -1,184 +1 @@
> *This page contains a detailed guide on how to parse a JSON string using the Arduino JSON library*
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) or [Using the library without Arduino](Using the library without Arduino).
## 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) 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 three 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.containsKey("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::iterator it=root.begin(); it!=root.end(); ++it)
{
Serial.println(it->key);
Serial.println(it->value.asString());
}
Or if you want to iterate through a nested array:
JsonObject& data = variables["data"];
for (auto dataobj : data){
Serial.println(dataobj.key);
}
## Advanced Example
Let's take what we've learned above up a gear :)
Our JSON array is now:
char json[] = "{\"data\":{\"time\":{\"day\":1,\"month\":3,\"year\":16,\"hours\":9,\"mins\":59,\"secs\":14}}}";
We parse it and check it as before with:
JsonObject& root = jsonBuffer.parseObject(json);
// Test if parsing succeeds.
if (!root.success()) {
Serial.println("parseObject() failed");
return;
}
Now to get the data, we can follow the object downwards, just like you would do with PHP etc...:
int day = root["data"]["time"]["day"];
int month = root["data"]["time"]["month"];
int year = root["data"]["time"]["year"];
int hours = root["data"]["time"]["hours"];
int mins = root["data"]["time"]["mins"];
int secs = root["data"]["time"]["secs"];
This allows for more complex data to be processed, the time as in this example or numerous values from a single function. Just make sure your jsonBuffer is large enough to handle the larger objects!
See the file called "JsonParserExample_Advanced.ino" in "ArduinoJson/examples/JsonParserExample/"
🚚 This page has been moved to https://bblanchon.github.io/ArduinoJson/doc/decoding/ 🚚

@@ -1,185 +1 @@
> *This page contains a detailed guide on how to generate a JSON string using the Arduino JSON library*
Before writing any code, don't forget to include the header:
```c++
#include <ArduinoJson.h>
```
For instructions on how to install the library, please read [Using the library with Arduino](Using the library with Arduino) or [Using the library without Arduino](Using the library without Arduino).
## Example
Here is an example to generate `{"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]}`
```c++
//
// 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`.
In the case of a `StaticJsonBuffer`, the memory is reserved on the stack. The template parameter (`200` in the example) is the number of bytes to reserved.
Alternatively, you can use a `DynamicJsonBuffer` that allocates memory on the heap and grow as required. It is the preferred way for devices with a significant amount of RAM, like the ESP8266.
See also:
* [Arduino JSON memory model](Memory model)
* [FAQ: What are the differences between StaticJsonBuffer and DynamicJsonBuffer?](FAQ#what-are-the-differences-between-staticjsonbuffer-and-dynamicjsonbuffer)
* [FAQ: How to determine the buffer size?](FAQ#how-to-determine-the-buffer-size)
## Step 2: Build object tree in memory
Once the `JsonBuffer` is ready, you can use it to build your in-memory representation of the JSON string.
#### Arrays
You create an array like this:
```c++
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:
```c++
array.add("bazinga!");
array.add(42);
array.add(true);
```
There are 3 syntaxes for floating point values:
```c++
array.add(3.1415); // default: 2 digits -> "3.14"
array.add(double_with_n_digits(3.1415, 4)); // explicit: 4 digits -> "3.1415"
array.add(3.1415, 4); // same as previous -> "3.1415"
```
> ##### 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 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:
```c++
JsonArray& nestedArray = array.createNestedArray();
JsonObject& nestedObject = array.createNestedObject();
```
#### Objects
You create an object like this:
```c++
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:
```c++
object["key1"] = "bazinga!";
object["key2"] = 42;
object["key3"] = true;
```
As for the arrays, there are two syntaxes for the floating point values:
```c++
object["key4"] = double_with_n_digits(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:
```c++
JsonArray& nestedArray = object.createNestedArray("key6");
JsonObject& nestedObject = object.createNestedObject("key7");
```
> ##### Other JsonObject functions
> * `object.set(key, value)` is a synonym for `object[key] = value`
> * `object.set(key, value, digits)` is a synonym for `object[key] = double_with_n_digits(value, digits)`
> * `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:
```c++
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 is very likely that the generated JSON ends up in a stream like `Serial` or `EthernetClient `, so you can save some time and memory by doing this:
```c++
array.printTo(Serial);
```
And, of course if you need an indented JSON string:
```c++
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 uses its own implementation of `Print` and everything is the same.
#### Length of the output data
If you need to know the length of the output data beforehand, use the `measureLength()` method:
```c++
int len = array.measureLength();
```
That comes in handy when you need to calculate the `Content-Length` when posting JSON data over HTTP.
🚚 This page has been moved to https://bblanchon.github.io/ArduinoJson/doc/encoding/ 🚚

26
Home.md

@@ -1,19 +1,19 @@
#### Installation
- [Using the library with Arduino](Using the library with Arduino)
- [Using the library without Arduino](Using the library without Arduino)
- [Using the library in a CMake project](Using the library in a CMake project)
- [Quick start](Quick Start)
#### User guide
- [Quick start](Quick Start)
- [Memory model](Memory model)
- [Decoding JSON](Decoding JSON)
- [Encoding JSON](Encoding JSON)
- [Examples](Examples)
- [Avoiding pitfalls](Avoiding pitfalls)
- ~~[Migrating code to new the API](Migrating code to the new API)~~ (obsolete)
- [Compatibility issues](Compatibility issues)
- [F.A.Q (Frequently Asked Questions) :confused:](https://bblanchon.github.io/ArduinoJson/faq/)
- [Installation](https://bblanchon.github.io/ArduinoJson/doc/installation/)
- [Decoding JSON](https://bblanchon.github.io/ArduinoJson/doc/decoding/)
- [Encoding JSON](https://bblanchon.github.io/ArduinoJson/doc/encoding/)
- [Memory model](https://bblanchon.github.io/ArduinoJson/doc/memory/)
- [Avoiding pitfalls](https://bblanchon.github.io/ArduinoJson/doc/pitfalls/)
- [API Reference](https://bblanchon.github.io/ArduinoJson/api/)
- ~~[Migrating code to new the API](Migrating code to the new API)~~ (obsolete)
#### Resources
- [F.A.Q (Frequently Asked Questions) :confused:](https://bblanchon.github.io/ArduinoJson/faq/)
- [Examples](Examples)
- [Bag of Tricks](Bag of Tricks)
- [ArduinoJson Assistant](https://bblanchon.github.io/ArduinoJson/assistant/)

@@ -1,107 +1 @@
> *This page explains how the memory is managed in the Arduino JSON library*
## 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 creates 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 you 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;
If you're in this situation, [ArduinoJson Assistant](https://bblanchon.github.io/ArduinoJson/assistant) will be of great help.
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 choose fixed allocation?
This fixed allocation approach may seem a bit strange, especially if you are a desktop application developer used to dynamic allocation, but it makes 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 is predictable
Don't forget that the memory is "freed" as soon as the `StaticJsonBuffer` is out of scope, like any other variable. It only holds the memory for a short amount of time.
## Dynamic memory allocation
This library also supports dynamic memory allocation.
However, usage of this memory model is **strongly discouraged** in embedded environments.
To switch to dynamic memory allocation, simply replace:
StaticJsonBuffer<N> jsonBuffer;
by
DynamicJsonBuffer jsonBuffer;
Memory is released in `DynamicJsonBuffer`'s destructor, so you don't have to do anything special.
## Memory usage
#### Object size for 8-bit AVR
| Type | Size |
|-------------------------|------------|
| JsonArray of N element | 4 + 8 * N |
| JsonObject of N element | 4 + 10 * N |
#### Object size on ESP8266
| Type | Size |
|-------------------------|------------|
| JsonVariant | 8 |
| JsonArray of N element | 8 + 12 * N |
| JsonObject of N element | 8 + 16 * N |
#### Object size on ESP8266 if `JsonFloat` is changed to `double`
| Type | Size |
|-------------------------|------------|
| JsonVariant | 16 |
| JsonArray of N element | 8 + 24 * N |
| JsonObject of N element | 8 + 32 * N |
#### Object size on x86 (tested on Visual Studio 2015)
| Type | Size |
|-------------------------|-------------|
| JsonVariant | 16 |
| JsonArray of N element | 12 + 24 * N |
| JsonObject of N element | 12 + 32 * N |
#### Object size on x64 (tested on Visual Studio 2015)
| Type | Size |
|-------------------------|-------------|
| JsonVariant | 16 |
| JsonArray of N element | 24 + 24 * N |
| JsonObject of N element | 24 + 32 * N |
🚚 This page has been moved to https://bblanchon.github.io/ArduinoJson/doc/memory/ 🚚

@@ -1,25 +1 @@
All you need to write a `CMakeLists.txt` like this one:
```CMake
cmake_minimum_required(VERSION 2.8.12)
project(Server)
add_subdirectory(ArduinoJson/src)
add_executable(server
server.c
)
target_link_libraries(server ArduinoJson)
```
Then just call:
```shell
mkdir build
cd build
cmake ..
make
```
See issue [#188](https://github.com/bblanchon/ArduinoJson/issues/188)
🚚 This page has been moved to https://bblanchon.github.io/ArduinoJson/doc/installation/ 🚚

@@ -1,48 +1 @@
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).
## Install the library
### For Arduino 1.6.x and above
ArduinoJson is available in Arduino's Library Manager.
You can automatically install it from there.
Note: if ArduinoJson doesn't appear in Library Manager, or if only old versions are listed, try to delete the local cache. For example, on Windows, you need to delete:
* `%LOCALAPPDATA%\Arduino15\library_index.json`
* `%LOCALAPPDATA%\Arduino15\library_index.json.tmp.gz`
You don't even need to close Arduino, just re-open the library manager.
### For older Arduino IDE
You needed to [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.
**NOTE**: There are two packages the standard and the "old-layout". You need to use the "old-layout" for Arduino 1.0.X, Energia and other alternative IDE.
### For Visual Micro / Visual Studio 2015 / Atmel Studio
You need the latest version (January 2016 or later) of [Visual Micro](http://www.visualmicro.com) installed for Visual Studio or Atmel Studio.
## Run the examples sketches
Click `File` / `Example` / `ArduinoJson`.
![Screen capture of Arduino IDE](http://i.imgur.com/g5UwkVh.png)
## 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. [Decoding JSON](Decoding JSON)
2. [Encoding JSON](Encoding JSON)
🚚 This page has been moved to https://bblanchon.github.io/ArduinoJson/doc/installation/ 🚚

@@ -1,8 +1 @@
ArduinoJson is a header-only library, so you just need to [download](https://github.com/bblanchon/ArduinoJson/releases) the package and unzip it in a convenient location.
Then add the `include/` folder to your compiler's or your IDE's include directories.
See next:
1. [Parsing JSON](Decoding-JSON)
2. [Generating JSON](Encoding-JSON)
🚚 This page has been moved to https://bblanchon.github.io/ArduinoJson/doc/installation/ 🚚

@@ -1 +0,0 @@
This wiki probably contains a few mistakes, please help other users by fixing it :kissing_smiling_eyes: