ESA2GJK1DH1K升级篇: 升级STM32 预热: 单片机定时 使用 http 获取云端文本文件里面的内容,然后显示在液晶屏
前言:
实现功能概要
STM32使用AT指令控制Wi-Fi以TCP方式连接咱上节安装的Web服务器,然后使用http的get协议获取云端文本文件里面的内容,
然后把获取的数据显示在OLED液晶屏.
效果图
实现功能的前提
1.在云端的电脑上的Web服务器的根目录放一个文件
注:以后Web服务器肯定还要做其它功能,所以最好在根目录多建几个文件夹,区分开各个功能,这个不用我说了吧!
我在根目录(html)建了一个 hardware文件夹-->STM32_AT8266 文件夹,然后里面放了 updatainfo.txt 文件
2.文件内容 {"version":"1.02.56"} 一个JSON格式的数据,大家随意都可以
测试一下文件是不是可以获取
http://47.92.31.46/hardware/STM32_AT8266/updatainfo.txt 根据自己的哈,这是我的
单片机如何实现
网页上是直接输入 http://47.92.31.46/hardware/STM32_AT8266/updatainfo.txt
那样输入以后端口号默认是 80,所以不需要写端口号
http://47.92.31.46/hardware:80/STM32_AT8266/updatainfo.txt 和上面的等价
实际上是先用TCP连接了IP地址: 47.92.31.46 端口号:80
然后发送:"GET /hardware/STM32_AT8266/updatainfo.txt HTTP/1.1\r\nHost: 47.92.31.46\r\n\r\n" HTTP的get协议
下图是测试截图
所以单片机只需要控制网络模块以TCP方式连接IP为: 47.92.31.46 端口号:80的服务器
然后发送 "GET /hardware/STM32_AT8266/updatainfo.txt HTTP/1.1\r\nHost: 47.92.31.46\r\n\r\n" 即可
程序下载测试
1,硬件设置: 短接STM32 PB2 和 WIFI RST (以后均采用硬件复位)
2,下载单片机程序
3,如果想让WIFI连接路由器,可直接 去掉屏蔽
如果采用以上步骤,可略过 " WIFI配网,让WIFI连接路由器 " 部分,编译下载程序后,即可实现功能!
WIFI配网,让WIFI连接路由器:
打开可以配网的APP,给Wi-Fi配网
请参考基础篇: https://www.cnblogs.com/yangfengwu/p/11760590.html
最终效果
等待大约5S 如果一直不显示可能是我动了服务器!!!
应用到自己的服务器
1.修改单片机程序访问的Web服务器的IP地址和端口号 访问文件的路径自己随意
2.按照单片机设置的访问的路径放置文件,
3.用自己的浏览器测试一下,如果测试可以获取,把程序下载到单片机即可
程序说明(不走配网步骤)
1,代码中连接的服务器信息,和获取的文件路径在这里设置的
2,去掉屏蔽,省去配网步骤
3.在 Init8266() 里面控制连接路由器
4,在AutoConnectTCP(); 里面,单片机通过AT指令配置8266以TCP透传模式方式连接Web服务器
5.进入主循环
程序说明(走配网步骤)
1,按钮按下3S执行配网
2,配网程序
3,配网成功,执行连接TCP服务器程序
注:此时主循环一直运行,使用的非阻塞框架!
注:本身主循环就是每隔5S发送一次 http get协议,有可能有人觉得上面就是多此一举,因为
其实我只是给大家一个思路,有时候第一次连接上服务器确实需要发送了个数据,告诉服务器或者别的客户端我上线了.
注意我的串口里面是处理了HTTP数据
1.这是返回的HTTP数据
HTTP/1.1 200 OK ----------可以获取数据 Server: openresty/1.15.8.2 Date: Wed, 16 Oct 2019 14:14:03 GMT Content-Type: text/plain Content-Length: 21 ----------真实数据的个数 Last-Modified: Sat, 12 Oct 2019 18:36:33 GMT Connection: keep-alive ETag: "5da21d31-15" Accept-Ranges: bytes ----------这里有个\r\n ----------这里还有个\r\n {"version":"1.02.56"} ----------真实数据
2.我写的解析函数
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) { Res =USART_ReceiveData(USART1); //读取接收到的数据 Usart1ReadBuff[Usart1ReadCnt] = Res; //接收的数据存入数组 Usart1ReadCnt++; if(Usart1ReadCnt > Usart1ReadLen -10)//防止数组溢出 { Usart1ReadCnt = 0; } Usart1IdleCnt = 0; //解析http数据-------------------------------Start //HTTP/1.1 200 OK if(!HttpHeadOK) { if(Res=='H' && HttpHeadCnt==0)HttpHeadCnt++; else if(Res=='T' && HttpHeadCnt==1)HttpHeadCnt++; else if(Res=='T' && HttpHeadCnt==2)HttpHeadCnt++; else if(Res=='P' && HttpHeadCnt==3)HttpHeadCnt++; else if(Res=='/' && HttpHeadCnt==4)HttpHeadCnt++; else if(Res=='1' && HttpHeadCnt==5)HttpHeadCnt++; else if(Res=='.' && HttpHeadCnt==6)HttpHeadCnt++; else if(Res=='1' && HttpHeadCnt==7)HttpHeadCnt++; else if(Res==' ' && HttpHeadCnt==8)HttpHeadCnt++; else if(Res=='2' && HttpHeadCnt==9)HttpHeadCnt++; else if(Res=='0' && HttpHeadCnt==10)HttpHeadCnt++; else if(Res=='0' && HttpHeadCnt==11)HttpHeadCnt++; else if(Res==' ' && HttpHeadCnt==12)HttpHeadCnt++; else if(Res=='O' && HttpHeadCnt==13)HttpHeadCnt++; else if(Res=='K' && HttpHeadCnt==14){HttpHeadOK = 1;HttpHeadCnt=0;HttpDataLength=0;} else { HttpHeadCnt=0; } } //Content-Length: XXXXXXXX if(HttpHeadOK && !HttpDataLengthOK)//获取http发过来的数据个数 { if(Res=='-' && HttpHeadCnt==0) HttpHeadCnt++; else if(Res=='L' && HttpHeadCnt==1)HttpHeadCnt++; else if(Res=='e' && HttpHeadCnt==2)HttpHeadCnt++; else if(Res=='n' && HttpHeadCnt==3)HttpHeadCnt++; else if(Res=='g' && HttpHeadCnt==4)HttpHeadCnt++; else if(Res=='t' && HttpHeadCnt==5)HttpHeadCnt++; else if(Res=='h' && HttpHeadCnt==6)HttpHeadCnt++; else if(Res==':' && HttpHeadCnt==7)HttpHeadCnt++; else if(Res==' ' && HttpHeadCnt==8)HttpHeadCnt++; else if(HttpHeadCnt>=9 && HttpHeadCnt<=16 )//最大99999999个字节. 16:99999999 17:999999999 18:9999999999 { if(Res!=0x0D) { HttpDataLength = HttpDataLength*10 + Res - '0'; HttpHeadCnt++; } else { HttpDataLengthOK = 1; HttpHeadCnt = 0; } } else { HttpHeadCnt = 0; } } //0D 0A 0D 0A if(HttpHeadOK && HttpDataLengthOK && HttpDataLength && !HttpHeadEndOK) { if(Res==0x0D && HttpHeadCnt==0)HttpHeadCnt++; else if(Res==0x0A && HttpHeadCnt==1)HttpHeadCnt++; else if(Res==0x0D && HttpHeadCnt==2)HttpHeadCnt++; else if(Res==0x0A && HttpHeadCnt==3){HttpHeadEndOK = 1;} else HttpHeadCnt = 0; } if(HttpHeadEndOK == 1)//http数据的head已经过去,后面的是真实数据 { HttpHeadEndOK=0; HttpHeadCnt = 0; HttpDataLengthOK=0; HttpRevDataOK=1;//----------------------------------证明接收到了正确的http数据了------------------------ Usart1ReadCnt=0;//串口从头开始接收数据,控制串口里面只接收真实数据 } //解析http数据-------------------------------end }