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升级篇: 关于升级篇数据校验
前言 鉴于大家都希望升级的时候加入数据校验,所以就满足大家的要求. 其实我也希望自己做的足够的稳定可靠,让大家使用起来放心. 上一节测试了一节加入校验以后的操作方式,这节来详细的说一下校验部分的代码. ...
随机推荐
- luogu P2495 [SDOI2011]消耗战 |虚树+LCA+dp
题目描述 在一场战争中,战场由n个岛屿和n-1个桥梁组成,保证每两个岛屿间有且仅有一条路径可达.现在,我军已经侦查到敌军的总部在编号为1的岛屿,而且他们已经没有足够多的能源维系战斗,我军胜利在望.已知 ...
- 用cp命令拷贝文件,源目录后带不带斜杠的区别
当我还是Linux超级傻白的时候,需要拷贝一个很大的数据集,然后再拷贝源文件夹的后面跟了一个前倾斜杠,然后就发现居然拷贝的是整个文件夹里的东西,而不是文件夹本身.事儿倒是不大,我重新建一个文件夹,把这 ...
- linux centos7下源码 tar安装mysql5.7.22或mysql5.7.20 图文详解
之前用的rpm安装的每次安装都是最新的,,,导致每次版本不统一... 现在用tar包安装5.7.22和5.7.20一样的 5.7.20之后的和之前的版本还是有点不一样的 官网地址 https:// ...
- sentry之一:sentry安装
Sentry 是一个开源的实时错误追踪系统,可以帮助开发者实时监控并修复异常问题.它主要专注于持续集成.提高效率并且提升用户体验.Sentry 分为服务端和客户端 SDK,前者可以直接使用它家提供的在 ...
- 以Integer类型传参值不变来理解Java值传参
最近在写代码的时候出了一个错误,由于对值引用理解的不深,将Integer传入方法中修改,以为传入后直接修改Integer中的值就不用写返回值接收了,虽然很快发现了问题,但还是来总结一下 首先是代码: ...
- keyword:react native bridge
js engine native react native bridge https://cn.bing.com/images/search?view=detailV2&id=AAF39636 ...
- 蒙特卡罗方法、蒙特卡洛树搜索(Monte Carlo Tree Search,MCTS)初探
1. 蒙特卡罗方法(Monte Carlo method) 0x1:从布丰投针实验说起 - 只要实验次数够多,我就能直到上帝的意图 18世纪,布丰提出以下问题:设我们有一个以平行且等距木纹铺成的地板( ...
- 深入V8引擎-初始化默认Platform
本来寻思着写一篇"'Hello' + ', World'"是怎么从JS代码编译然后输出的,然而compile过程的复杂性远超我的想象,强上怕会走火入魔,还是老老实实先回家种田,找点 ...
- 关于YII框架Response content must not be an array的解决方法
public function actionGet_permissions() { \Yii::$app->response->format = \yii\web\Response::FO ...
- python练习题:利用切片操作,实现一个trim()函数,去除字符串首尾的空格,注意不要调用str的strip()方法
方法一: # -*- coding: utf-8 -*- # 利用切片操作,实现一个trim()函数,去除字符串首尾的空格,注意不要调用str的strip()方法: def trim(s): whil ...