本系列博客学习由非官方人员 半颗心脏 潜心所力所写,仅仅做个人技术交流分享,不做任何商业用途。如有不对之处,请留言,本人及时更改。
- 1、 Esp8266之 搭建开发环境,开始一个“hellow world”串口打印。
- 2、 Esp8266之 利用GPIO开始使用按钮点亮你的“第一盏灯”。
- 3、 Esp8266之 利用 “软件定时器 ” 定时0.5秒闪烁点亮一盏LED。
- 4 、Esp8266之 了解PWM,更为深入地用PWM控制一盏LED的亮度变化。
- 5 、Esp8266之 原生乐鑫SDK高级使用之封装Post与Get请求云端,拿到“天气预报信息”。
- 6 、Esp8266之 了解 SmartConfig与Airkiss一键配网,给8266配网上云端。无需把wifi名字密码写在固件里。
- 7 、Esp8266之 了解 softAP热点配网模式原理,仿“机智云”定义自己的热点配网模式协议。
- 8、 Esp8266之 你要找的8266作为UDP、TCP客户端或服务端的角色通讯,都在这了。
- 9、 Esp8266进阶之路第一篇: [小实战上篇]Windows系统搭建8266的本地Mqtt服务器,局域网点亮一盏LED灯。
- 10、 Esp8266进阶之路第二篇: [小实战下篇]Windows系统搭建8266的本地Mqtt服务器,局域网点亮一盏LED灯。
- 11、 Esp8266进阶之路第三篇: 8266接入阿里智能,点亮一盏LED灯,期待天猫精灵语音控制的不约而至!
- 12、 Esp8266进阶之路第四篇: 图文并茂学习阿里云主机搭建8266MQTT服务器,实现移动网络远程控制一盏LED。
- 13、 Esp8266进阶之路第五篇: 动手做个8266毕设小案例,smartConfig + MQTT协议轻松实现远程控制一盏LED。
- 14、 Esp8266进阶之路第六篇: esp8266的 FreeRtos系统学习的正确姿势 —— 环境搭建、烧录。
- 15、 Esp8266进阶之路第七篇: esp8266的 物联网又一股清流,8266接入阿里云平台非阿里智能的SDS服务,点亮一盏LED灯。
- 16、 Esp8266进阶之路第八篇: esp8266的 基于Nonos移植红外线H1838,实现红外遥控器配网,远程控制一盏灯。
- 17、 Esp8266进阶之路第九篇: esp8266自研的快速上电开关五次 (开-关为一次) ,无需按键触发则8266进去一键配网模式。
- 18、 Esp8266进阶之路第十篇: esp8266 基于NONOS 实现 OTA 远程升级,实现无线“ 热修复 ”升级固件程序。
- 19、 Esp8266进阶之路第十一篇【外设篇】: esp8266驱动 ds18b20、dht11 温湿度传感器,采集温湿度传感器到服务器。
- 20、 Esp8266进阶之路第十一篇【高级篇】: 深入学习esp8266的esp now模式,仿机智云做一个小网关,实现无需网络下轻松彼此连接通讯交互数据。
- 21、 Esp8266进阶之路第十二篇【高级篇】: 浅谈 esp8266 如何在本地局域网网络情况下实现最大效率地和前端实现数据交互。
- 22、 Esp8266进阶之路第十三篇【混杂篇】: esp8266的工程如何添加第三方静态库文件以及如何自定义文件夹,聊聊那些makeFile的事。。
- 23、 Esp8266进阶之路第十四篇【高级篇】: 再来一波 esp8266 基于 freeRtos系统连接自己私有的服务器实现OTA远程升级,接触下 lwip的基本知识。。
- 24、 Esp8266进阶之路第十五篇【高级篇】: 渗透学习回顾下esp8266的外置spi芯片25q系列,熟悉8266代码块在其的分布,得心应手放置图片或其他资料。
- 25、 Esp8266进阶之路第十六篇【高级篇】: 深聊下esp8266的串口 Uart 通讯中断编程,为您准备好了 NONOS 版本 和 RTOS 系统的串口驱动文件。
- 26、 Esp8266进阶之路第十七篇【高级篇】: RTOS分析 MQTT 实现过程,实现移植 MQTT协议在 esp8266 rtos实时系统,可断线重连。
- 27、 Esp8266进阶之路第十八篇【高级篇】: 跟紧脚步,用VisualStudio Code开发 esp8266 rtos SDK v3.0版本,全新的 idf 框架,节省内存模块化开发。
- 28、 Esp8266进阶之路第十九篇【高级篇】: 教你轻松自如使用cJson在乐鑫 esp8266 如何解析一段json数据以及如何生成一段json数据。
一、前言;
大半个月没有更新博客了,最近在搞阿里的
alios-things
,终于有空更新了下博客,前几天在咱们的群看到有人问怎么剖析一段json
数据,其实在8266
这个非常容易实现。那么本文将直接带你怎么实现解析一段json
以及如何生成一段json
;
二、什么是JSON
;
这个问题其实百度一大堆,我这里浅显说下,它就是一种数据格式,注意:是数据格式,不是协议!最初来源于
JavaScript
,之后被广泛使用在各个语言中,因为它轻量小,适合数据交互;其实,在乐鑫也有提供这么一个
json
使用库,但是我一般不会去独立去研究它,因为习惯了一个非常强大著名的嵌入式专用的cJSON
库。。那么本博文也是基于cJSON
库来解析一段json数据以及如何生成一段json数据,以及注意在使用过程中的一些问题!!!
三、如何解析一段JSON
;
- 解析下面一段数据:
- 包括字符串,整型,数组型;
{
"mac": "84:f3:eb:b3:a7:05",
"number": 2,
"value": {
"name": "xuhongv",
"age": 18,
"blog": "https://blog.csdn.net/xh870189248"
},
"hexArry": [51, 15, 63, 22, 96]
}
思路:
1、先确定是否正确的
json
格式,通过网上的在线监测是否json
数据的网址:
2、我们先判断整体是否一个
json
格式数据:
// jsonRoot 是您要剖析的数据
//首先整体判断是否为一个json格式的数据
cJSON *pJsonRoot = cJSON_Parse(jsonRoot);
//如果是否json格式数据
if (pJsonRoot !=NULL) {
}
3、我们一层一层来剖析
json
格式数据:
- 3.1 先从
mac
字段开始:
//解析mac字段字符串内容
cJSON *pMacAdress = cJSON_GetObjectItem(pJsonRoot, "mac");
//判断mac字段是否json格式
if (pMacAdress) {
//判断mac字段是否string类型
if (cJSON_IsString(pMacAdress))
os_printf("get MacAdress:%s \n", pMacAdress->valuestring);
} else
os_printf("get MacAdress failed \n");
- 3.2 再到我们的
number
:
//解析number字段int内容
cJSON *pNumber = cJSON_GetObjectItem(pJsonRoot, "number");
//判断number字段是否存在
if (pNumber){
//判断mac字段是否数字整型类型
if (cJSON_IsNumber(pNumber))
os_printf("get Number:%d \n", pNumber->valueint);
}
else
os_printf("get Number failed \n");
- 3.3 再仔细看看我们的
value
,其实它里面包含的内容就是json
格式,因此我们把它当做是一个json
对象:
//解析value字段内容,判断是否为json
cJSON *pValue = cJSON_GetObjectItem(pJsonRoot, "value");
if (pValue) {
//进一步剖析里面的name字段:注意这个根节点是 pValue
cJSON *pName = cJSON_GetObjectItem(pValue, "name");
if (pName)
if (cJSON_IsString(pName))
os_printf("get value->Name : %s \n", pName->valuestring);
//进一步剖析里面的age字段:注意这个根节点是 pValue
cJSON *pAge = cJSON_GetObjectItem(pValue, "age");
if (pAge)
if (cJSON_IsNumber(pAge))
os_printf("get value->Age : %d \n", pAge->valueint);
//进一步剖析里面的blog字段:注意这个根节点是 pValue
cJSON *pBlog= cJSON_GetObjectItem(pValue, "blog");
if (pBlog)
if (cJSON_IsString(pBlog))
os_printf("get value->pBlog : %s \n", pBlog->valuestring);
}
- 3.4 下面这段就有点意思了,是解析数组,先获取里面的长度,然后逐个打印一下:
//剖析
cJSON *pArry = cJSON_GetObjectItem(pJsonRoot, "hexArry");
if (pArry) {
//获取数组长度
int arryLength = cJSON_GetArraySize(pArry);
os_printf("get arryLength : %d \n", arryLength);
//逐个打印
int i ;
for (i = 0; i < arryLength; i++)
os_printf("cJSON_GetArrayItem(pArry, %d)= %d\n",i,cJSON_GetArrayItem(pArry, i)->valueint);
}
- 看看打印:
四、如何生成一段JSON
;
生成
json
格式的方法很多种,我觉得最大效率的就是用sprintf()
函数,这个是傻瓜式,直接套模板就行了。既然说到了cJson
那么我们肯定会教大家怎么使用生成的,好吧!下面生成这个
json
格式信息,其中mac
字段的地址是根据自己的设备动态生成的,是不是有点意思?
{
"mac": "65:c6:3a:b2:33:c8",
"number": 2,
"value": {
"mac": "xuhongv",
"age": 18,
"mac": "https://blog.csdn.net/xh870189248"
},
"hex": [51, 15, 63, 22, 96]
}
- 代码比较少,我直接上全部:
//取一下本地的station的mac地址,保存在全局变量tempMessage
initGetMacAdress();
cJSON *pRoot = cJSON_CreateObject();
cJSON *pValue = cJSON_CreateObject();
//新增一个字段mac到根点,数值是tempMessage
cJSON_AddStringToObject(pRoot,"mac",tempMessage);
//新增一个字段number到根点,数值是2
cJSON_AddNumberToObject(pRoot,"number",2);
cJSON_AddStringToObject(pValue,"mac","xuhongv");
cJSON_AddNumberToObject(pValue,"age",18);
cJSON_AddStringToObject(pValue,"mac","https://blog.csdn.net/xh870189248");
cJSON_AddItemToObject(pRoot, "value",pValue);
//数组初始化
int hex[5]={51,15,63,22,96};
cJSON *pHex = cJSON_CreateIntArray(hex,5);
cJSON_AddItemToObject(pRoot,"hex",pHex);
char *s = cJSON_Print(pRoot);
os_printf("\r\n creatJson : %s\r\n", s);
//释放内存
cJSON_free((void *) s);
cJSON_Delete(pRoot);
五、cJSON
库常见的函数说明;
这里我就介绍下我们常见常用的函数说明,绝对原创:
- 1、 cJSON_Parse( const char *value );
开始识别一个字符串是否为
json
格式,返回数值就是一个cJSON
,如果返回的cJSON
为NULL
则表示不是json
格式,否则就是json
格式。
- 2、cJSON_GetObjectItem( const cJSON * const object, const char * const string );
从一个
json
格式数据剖析一个指定的字段的数据,返回数值就是一个cJSON
,如果返回的cJSON
为NULL
则表示获取失败,否则获取成功!
- 3、cJSON_IsString(const cJSON * const item);
从一个
json
格式数据判断是否为字符串类型,返回数值就是一个布尔值,如果返回false
则表示这个字段是字符串类型,否则不是!以此类推,其他的cJSON_IsBool()
、cJSON_IsNumber()
都是一样的意思!
- 3、cJSON_GetArraySize(const cJSON *array);
从一个
json
格式的数组数据获取该数组的长度。
- 4、cJSON_GetArrayItem(const cJSON *array, int index);
从一个
json
格式的数组获取该数组的指定索引的元素,index
是下标。
- 5、 cJSON_Print(const cJSON *item);
返回一个
json
格式的数据,返回时char*
类型,注意使用后要释放内存。调用cJSON_free()
即可!!
- 6、 cJSON_Delete(cJSON *c);
释放一个
json
格式的数据所占的内存,注意一般使用这个数据之后,释放根节点即可!!
- 7、 cJSON_AddStringToObject(object,name,s) ;
新增一个字符串类型字段到
json
格式的数据!name
是字段,s
是数值。
- 8、 cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item);
新增一个新的子节点
cJSON
到根节点!string
是字段名字!
六、cJSON
—–小徐告诫编程注意的问题;
1、注意每次使用(包括剖析和生成)之后,都要记得释放内存,就是调用
cJSON_Delete()
方法,否则一直在占据内存,像8266
这样的本身内存就少,运行久了就会死机的 !2、在剖析数据时候,一定要遵循规范,一定要判断是否
json
数据,而且是否想要的类型,比如字符串,整型,这些都是要认真核对。否则会造成esp8266
重启。3、在处理数组时候,一定要注意不要数组越界问题!最后,祝大家养成好的编程习惯,受益终生。
七、其他;
本博文代码下载:https://download.csdn.net/download/xh870189248/10649940
esp8266源代码学习汇总:https://github.com/xuhongv/StudyInEsp8266
esp32源代码学习汇总:https://github.com/xuhongv/StudyInEsp32
工程串口打印截图: