2016年9月30日更新:本人移植了cJSON到ESP8266的NONOS SDK,詳情可以查看這篇文章:
http://blog.csdn.net/yannanxiu/article/details/52713746
===============================================
一、概述
這篇文章是講解如何用ESP8266官方提供的Json接口處理數(shù)據(jù)。
首先要在esp_iot_sdk/example/IoT_Demo示例目錄下找到user_json.c 和user_json.h ,把這兩個文件包含進自己的工程。
查看json.h文件,里面有一下宏定義
[cpp] ?view plaincopy print?
#define?JSON_TYPE_ARRAY?'[' ?? #define?JSON_TYPE_OBJECT?'{' ?? #define?JSON_TYPE_PAIR?':' ?? #define?JSON_TYPE_PAIR_NAME?'N'?/*?for?N:V?pairs?*/ ?? #define?JSON_TYPE_STRING?'"' ?? #define?JSON_TYPE_INT?'I' ?? #define?JSON_TYPE_NUMBER?'0' ?? #define?JSON_TYPE_ERROR?0 ??
后面的例程都是用此宏定義來判斷Json的鍵值的數(shù)據(jù)類型。
二、生成一個Json
下面給出生成Json樹的示例,生成的JSON樹get_h內(nèi)容如下:"hi":{"hello":"world"}
[cpp] ?view plaincopy print?
?? LOCAL?int ?ICACHE_FLASH_ATTR?? hello_get(struct ?jsontree_context?*js_ctx)?? {?? ????const ? char ?*path?=?jsontree_path_name(js_ctx,?js_ctx->depth?-?1);?? ????char ?string[32];?? ?? ????if ?(os_strncmp(path,? "hello" ,?5)?==?0)?{?? ????????os_sprintf(string,?"world" );?? ????}?? ?? ????jsontree_write_string(js_ctx,?string);?? ?? ????return ?0;?? }?? ?? LOCAL?struct ?jsontree_callback?hello_callback?=?? ????JSONTREE_CALLBACK(hello_get,?NULL);?? ?? JSONTREE_OBJECT(get_hello,?? ????????????????JSONTREE_PAIR("hello" ,?&hello_callback));?? JSONTREE_OBJECT(get_h,?? ????????????????JSONTREE_PAIR("hi" ,?&get_hello));??
其中宏定義JSONTREE_OBJECT是生成一個JSON數(shù)的對象,第一個參數(shù)是該對象的名稱(get_h),JSONTREE_PAIR是生成一個鍵值對的宏。
JSONTREE_CALLBACL是生成一個回調(diào)指針的宏,該宏有兩個參數(shù),第一個參數(shù)是設置讀取JSON樹的值的函數(shù),這里為hello_get函數(shù),第二個參數(shù)是設置寫入JSON樹的值的函數(shù),這里沒有用到,為NULL。
hello_get是生成JSON樹的值的函數(shù)。其中用os_strncnp進行Json鍵的判斷,如果鍵為hello,則對該鍵寫入"world"值。
這里生成的JSON是:"hi":{"hello","world"},hi是用來調(diào)用后面Json數(shù)據(jù)的:
[cpp] ?view plaincopy print?
#define?BUF_LENTH?64 ?? LOCAL?char ?buf[BUF_LENTH];?? ????json_ws_send((struct ?jsontree_value?*)&get_h,? "hi" ,?buf);?? ????os_printf("%s\n" ,buf);??
使用json_ws_send函數(shù)可以把hi后面的數(shù)據(jù)寫入buf,json_ws_send函數(shù)在IoT_demo例程中的user_json.c文件里。
最后打印結(jié)果是:
{
"hello":"world"
}
三、生成一個溫濕度Json數(shù)據(jù)
下面是一個生成溫濕度的例程:
[cpp] ?view plaincopy print?
?? LOCAL?int ?ICACHE_FLASH_ATTR?? dht11_get(struct ?jsontree_context?*js_ctx)?? {?? ????const ? char ?*path?=?jsontree_path_name(js_ctx,?js_ctx->depth?-?1);?? ????char ?string[32];?? ?? ????if ?(os_strncmp(path,? "temp" ,?4)?==?0)?? ????{?? ?????????? ????????os_sprintf(string,"25" );?? ????}?? ????else ? if (os_strncmp(path,? "hum" ,?3)?==?0)?? ????{?? ?????????? ????????os_sprintf(string,"40" );?? ????}?? ?? ????jsontree_write_string(js_ctx,?string);?? ?? ????return ?0;?? }?? ?? LOCAL?struct ?jsontree_callback?dht11_callback?=?? ????JSONTREE_CALLBACK(dht11_get,?NULL);?? ?? JSONTREE_OBJECT(get_dht11,?? ????????????????JSONTREE_PAIR("temp" ,?&dht11_callback),?? ????????JSONTREE_PAIR("hum" ,?&dht11_callback));?? JSONTREE_OBJECT(DHT11JSON,?? ????????????????JSONTREE_PAIR("dht11" ,?&get_dht11));?? ?? ?? char *?ICACHE_FLASH_ATTR?? get_dht11_json(void )?? {?? ????static ? char ?dht11_buf[64];?? ????os_memset(dht11_buf,0,64);???????? ????json_ws_send((struct ?jsontree_value?*)&DHT11JSON,? "dht11" ,?dht11_buf);?? ????return ?dht11_buf;?? }??
之后在user_init入口函數(shù)寫一個打印函數(shù)
[cpp] ?view plaincopy print?
os_printf(get_dht11_json());??
就可以看到串口打印出
{ "temp":"25", "hum":"40" }
四、一個完整的生成Json數(shù)據(jù)示例
下面是一個完整的生成Json數(shù)據(jù)的示例,可以生成字符串、整型值、數(shù)組、Json對象的Value。
Json數(shù)據(jù)的生成最重要的是理解函數(shù)回調(diào)機制,看代碼要從下往上看,如果看官接觸過異步回調(diào)機制的代碼,閱讀起來可能會有一種相似的感覺。
[cpp] ?view plaincopy print?
#include?"user_json.h" ?? #include?"ets_sys.h" ?? #include?"os_type.h" ?? #include?"osapi.h" ?? #include?"mem.h" ?? #include?"user_interface.h" ?? ?? LOCAL?int ?ICACHE_FLASH_ATTR?? jsonTree_get(struct ?jsontree_context?*js_ctx)?? {?? ????const ? char ?*path?=?jsontree_path_name(js_ctx,?js_ctx->depth?-?1);?? ?????? ?????? ????if ?(os_strncmp(path,? "String" ,?os_strlen( "String" ))?==?0)?{?? ????????jsontree_write_string(js_ctx,?"data" );?? ?????? ????}?else ? if ?(os_strncmp(path,? "Integer" ,?os_strlen( "Integer" ))?==?0)?{?? ????????jsontree_write_int(js_ctx,?1);?? ?????? ????}?else ? if ?(os_strncmp(path,? "Array" ,?os_strlen( "Array" ))?==?0)?{?? ????????int ?array[3]?=?{0,1,2};?? ????????jsontree_write_atom(js_ctx,?"[" );?? ????????jsontree_write_int_array(js_ctx,?array,?3);?? ????????jsontree_write_atom(js_ctx,?"]" );?? ????}?? ?? ????return ?0;?? }?? ?? LOCAL?int ?ICACHE_FLASH_ATTR?? jsonArray_get(struct ?jsontree_context?*js_ctx)?? {?? ????const ? char ?*path?=?jsontree_path_name(js_ctx,?js_ctx->depth?-?1);?? ?? ????if ?(os_strncmp(path,? "K1" ,?os_strlen( "K2" ))?==?0)?{?? ????????jsontree_write_string(js_ctx,?"D1" );?? ????}?else ? if ?(os_strncmp(path,? "K2" ,?os_strlen( "K2" ))?==?0)?{?? ????????jsontree_write_string(js_ctx,?"D2" );?? ????}?else ? if ?(os_strncmp(path,? "K3" ,?os_strlen( "K3" ))?==?0)?{?? ????????jsontree_write_string(js_ctx,?"D3" );?? ????}?? ?? ????return ?0;?? }?? ?? ?? ?? LOCAL?struct ?jsontree_callback?jsonArrayCallback?=?? ????JSONTREE_CALLBACK(jsonArray_get,?NULL);?? ?? JSONTREE_OBJECT(jsonArrayData,?? ????????????????JSONTREE_PAIR("K1" ,?&jsonArrayCallback),?? ????????????????JSONTREE_PAIR("K2" ,?&jsonArrayCallback),?? ????????JSONTREE_PAIR("K3" ,?&jsonArrayCallback));?? JSONTREE_ARRAY(jsonArray,?? ???????????????JSONTREE_PAIR_ARRAY(&jsonArrayData),?? ???????????????JSONTREE_PAIR_ARRAY(&jsonArrayData),?? ???????????????JSONTREE_PAIR_ARRAY(&jsonArrayData));?? ?? LOCAL?struct ?jsontree_callback?jsonCallback?=?? ????JSONTREE_CALLBACK(jsonTree_get,?NULL);?? ?? JSONTREE_OBJECT(jsonObject,?? ????????????????JSONTREE_PAIR("String" ,?&jsonCallback),?? ????????????????JSONTREE_PAIR("Integer" ,?&jsonCallback),?? ????????????????JSONTREE_PAIR("JsonArray" ,?&jsonArray));?? JSONTREE_OBJECT(jsonTestTrees,?? ????????????????JSONTREE_PAIR("String" ,?&jsonCallback),???? ?? ????????JSONTREE_PAIR("Integer" ,?&jsonCallback),??? ?? ????????JSONTREE_PAIR("Array" ,?&jsonCallback),????? ?? ????????JSONTREE_PAIR("JsonObject" ,?&jsonObject));? ?? JSONTREE_OBJECT(jsonTestTree,?? ????????????????JSONTREE_PAIR("jsonTest" ,?&jsonTestTrees));?? ?? ?? #define?LENGTH?512 ?? char *?getJsonTree( void )?? {?? ????static ? char ?jsonbuf[LENGTH];?? ????os_memset(jsonbuf,?0,?LENGTH);???????? ????json_ws_send((struct ?jsontree_value?*)&jsonTestTree,? "jsonTest" ,?jsonbuf);?? ?? ?????? ?? ????return ?jsonbuf;?? }??
該代碼會生成如下Json數(shù)據(jù):
[plain] ?view plaincopy print?
{?? ????"String":?"data",?? ????"Integer":?1,?? ????"Array":?[?? ????????0,?? ????????1,?? ????????2?? ????],?? ????"JsonObject":?{?? ????????"String":?"data",?? ????????"Integer":?1,?? ????????"JsonArray":?[?? ????????????{?? ????????????????"K1":?"D1",?? ????????????????"K2":?"D2",?? ????????????????"K3":?"D3"?? ????????????},?? ????????????{?? ????????????????"K1":?"D1",?? ????????????????"K2":?"D2",?? ????????????????"K3":?"D3"?? ????????????},?? ????????????{?? ????????????????"K1":?"D1",?? ????????????????"K2":?"D2",?? ????????????????"K3":?"D3"?? ????????????}?? ????????]?? ????}?? }??
五、從Json提取數(shù)據(jù)
如果網(wǎng)絡發(fā)送一串JSON數(shù)據(jù)給ESP8266,如何使用該接口獲取JSON的鍵值呢?下面給出示例代碼,這里使用的數(shù)據(jù)是上面生成的數(shù)據(jù)。
其中第二次的Json對象數(shù)據(jù)獲取很麻煩,所以傳給8266的Json盡量用一層,如果是數(shù)組里面再有Json對象,那么就更麻煩了,具體請看代碼。
[cpp] ?view plaincopy print?
LOCAL? int ?ICACHE_FLASH_ATTR?? jsonTree_set(struct ?jsontree_context?*js_ctx,? struct ?jsonparse_state?*parser)?? {?? ????int ?type;?? ?? ????while ?((type?=?jsonparse_next(parser))?!=?0)?{?? ?????????? ????????if ?(type?==?JSON_TYPE_PAIR_NAME)?{?? ????????????char ?buffer[64];?? ????????????os_bzero(buffer,?64);?? ?? ????????????if ?(jsonparse_strcmp_value(parser,? "String" )?==?0)?{?? ????????????????jsonparse_next(parser);??? ????????????????type?=?jsonparse_next(parser);???? ????????????????os_printf("String?Value?type?=?%c\n" ,?type);???? ?? ?? ?????????????????? ????????????????if ?(JSON_TYPE_STRING?==?type){?? ?? ????????????????????jsonparse_copy_value(parser,?buffer,?sizeof (buffer));?? ????????????????????os_printf("String?Value?=?%s\n" ,?buffer);?? ????????????????}?? ?? ????????????}?else ? if ?(jsonparse_strcmp_value(parser,? "Integer" )?==?0)?{?? ????????????????jsonparse_next(parser);?? ????????????????type?=?jsonparse_next(parser);?? ?? ?? ????????????????os_printf("Integer?Value?type?=?%c\n" ,?type);??? ?? ?????????????????? ????????????????if (JSON_TYPE_NUMBER?==?type){??? ?? ?????????????????????? ????????????????????int ?num?=?0;?? ????????????????????num?=?jsonparse_get_value_as_int(parser);?? ????????????????????os_printf("Integer?Value?=?%d\n" ,?num);????? ?? ????????????????}?? ????????????}?else ? if ?(jsonparse_strcmp_value(parser,? "Array" )?==?0)?{?? ????????????????jsonparse_next(parser);??? ????????????????type?=?jsonparse_next(parser);?? ????????????????os_printf("Array?Value?type?=?%c\n" ,?type);????? ?? ?? ?????????????????? ????????????????if (JSON_TYPE_ARRAY?==?type){???? ?? ?????????????????????? ????????????????????int ?length?=?jsonparse_get_len(parser);?? ????????????????????os_printf("Array?Length?=?%d\n" ,?length);??? ?? ?? ????????????????????int ?i;?? ????????????????????int ?num?=?100;?? ?????????????????????? ????????????????????for (i=0;?i<length;?i++){?? ????????????????????????type?=?jsonparse_next(parser);?? ?????????????????????????? ????????????????????????os_printf("Array[%d]?type?=?%c?" ,?i,?type);?? ?? ?????????????????????????? ????????????????????????if (JSON_TYPE_NUMBER==type){?? ????????????????????????????num?=?jsonparse_get_value_as_int(parser);?? ????????????????????????????os_printf("Array[%d]?=?%d\n" ,?i,?num);?? ????????????????????????}?? ?????????????????????????? ?????????????????????????? ????????????????????????else {?? ????????????????????????????os_printf("\n" );?? ????????????????????????}?? ????????????????????}?? ????????????????}?? ????????????}?? #if?1 ?? ????????????else ? if ?(jsonparse_strcmp_value(parser,? "JsonObject" )?==?0)?{?? ????????????????jsonparse_next(parser);??? ????????????????type?=?jsonparse_next(parser);?? ????????????????os_printf("JsonObject?Value?type?=?%c\n" ,?type);???????? ?? ?? ????????????????if (JSON_TYPE_OBJECT?==?type){??? ?? ????????????????????int ?length?=?jsonparse_get_len(parser);?? ????????????????????os_printf("JsonObject?Length?=?%d\n" ,?length);?? ?? ?????????????????????? ?????????????????????? ?????????????????????? ?? ?????????????????????? ????????????????????int ?i?=?0;?? ?????????????????????? ????????????????????while (type?!=? '}' ){?? ????????????????????????i++;?? ????????????????????????type?=?jsonparse_next(parser);?? ?? ????????????????????????os_printf("JsonObject[%d]?type?=?%c" ,?i,?type);?? ????????????????????????os_printf("\n" );?? ?????????????????????????? ?????????????????????????? ?????????????????????????? ?????????????????????????? ????????????????????????jsonObject_set(parser);?? ????????????????????}?? ????????????????}?? ?? ????????????}?? #endif ?? ????????}?? ????}?? ?? ????return ?0;?? }?? ?? LOCAL?int ?ICACHE_FLASH_ATTR?? jsonObject_set(struct ?jsonparse_state?*parser)?? {?? ????int ?type?=?jsonparse_get_type(parser);?? ????int ?vtype?=?parser->vtype;?? ?????? ????char ?buffer[64];?? ????os_bzero(buffer,?64);?? ?? ?????? ????if ?(vtype?==?JSON_TYPE_PAIR_NAME)?{?? ???????if ?(jsonparse_strcmp_value(parser,? "String" )?==?0)?{?? ????????????jsonparse_next(parser);??? ????????????type?=?jsonparse_next(parser);???? ?????????????? ?? ?????????????? ????????????if ?(JSON_TYPE_STRING?==?type){?? ?? ????????????????jsonparse_copy_value(parser,?buffer,?sizeof (buffer));?? ????????????????os_printf("jsonObject?String?Value?=?%s\n" ,?buffer);?? ????????????}?? ?? ????????}?else ? if ?(jsonparse_strcmp_value(parser,? "Integer" )?==?0)?{?? ????????????jsonparse_next(parser);?? ????????????type?=?jsonparse_next(parser);?? ?????????????? ?????????????? ????????????if (JSON_TYPE_NUMBER?==?type){??? ?? ?????????????????? ????????????????int ?num?=?0;?? ????????????????num?=?jsonparse_get_value_as_int(parser);?? ????????????????os_printf("jsonObject?Integer?Value?=?%d\n" ,?num);?????? ?? ????????????}?? ????????}?else ? if ?(jsonparse_strcmp_value(parser,? "JsonArray" )?==?0)?{?? ????????????jsonparse_next(parser);?? ????????????type?=?jsonparse_next(parser);?? ?????????????? ?????????????? ????????????if (JSON_TYPE_ARRAY?==?type){?? ?????????????????? ?????????????????? ????????????????int ?length?=?jsonparse_get_len(parser);?? ????????????????os_printf("JsonArray?Length?=?%d\n" ,?length);??? ?? ?? ?????????????????? ????????????????int ?i?=?0;?? ?????????????????? ????????????????while (type?!=? ']' ){i++;????? ?? ?? ????????????????????type?=?jsonparse_next(parser);?? ?? ????????????????????os_printf("JsonArray[%d]?type?=?%c" ,?i,?type);?? ????????????????????os_printf("\n" );?? ?? ?????????????????????? ????????????????????if ?(type?==?JSON_TYPE_PAIR_NAME)?{?? ???????????????????????if ?(jsonparse_strcmp_value(parser,? "K1" )?==?0)?{?? ????????????????????????????jsonparse_next(parser);??? ????????????????????????????type?=?jsonparse_next(parser);???? ?????????????????????????????? ?? ?????????????????????????????? ????????????????????????????if ?(JSON_TYPE_STRING?==?type){?? ?? ????????????????????????????????os_bzero(buffer,?64);?? ????????????????????????????????jsonparse_copy_value(parser,?buffer,?sizeof (buffer));?? ????????????????????????????????os_printf("K1?=?%s\n" ,?buffer);?? ????????????????????????????}?? ????????????????????????}?else ? if (jsonparse_strcmp_value(parser,? "K2" )?==?0){?? ????????????????????????????jsonparse_next(parser);??? ????????????????????????????type?=?jsonparse_next(parser);???? ?????????????????????????????? ????????????????????????????if ?(JSON_TYPE_STRING?==?type){?? ?? ????????????????????????????????os_bzero(buffer,?64);?? ????????????????????????????????jsonparse_copy_value(parser,?buffer,?sizeof (buffer));?? ????????????????????????????????os_printf("K2?=?%s\n" ,?buffer);?? ????????????????????????????}?? ????????????????????????}?else ? if (jsonparse_strcmp_value(parser,? "K3" )?==?0){?? ????????????????????????????jsonparse_next(parser);??? ????????????????????????????type?=?jsonparse_next(parser);???? ?????????????????????????????? ????????????????????????????if ?(JSON_TYPE_STRING?==?type){?? ?? ????????????????????????????????os_bzero(buffer,?64);?? ????????????????????????????????jsonparse_copy_value(parser,?buffer,?sizeof (buffer));?? ????????????????????????????????os_printf("K3?=?%s\n" ,?buffer);?? ????????????????????????????}?? ????????????????????????}?? ????????????????????}?? ????????????????}?? ????????????}?? ????????}?? ????}?? }?? ?? ?? ?? LOCAL?int ?ICACHE_FLASH_ATTR?? jsonArray_set(struct ?jsontree_context?*js_ctx,? struct ?jsonparse_state?*parser)?? {?? ????int ?type;?? ?? ????while ?((type?=?jsonparse_next(parser))?==?0)?{?? ?????????? ????????if ?(type?==?JSON_TYPE_PAIR_NAME)?{?? ????????????char ?buffer[64];?? ????????????os_bzero(buffer,?64);?? ?? ????????????if ?(jsonparse_strcmp_value(parser,? "K1" )?==?0)?{?? ????????????????if ?(JSON_TYPE_STRING?==?type){?? ?? ????????????????????jsonparse_copy_value(parser,?buffer,?sizeof (buffer));?? ????????????????????os_printf("K1?Value?=?%s\n" ,?buffer);?? ????????????????}?? ????????????}?else ? if ?(jsonparse_strcmp_value(parser,? "K2" )==0)?{?? ????????????????if ?(JSON_TYPE_STRING?==?type){?? ?? ????????????????????jsonparse_copy_value(parser,?buffer,?sizeof (buffer));?? ????????????????????os_printf("K2?Value?=?%s\n" ,?buffer);?? ????????????????}?? ????????????}?else ? if ?(jsonparse_strcmp_value(parser,? "K3" )==0)?{?? ????????????????if ?(JSON_TYPE_STRING?==?type){?? ?? ????????????????????jsonparse_copy_value(parser,?buffer,?sizeof (buffer));?? ????????????????????os_printf("K3?Value?=?%s\n" ,?buffer);?? ????????????????}?? ????????????}?? ????????}?? ????}?? ?? ????return ?0;?? }?? ?? ?? ?? ?? void ?ICACHE_FLASH_ATTR?? setJsonTree(char ?*json)?? {?? ????struct ?jsontree_context?js;?? ?? ????jsontree_setup(&js,?(struct ?jsontree_value?*)&jsonTestTree,?json_putchar);?? ????json_parse(&js,?json);?? }?? ?? void ?ICACHE_FLASH_ATTR?? setJsonObject(char ?*json)?? {?? ????struct ?jsontree_context?js;?? ?? ????jsontree_setup(&js,?(struct ?jsontree_value?*)&jsonObject,?json_putchar);?? ????json_parse(&js,?json);?? }??
最后要修改一下這條語句,給jsonCallback第二個參數(shù)添加jsonTree_set。
[cpp] ?view plaincopy print?
LOCAL? struct ?jsontree_callback?jsonCallback?=?? ????JSONTREE_CALLBACK(jsonTree_get,?jsonTree_set);??
打印:
String Value type = " String Value = data Integer Value type = 0 Integer Value = 1 Array Value type = [ Array Length = 5 Array[0] type = 0 Array[0] = 0 Array[1] type = ,? Array[2] type = 0 Array[2] = 1 Array[3] type = ,? Array[4] type = 0 Array[4] = 2 JsonObject Value type = { JsonObject Length = 10 JsonObject[1] type = N jsonObject String Value = data JsonObject[2] type = , JsonObject[3] type = N jsonObject Integer Value = 1 JsonObject[4] type = , JsonObject[5] type = N JsonArray Length = 9 JsonArray[1] type = { JsonArray[2] type = N K1 = D1 JsonArray[3] type = , JsonArray[4] type = N K2 = D2 JsonArray[5] type = , JsonArray[6] type = N K3 = D3 JsonArray[7] type = } JsonArray[8] type = , JsonArray[9] type = { JsonArray[10] type = N K1 = D1 JsonArray[11] type = , JsonArray[12] type = N K2 = D2 JsonArray[13] type = , JsonArray[14] type = N K3 = D3 JsonArray[15] type = } JsonArray[16] type = , JsonArray[17] type = { JsonArray[18] type = N K1 = D1 JsonArray[19] type = , JsonArray[20] type = N K2 = D2 JsonArray[21] type = , JsonArray[22] type = N K3 = D3 JsonArray[23] type = } JsonArray[24] type = ] JsonObject[6] type = }
六、代碼下載
如果想要示例代碼,可以從這里下載:http://download.csdn.net/detail/u012163234/9638834
總結(jié)
以上是生活随笔 為你收集整理的【ESP8266】使用ESP8266 NONOS SDK的JSON API 的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔 推薦給好友。