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 OK ----------可以获取数据
Server: openresty/1.15.8.2
Date: Wed, Oct :: GMT
Content-Type: text/plain
Content-Length: 21 ----------真实数据的个数
Last-Modified: Sat, Oct :: 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 -)//防止数组溢出
{
Usart1ReadCnt = ;
}
Usart1IdleCnt = ; //解析http数据-------------------------------Start
//HTTP/1.1 200 OK
if(!HttpHeadOK)
{
if(Res=='H' && HttpHeadCnt==)HttpHeadCnt++;
else if(Res=='T' && HttpHeadCnt==)HttpHeadCnt++;
else if(Res=='T' && HttpHeadCnt==)HttpHeadCnt++;
else if(Res=='P' && HttpHeadCnt==)HttpHeadCnt++;
else if(Res=='/' && HttpHeadCnt==)HttpHeadCnt++;
else if(Res=='' && HttpHeadCnt==)HttpHeadCnt++;
else if(Res=='.' && HttpHeadCnt==)HttpHeadCnt++;
else if(Res=='' && HttpHeadCnt==)HttpHeadCnt++;
else if(Res==' ' && HttpHeadCnt==)HttpHeadCnt++;
else if(Res=='' && HttpHeadCnt==)HttpHeadCnt++;
else if(Res=='' && HttpHeadCnt==)HttpHeadCnt++;
else if(Res=='' && HttpHeadCnt==)HttpHeadCnt++;
else if(Res==' ' && HttpHeadCnt==)HttpHeadCnt++;
else if(Res=='O' && HttpHeadCnt==)HttpHeadCnt++;
else if(Res=='K' && HttpHeadCnt==){HttpHeadOK = ;HttpHeadCnt=;HttpDataLength=;}
else
{
HttpHeadCnt=;
}
} //Content-Length: XXXXXXXX
if(HttpHeadOK && !HttpDataLengthOK)//获取http发过来的数据个数
{
if(Res=='-' && HttpHeadCnt==) HttpHeadCnt++;
else if(Res=='L' && HttpHeadCnt==)HttpHeadCnt++;
else if(Res=='e' && HttpHeadCnt==)HttpHeadCnt++;
else if(Res=='n' && HttpHeadCnt==)HttpHeadCnt++;
else if(Res=='g' && HttpHeadCnt==)HttpHeadCnt++;
else if(Res=='t' && HttpHeadCnt==)HttpHeadCnt++;
else if(Res=='h' && HttpHeadCnt==)HttpHeadCnt++;
else if(Res==':' && HttpHeadCnt==)HttpHeadCnt++;
else if(Res==' ' && HttpHeadCnt==)HttpHeadCnt++;
else if(HttpHeadCnt>= && HttpHeadCnt<= )//最大99999999个字节. 16:99999999 17:999999999 18:9999999999
{
if(Res!=0x0D)
{
HttpDataLength = HttpDataLength* + Res - '';
HttpHeadCnt++;
}
else
{
HttpDataLengthOK = ;
HttpHeadCnt = ;
}
}
else
{
HttpHeadCnt = ;
}
} //0D 0A 0D 0A
if(HttpHeadOK && HttpDataLengthOK && HttpDataLength && !HttpHeadEndOK)
{
if(Res==0x0D && HttpHeadCnt==)HttpHeadCnt++;
else if(Res==0x0A && HttpHeadCnt==)HttpHeadCnt++;
else if(Res==0x0D && HttpHeadCnt==)HttpHeadCnt++;
else if(Res==0x0A && HttpHeadCnt==){HttpHeadEndOK = ;}
else HttpHeadCnt = ;
} if(HttpHeadEndOK == )//http数据的head已经过去,后面的是真实数据
{
HttpHeadEndOK=;
HttpHeadCnt = ;
HttpDataLengthOK=; HttpRevDataOK=;//----------------------------------证明接收到了正确的http数据了------------------------
Usart1ReadCnt=;//串口从头开始接收数据,控制串口里面只接收真实数据
}
//解析http数据-------------------------------end }

ESA2GJK1DH1K升级篇: 升级STM32 预热: 单片机定时 使用 http 获取云端文本文件里面的内容,然后显示在液晶屏的更多相关文章
- ESA2GJK1DH1K升级篇: 升级STM32 预热: 单片机每隔一定时间 使用 http 获取天气
前言: 实现功能概要: STM32使用AT指令控制Wi-Fi以TCP方式连接服务器(YY天气Web服务器),然后使用http的get协议获取今天的天气数据 单片机提取今天的温度和湿度数据,把温湿度数据 ...
- ESA2GJK1DH1K升级篇: STM32远程乒乓升级,基于GPRS模块AT指令TCP透传方式,定时访问升级(含有数据校验)
实现功能概要 单片机定时使用http访问云端的程序版本,如果版本不一致, 然后通过http下载最新的升级文件,实现远程升级STM32程序. 兼容Air202 ,SIM800 测试准备工作(默认访问我的 ...
- ESA2GJK1DH1K升级篇: STM32远程乒乓升级,基于(GPRS模块AT指令TCP透传方式),定时访问升级(兼容Air202,SIM800)
实现功能概要 单片机定时使用http访问云端的程序版本, 如果版本不一致,然后通过http下载最新的升级文件,实现远程升级STM32. 兼容Air202,SIM800 测试准备工作(默认访问我的服务器 ...
- ESA2GJK1DH1K升级篇: STM32远程乒乓升级,基于(Wi-Fi模块AT指令TCP透传方式),MQTT通信控制升级
实现功能概要 前面的版本都是,定时访问云端的程序版本,如果版本不一致,然后下载最新的升级文件,实现升级. 这一节,在用户程序里面加入MQTT通信,执行用户程序的时候,通过接收MQTT的升级命令实现升级 ...
- ESA2GJK1DH1K升级篇: STM32远程乒乓升级,基于GPRS模块(Air202,SIM800)AT指令TCP透传方式,MQTT通信控制升级
实现功能概要 这节和上一节的功能一样(只不过上节是利用Wi-Fi模块,这节是利用GPRS模块) 用户程序里面加入MQTT通信,执行用户程序的时候, 通过接收MQTT的升级命令实现升级. 凡是可以实现M ...
- ESA2GJK1DH1K升级篇: STM32远程乒乓升级,基于WIFI模块AT指令TCP透传方式,定时访问升级(含有数据校验)
实现功能概要 定时使用http访问云端的程序版本,如果版本不一致,然后通过http下载最新的升级文件,实现升级. 测试准备工作(默认访问我的服务器,改为自己的服务器,请看后面说明) 一,下载BootL ...
- ESA2GJK1DH1K升级篇: STM32远程乒乓升级,基于(WIFI模块AT指令TCP透传方式),定时访问升级
前言 学习此代码所需: 实现功能概要 定时使用http访问云端的程序版本,如果版本不一致,然后通过http下载最新的升级文件,实现升级. 测试准备工作(默认访问我的服务器,改为自己的服务器,请看后面说 ...
- ESA2GJK1DH1K升级篇: 阿里云物联网平台 OTA: 关于阿里云物联网平台 OTA 的升级流程
前言 鉴于有些用户直接想使用现成的物联网平台实现 OTA 远程升级 我就写一写这系列的文章 注意:首先大家必须把我自建服务器是如何实现的看明白! 我看了下阿里云提供的,实际上流程和咱自建实现的差别不大 ...
- ESA2GJK1DH1K升级篇: 关于升级篇数据校验
前言 鉴于大家都希望升级的时候加入数据校验,所以就满足大家的要求. 其实我也希望自己做的足够的稳定可靠,让大家使用起来放心. 上一节测试了一节加入校验以后的操作方式,这节来详细的说一下校验部分的代码. ...
随机推荐
- springboot mybatis常见异常及处理方法
1.in导致的异常 Data truncation: Truncated incorrect DOUBLE value: 异常过程: mapper接口如下: public int updateBatc ...
- PHP接口并发测试的方法
PHP接口并发测试的方法 <pre> header('Content-type:text/html; Charset=utf-8'); $uri = "输入你的url" ...
- docker命令集合
#docker安装yum -y install docker-iodocker --version #启动Docker进程systemctl start dockersystemctl status ...
- 明解C语言 入门篇 第九章答案
练习9-1 /* 将字符串存储在数组中并显示(其2:初始化) */ #include <stdio.h> int main(void) { char str[] = "ABC\0 ...
- OCC与MVCC 的区别
一.前言 在数据库中,并发控制是指在多个用户/进程/线程同时对数据库进行操作时,如何保证事务的一致性和隔离性的,同时最大程度地并发. 当多个用户/进程/线程同时对数据库进行操作时,会出现3种冲突情形: ...
- scala练习题--万年历
使用方法去完成 import scala.io.StdIn object work1 { def main(args: Array[String]): Unit = { // 1.先输出提示语句,并 ...
- 【翻译】tus----一个可续传文件上传的开放协议
tus tus是一个可续穿文件上传协议,它以Http协议为载体,统一了一个文件断点续传的标准. 这篇文章翻译自https://tus.io/ 目前该协议版本信息如下: Version: 1.0.0 ( ...
- HTML Web Workers
Web worker 是运行在后台的 JavaScript,不会影响页面的性能. 什么是 Web Worker? 当在 HTML 页面中执行脚本时,页面是不可响应的,直到脚本已完成. Web work ...
- 关于html的相关讲解
浏览器chrome Chrome它内部有一个解析器,这个解析器就是解析我们的代码,各个浏览器的内核不一样,所以存在浏览器的兼容.这个内核是一个引擎. 谷歌的内核是webkit 引擎是v8. 客户端的请 ...
- 隐马尔科夫模型(Hidden Markov Models) 系列之一
转自:http://blog.csdn.net/eaglex/article/details/6376826 介绍(introduction) 通常我们总是对寻找某一段时间上的模式感兴趣,这些模式可能 ...