diff --git a/API-Reference.md b/API-Reference.md index 210fecf..aaa47c2 100644 --- a/API-Reference.md +++ b/API-Reference.md @@ -1 +1 @@ -🚚 The API Reference has been moved to https://bblanchon.github.io/ArduinoJson/api/ 🚚 \ No newline at end of file +🚚 This page has been moved to https://bblanchon.github.io/ArduinoJson/api/ 🚚 diff --git a/Avoiding-pitfalls.md b/Avoiding-pitfalls.md index 0b4d837..a7b1732 100644 --- a/Avoiding-pitfalls.md +++ b/Avoiding-pitfalls.md @@ -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/ 🚚 diff --git a/Compatibility-issues.md b/Compatibility-issues.md index 6de6479..be909fa 100644 --- a/Compatibility-issues.md +++ b/Compatibility-issues.md @@ -1,122 +1 @@ - - -- [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) - - - - -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' -``` - -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/ 🚚 diff --git a/Decoding-JSON.md b/Decoding-JSON.md index e12327a..cb72686 100644 --- a/Decoding-JSON.md +++ b/Decoding-JSON.md @@ -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 - -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(); - 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()`: - - if (root["extra"].is()) - { - // 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/" \ No newline at end of file +🚚 This page has been moved to https://bblanchon.github.io/ArduinoJson/doc/decoding/ 🚚 diff --git a/Encoding-JSON.md b/Encoding-JSON.md index 3ac41ab..96d0d7f 100644 --- a/Encoding-JSON.md +++ b/Encoding-JSON.md @@ -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 -``` - -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. \ No newline at end of file +🚚 This page has been moved to https://bblanchon.github.io/ArduinoJson/doc/encoding/ 🚚 diff --git a/Home.md b/Home.md index d921197..ac5dc5c 100644 --- a/Home.md +++ b/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/) @@ -29,4 +29,4 @@ #### Misc - [Contributing](Contributing) - [Projects using Arduno JSON library](Projects using ArduinoJson) -- [Donations](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=donate%40benoitblanchon%2efr&lc=GB&item_name=Benoit%20Blanchon&item_number=Arduino%20JSON¤cy_code=EUR&bn=PP%2dDonationsBF%3abtn_donate_LG%2egif%3aNonHosted) :beers: \ No newline at end of file +- [Donations](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=donate%40benoitblanchon%2efr&lc=GB&item_name=Benoit%20Blanchon&item_number=Arduino%20JSON¤cy_code=EUR&bn=PP%2dDonationsBF%3abtn_donate_LG%2egif%3aNonHosted) :beers: diff --git a/Memory-model.md b/Memory-model.md index ecb5c19..9ee4aca 100644 --- a/Memory-model.md +++ b/Memory-model.md @@ -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 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 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 | \ No newline at end of file +🚚 This page has been moved to https://bblanchon.github.io/ArduinoJson/doc/memory/ 🚚 diff --git a/Using-the-library-in-a-CMake-project.md b/Using-the-library-in-a-CMake-project.md index 72dd7c4..282d1e9 100644 --- a/Using-the-library-in-a-CMake-project.md +++ b/Using-the-library-in-a-CMake-project.md @@ -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) \ No newline at end of file +🚚 This page has been moved to https://bblanchon.github.io/ArduinoJson/doc/installation/ 🚚 diff --git a/Using-the-library-with-Arduino.md b/Using-the-library-with-Arduino.md index cbaefc6..282d1e9 100644 --- a/Using-the-library-with-Arduino.md +++ b/Using-the-library-with-Arduino.md @@ -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: - - /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 - -Then follow the instructions: - -1. [Decoding JSON](Decoding JSON) -2. [Encoding JSON](Encoding JSON) \ No newline at end of file +🚚 This page has been moved to https://bblanchon.github.io/ArduinoJson/doc/installation/ 🚚 diff --git a/Using-the-library-without-Arduino.md b/Using-the-library-without-Arduino.md index 935c379..282d1e9 100644 --- a/Using-the-library-without-Arduino.md +++ b/Using-the-library-without-Arduino.md @@ -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) \ No newline at end of file +🚚 This page has been moved to https://bblanchon.github.io/ArduinoJson/doc/installation/ 🚚 diff --git a/_Footer.md b/_Footer.md deleted file mode 100644 index 234e0ee..0000000 --- a/_Footer.md +++ /dev/null @@ -1 +0,0 @@ -This wiki probably contains a few mistakes, please help other users by fixing it :kissing_smiling_eyes: \ No newline at end of file