一种基于ESP8266与USART HMI的通用WIFI物联网接入方式
2020-09-10卢光钰
卢光钰
摘要:本文在USART HMI串口触摸屏、正点原子MINI STM32F103RCT6单片机开发板、正点原子WIFI模块ATK-ESP8266的硬件基础上,通过C语言malloc函数动态分配内存存储WIFI账号密码的基本方法,解决了8266灵活动态输入WIFI账号密码问题,从而提高了以8266模块为核心的物联网客户端设备的实用性。
关键词:ESP8266 WIFI malloc USART HMI
物聯网作为进行信息交换和通信的新型平台,其基础技术在于客体(信息、物体、数据等)与互联网的连接。ESP8266 系列模组是安信可(Ai-thinker)公司采用乐鑫ESP8266芯片开发的一系列WIFI模组模块,专为移动设备、可穿戴电子产品和物联应用设计。ESP8266(以下简称8266)在TCP client透传模式,即客户端模式下,可以通过单片机串口输入一系列AT指令进行操作,连接WIFI网络与远端服务器相互通讯,从而完成数据上传的功能。基本步骤为:
1,单片机向8266输入AT+CWMODE=1;(设置8266为STA模式)
2,输入AT+RST;(8266重启)
3,输入AT+CWJAP=“SSID”,“11111111”;(输入WIFI账号密码)
4,输入AT+CIPSTART=“TCP”,“183. 230. 40. 33”,80;(输入远端服务器IP与端口号,此处为中移动ONEnet物联网平台IP与端口号)
5,输入AT+CIPMODE=1;(开启透传模式)
6,输入AT+CIPSEND;(开始透传)
7,输入网络报文信息。
在步骤3中,WIFI的账号密码要事先在单片机程序中确定,当8266连接到其他WIFI网络时,需要在源程序中更改账号密码,再烧入单片机中,在很大程度上影响了8266设备的通用性与便利性。
本文在USART HMI串口触摸屏、正点原子MINI STM32F103RCT6单片机开发板、正点原子WIFI模块ATK-ESP8266的硬件基础上,通过C语言malloc函数动态分配内存存储WIFI账号密码的基本方法,解决了8266灵活动态输入WIFI账号密码问题,从而提高了以8266模块为核心的物联网客户端设备的实用性,具体方法如下文所示。
1 USART HMI触摸屏功能设计
USART HMI触摸屏是一款以STM32F030CRT6为核心的可编程LCD电容式触摸屏,用户可以通过USART HMI上位软件对其进行编程,运用按钮、进度条、切图、文本等组件,实现对下位单片机的控制、采样、显示等功能,触摸屏与单片机之间通过RXTX串口进行通信。本文中的USART HMI有两大基本功能:1,将外置传感器的参数显示在主界面上;2,点击主界面右下角“WIFI”按钮时,进入WIFI登录界面,输入账号密码,点击”OK”,USART HMI将账号密码信息通过串口3上传给单片机并切回到主界面。如图1、2所示:
USART HMI在上电时,因为电压不稳定,可能会发送几帧乱码,影响单片机识别,所以设置触摸屏初始化事件为“printh 0d 0a”,即发送两帧结束符使单片机能够接收完乱码,不让乱码掺杂在正常数据代码之中,后期在正常数据码前端设置标志帧使单片机能够正确分辨。
主界面的传感器数据通过文本控件显示,设置为n0,设置传感器数据变量名称为k,则单片机输入的命令为printf("n0.val=%d\xff\xff\xff",k),三个0xff为结束符,否则USART HMI不能识别。设置右下方图片控件p0为WIFI图标,弹起事件为“page 1”,即转换到WIFI登陆界面。
如图3所示,WIFI登录界面由SSID账号输入栏、PAS密码输入栏、0-9全数字键盘、A-Z全字母键盘、下划线、中折线、CAP大小写切换按键、BS删除键、OK发送键组成,能够满足一般WIFI账号密码输入要求。SSID账号与PAS密码使用文本控件,用ASCII码发送。设置一个切换变量va0,SSID按钮与PAS按钮改变va0的值,当全键盘上的字母与数字键按下时,判断va0的值,决定按下的文本出现在SSID栏或者PAS栏中。另外设置一个变量va1,通过按钮CAP键改变变量va1的值,设置一个黄色CAP键与一个红色CAP键上下叠加,分别对应一个不同的变量va1的值,一个CAP键按下时,自身就通过vis命令隐藏,显露出另一个CAP键,以实现CAP键切换以及字母大小写切换,字母按钮按下时,根据va1的值,来决定输出字符的大小写。
OK键按下时,完成对账号密码信息的发送,按下事件中的代码为:
printh 4c 47 59/prints t0.txt,0/printh 22 2c 22/prints t1.txt,0/printh 22/printh 0d 0a page main
例如当SSID为123,PAS为111时,发送的ASCII码为:
4c 47 59 31 32 33 22 2c 22 31 31 31 22 0d 0a
即为LGY123”,”111”,LGY为标志位,代表此帧数据为正常数据而非乱码。
2 单片机C程序设计
在stm32单片机中,AT指令是通过数组的形式发送的。在纯C语言编程中,在定义数组的时候,必须同时定义数组的大小,因为C语言本身没有提供动态数组这种数据结构。但是不同用户的SSID账号与密码长度并不一致,如果定义一个比较长的数组AT3[],将USART HMI传来的信息强行赋值,会在数组尾部产生空位,使AT指令无效。
因此,使用malloc函数解决此问题,malloc函数是一种分配长度为num_bytes字节的内存块的函数,可以向系统申请分配指定size个字节的内存空间。malloc的全称是memory allocation,中文叫动态内存分配,当无法知道内存具体位置的时候,想要绑定真正的内存空间,就需要用到动态的分配内存。
具体方法为:1,首先添加头文件#include "stdlib.h",malloc函数在此头文件中定义;2,定义指向数组AT3的指针char *AT3;定义整型变量WW,作为数组AT3的动态长度数值,在正点原子的串口例程中,定义串口3接收标志变量USART3_RX_STA为u8型,前5位为串口3接收到的数组长度,长度可以通过length = USART3_RX_STA&0x3f;语句得到,而如前文所示,输入账号密码的AT指令的前10位字段AT+CWJAP=”是固定不变的,然后再扣除3位标志位”LGY”,可知AT3的长度值WW=length+7。
3,通過语句AT3=(char*)malloc(sizeof(int)*WW);即可完成定义动态数组,相当于定义char AT3[WW]。
4,将AT+CWJAP=”依次赋值到AT3[0]到AT3[9],如AT3[0]=0x41;AT3[1]=0x54...直至AT3[9]=0x22;最后通过双循环赋值语句:
for(i=10,j=3;i<7+length,j<length;i++,j++)
{
AT3[i]=USART3_RX_BUF[j]; /*对数组进行赋值操作*/
}
完成对AT3[WW]的定义赋值操作。
最后说明整个main函数的基本流程与单片机-ESP8266通讯的基本方法。当单片机向ESP8266发送AT指令时,ESP8266都会产生相应的响应,如发送AT1:AT+CWMODE=1;(设置8266为STA模式)时,8266会返回字符数组“OK”,如果单片机检测到“OK”,说明8266成功完成了AT1操作,单片机可以继续发送AT2指令,以此类推。当最后开始透传指令AT7[]={"AT+CIPSEND\r\n"};响应成功之后,发送网络报文:
char postT[]={
“POST /devices/39163308/datapoints?type=3 HTTP/1.1 \r\n”
“api-key:E6uOnPTftKQX=KwIfO8BHnL63mg=\r\n”
“Host:api.heclouds.com\r\n”
“Content-Length:50\r\n”
“\r\n”
“{\“001\”:50.5,\“002\”:50.6,\“003\”:506}\r\n”
即可将传感器数据发送至设备ID为39163308,
api-key为E6uOnPTftKQX=KwIfO8BHnL63mg=的ONENET物联网平台应用的数据流001、002、003中,此处数据固定为50.5、50.6和506.传感器数据需要重新赋值到网络报文数组相应位中。id与api-key可在onenet平台自由申请,具体方法不赘述,最后需要注意设备供电应该稳定充足,否则8266不能正常工作。
通过串口助手连接8266的TX端,监控8266返回给单片机的响应信息,如图4、5所示,可见8266成功识别所有AT指令,并且成功与上位服务器连接,发送网络报文。
如图6所示,ONENET物联网平台成功接收到了8266传来的数据信息,实现了远程监控功能。
使用本文提出的方法,可以方便实现8266的WIFI连接,用户不需要改写各户端设备的源程序,自行在触摸屏输入SSID账号与密码即可,提高了8266设备的实用性。设备可以方便接入各种传感器接口,采集温湿度、甲醛含量、用电量等等,有很强通用性,工程技术人员可以参考使用。