查看: 1570|回复: 3

【麒麟传说】基于51核STC12C5A60S2 单片机的HTTP数据上传

  [复制链接]

3

主题

7

帖子

24

积分

新手上路

Rank: 1

积分
24
发表于 2018-12-12 14:35:35 | 显示全部楼层 |阅读模式
STC12单片机作为国产单片机中的战斗机,性价比很高,但内核为51,不像ARM单片机有库函数可以很方便的调用。用它作下位机实现ONENET平台连接,串口1用作调试,串口2用作与wifi或sim模块通信,程序思路是(1)封装底层的串口函数,(2)移植ESP8266或SIM800C的AT控制指令,(3)移植HTTP协议包
(1)      串口封装函数
主要是初始化,接收中断,和发送函数,串口2接收数据缓存区加上清空函数
extern  u8 Uart1_Buf[Buf1_Max];//串口1数据缓存区
extern u8 Uart2_Buf[Buf2_Max];//串口2数据缓存区
extern u8 Cnt_Uart1;
extern u8 First_Int ;
extern u8 First_IntPre;
void Uart1Init(void);
void Uart2Init(void);
void UART1_SendData(u8 dat);
void UART1_SendString(char *s);
void UART2_SendData(u8 dat);
void UART2_Send_Len(unsigned char *s,u8 len);
void CLR_Buf2(void);
(2)      ESP8266 WIFI 模块程序移植
ESP8266 WIFI模块使用标准AT指令集,在STC12程序中只要串口函数封装成功,后面只需要调用串口给ESP8266发送AT指令就行,但需要注意STC12毕竟是8位的51内核,性能远不如STM32,所以声明数据寄存器时不能太大,之前定义Send_Buf[512]用作上传平台数据寄存,就发现程序跑飞,但改小为256程序就稳定了。
ONENET开发文档接入帮助里有用调试工具连接平台提供了简明易懂的接入实验(注意所有AT指令后必须换行):
第一步:依次发送如下几个命令对WIFI模块进行配置:
AT+CWMODE=3//设置WIFI应用模式
AT+RST//重置WIFI模块
AT+CIFSR//查询本地IP
AT+CWJAP=\"yourssid\",\"password\" //连接无线路由器
注意:这些配置是ESP8266的本地配置,完成后,若模块重新上电,可直接进入第二步,与服务器建立TCP连接。
第二步:和OneNet服务器建立TCP连接,依次发送命令:
AT+CIPSTART=\"TCP\",\"183.230.40.33\",80  //和服务器建立TCP连接
AT+CIPMODE=1    //进入透明传输模式
AT+CIPSEND  //开始传输
按照连接帮助,到此,我们可以发送前面准备好的数据了,发送HTTP数据报为:
POST/devices/11333253/datapoints HTTP/1.1
api-key:EiDCwj4OMZgZ6hsnYorJbcKn22o=
Host:api.heclouds.com
Content-Length:63

{\"datastreams\":[{\"id\":\"sys_time\",\"datapoints\":[{\"value\":50}]}]}
但发现返回结果并不成功:

经过实验,采用如下格式发现数据能上传成功:
POST/devices/11333253/datapoints?type=3 HTTP/1.1
api-key:EiDCwj4OMZgZ6hsnYorJbcKn22o=
Host:api.heclouds.com
Content-Length:32

{\"LIGHT\":\"124\"}

file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image005.jpg
file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image007.jpg
该返回结果说明,本次上传数据成功,数据上传成功后,OneNet服务器会保持TCP连接,那么下次进行数据传送,并不需要重复第二步。
实验成功后程序设计就好办了,做如下两个函数:

file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image009.jpg
file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image011.jpg
初始化用来配置wifi,建立TCP连接,数据发送函数用来传输数据。
(3)      HTTP协议移植
论坛提供很多HTTP数据封装的SDK,但这些SDK主要针对ARM单片机,移植51核的STC12上发现缺少很多底层库函数支持,没办法只有去查阅RESTfulAPI接口文档,自己手动封装,HTTP协议移植需要参考ONENET提供的文档:OneNet接入方案与RESTfulAPI接口。简单来说该文档解释了怎么传数据,ONENET服务器才不会拒绝你。
刚看到这个文档的时候,作为一个上网都只知道通过百度的通信小白,我打算从入门到放弃……
但是功夫不负有心人,重点从来不在正文中。在后面的说明里,我发现了如下片段:
1)        为了节省流量,增加数据点支持如下简写方式。在请求的URL中增加type字段,指示所使用的简写方式。目前type支持3,4,5三种情况
n  http://<API_ADDRESS>/devices/<device_id>/datapoints?type=3
{“temperature”:22.5,”humidity”:”95.2%”}
表示在数据流temperature中增加一个数据点22.5,在humidity中增加一个数据点95.2%。
n  http://<API_ADDRESS>/devices/<device_id>/datapoints?type=4
{“temperature”:{“2015-03-22T22:31:12”:22.5}}
表示在数据流temperature中加一个数据点,在2015年2月22日22点31分12秒的值为22.5
n  http://<API_ADDRESS>/devices/<device_id>/datapoints?type=5
,;temperature,2015-03-22T22:31:12,22.5;102;pm2.5,89;10
file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image012.png
简写方式理解起来就简单多了,
结合简单数据包例子说明如何封装:
数据包由两部分构成:包头+内容,中间空行不能省略
如下:
file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image014.jpg
POST表示的是HTTP的操作方式,主要有GETPOSTPUTDELETE,我们这里只用到POST新增,就是在ONENET上创建个新的数据点;datapoints?type=3表示简写数据类型,选择3就按照3对应的格式将所有数据串成一个规定的字符串,不同类型形式不同,例如:
file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image016.jpg
HTTP/1.1 表示HTTP1.1协议,使用的是长连接,这样下位机发送完一次数据后ONENET服务器并不会立即关闭TCP连接,一定时间内发送不需要重新建立TCP; Content-Length表示后面内容的字符串大小,必须准确,否则平台不能解析,字符串大小编程时容易获得,调试时可以直接将内容粘贴到word里面查看字符数。
搞清以上原理过后手动封装起来就很简单,封装函数见附件工程onenet.c文件

来源: 【麒麟传说】基于51核STC12C5A60S2 单片机的HTTP数据上传
回复

举报

1

主题

7

帖子

20

积分

新手上路

Rank: 1

积分
20
发表于 2019-2-10 14:56:23 | 显示全部楼层
guidianren 发表于 2019-1-7 08:46
多此一举,8266跑160兆,本身就可以做单片机使用,直接用http就能发数据。52连提鞋都不够啊。 ...

ao

0

主题

3

帖子

9

积分

新手上路

Rank: 1

积分
9
发表于 2019-1-7 08:46:28 | 显示全部楼层
多此一举,8266跑160兆,本身就可以做单片机使用,直接用http就能发数据。52连提鞋都不够啊。

20

主题

900

帖子

1677

积分

金牌会员

Rank: 6Rank: 6

积分
1677
发表于 2018-12-12 16:05:14 | 显示全部楼层
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表