通信接口

json在arduino上的应用

字号+ 作者:duino123.com 来源:https://codeload.github.com/re 2016-06-20 09:45 我要评论( )

json在arduino上的应用

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.

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 Libray 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 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 installed for Visual Studio or Atmel Studio.

Run the examples sketches

Click File / Example / ArduinoJson.

Screen capture of Arduino IDE

Use the library in your sketches

Just add the following line at the top of your program:

#include <ArduinoJson.h>

Then follow the instructions:

2. 解析
 

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 or 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 theStaticJsonBuffer.

Before continuing please read the page Arduino JSON 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());
}

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/"

3. 编码
 

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:

#include <ArduinoJson.h>

For instructions on how to install the library, please read Using the library with Arduino or Using the library without Arduino.

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 theStaticJsonBuffer.

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:

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:

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 3 syntaxes for floating point values:

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'sPrint::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"] = 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:

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 aPrint 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 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:

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: HardwareSerialSoftwareSerial,LiquidCrystalEthernetClientWiFiClientWire... 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:

int len = array.measureLength();

That comes in handy when you need to calculate the Content-Length when posting JSON data over HTTP.

4. 库下载

内容来源:https://codeload.github.com/rengaoadmin/ArduinoJson/zip/master 

如需更详细资料,如有好资源分享,请加入QQ交流群:214461008

欢迎阅读,欢迎转载,不用注明出处!本站只提供入门和进阶资料,做您学习的小伙伴!

老司机也欢迎光临指导!有好内容请加群:214461008 不要看声明了,看内容吧!

相关文章
  • 两块Arduino之间通过SPI通信

    两块Arduino之间通过SPI通信

    2016-06-01 13:02

  • 常见的几种arduino型号的IIC引脚定义

    常见的几种arduino型号的IIC引脚定义

    2016-05-29 14:40

  • Arduino软串口的使用

    Arduino软串口的使用

    2016-05-04 15:27

  • [2016.05.04]Arduino串口从基础到高级最全面教程

    [2016.05.04]Arduino串口从基础到高级最全面教程

    2016-05-05 14:14

网友点评
Arduino