esp8266制作太空人天气时钟
Posted 云中志
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了esp8266制作太空人天气时钟相关的知识,希望对你有一定的参考价值。
背景
简单来说,就是最近太闲了,然后下班也无所事事,在B站上刷着一众up
们的diy
视频,一次又一次地激起了我应该做点啥的想法,于是在这一阵又一阵的激励下,我再次燃起了对diy
硬件的兴趣,于是我便又一次把自己年前买到的一些硬件翻出来,开始自己的新一轮arduino
之旅。
材料准备
本次项目的总成本不到30RMB
,esp8266
开发板的成本13RMB
,1.3
寸IPS
屏幕成本15RMB
esp8266
开发板- 杜邦线
6
条 1.3
寸TFT
屏幕一个(ST7789
)
准备工作
接线
接线对应关系如下:
TFT | esp8266 | 备注 |
---|---|---|
GND | G | |
VCC | 3V | |
SCL | D5 | |
SDA | D7 | |
RES | D4 | |
DC | D3 |
视频发出来之后,有好多小伙伴在问如何接线,这里我放出一张实物的接线示意图,各位小伙伴直接对照图片进行连接即可:
依赖库
安装TFT_eSPI
库,这里算是arduino
的最基本操作了,我们就不展开了。
如果对esp8266
的开发环境还有疑问的小伙伴可以看下我之前发出来了的相关内容:
https://zhuanlan.zhihu.com/p/589448075
运行测试用例
这里运行测试用例的意义是为了验证我们的接线和环境配置是否正常
修改配置
运行测试用例前,我们要先修改Arduino\\libraries\\TFT_eSPI
下的User_Setup.h
文件,修改这个文件的作用是配置屏幕的相关数据,确保代码可以驱动我们的屏幕,主要包括屏幕驱动版本、分辨率和屏幕引脚定义,具体修改的点如下:
- 驱动文件设置:这里根据
TFT
屏幕的驱动版本选择
- 屏幕分辨率:这里也是根据屏幕参数选择
- 引脚设置:这里只需要设置
dc
和rst
引脚即可,要和接线部分的引脚相对应
其余配置项保持默认即可。
运行测试用例
选择一个示例,这里我们选择Colour_test
然后选择串口和开发板,上传即可。如果接线和代码都没有问题,那么屏幕会显示如下图像:
至此,我们的准备工作告一段落,下面开始我们的代码编写。
开始撸代码
本项目是基于esp8266和IPS彩屏的一个桌面天气时钟,项目代码基于嘉立创开源平台的《ESP8266太空人天气时钟》源码,优化了其中HTTPClient的报错,代码本身未作大的调整,项目地址如下:
https://oshwhub.com/nanxiangxiao/tai-kong-ren-shi-zhong_copy
本次项目演示的代码仓库如下:
https://github.com/Syske/esp8266-click-weather-ips
下面我们简单介绍下代码的修改点,确保各位小伙伴看了之后就可以直接点亮。这里我们要修改的文件只有一个——click-weather.ino
,由于代码本身内容过多,这里我们只贴出需要修改的部分:
wifi相关信息
这里把wifi
改成你自己的,之后直接上传代码即可。
关于城市编码
在实际测试过程中,发现ip
识别城市会有异常的情况,这时候我们可以通过配置城市编码的方式来解决,当然也需要将根据ip
获取城市编码的相关代码注释掉
城市的编码信息可以从下面这个地址中搜索:
https://gitee.com/sysker/LocationList/blob/master/China-City-List-latest.csv
至此,我们本次的项目基本上就结束了。
其他修改点
如果只是想复刻项目的小伙伴,以下内容可以不关注,这里说的是我在原代码基础上的优化点。其实这里的优化点和没有优化一样,因为这里所谓的优化点应该是由于httpClient
版本问题,优化的原因是原代码在编译过程中报错了,然后我根据错误提示做了简单的调整:
错误的意思是HTTPClient
的begin(URL)
过期了,推荐我们使用begin(WiFiClient, url)
,所以我的优化点就是改成了新方法:
- 首先实例化一个
WiFiClient
- 然后替换所有调用
begin
方法的地方,之后成功编译代码
简单总结
本次项目的难点有两个,第一个是esp8266
点亮屏幕部分的配置和接线,这一块如果顺利,本次项目基本上就算完成了70%
;第二个就是项目源码的修改和上传,这块要求对arduino
和C++
的基础知识,但是参照本教程也可以顺利完成。好了,关于这个项目,我们就先说这么多,有疑问的小伙伴可以留言,我们一起探讨交流。
最后,说点题外话,今天登录公众号,看到有小伙伴问为啥停更了,我看了下更新记录,从去年12月17日之后,公众号就没有再更新过相关内容,原因有两个:
- 客观因素:确实没有太多时间来做自己的事情,但是这一点我就可以反驳自己,毕竟二月份和三月份也没咋加班,周六周天更不会去加班,所以更多的还是主观因素
- 主观因素,主要我自己感觉挺迷茫的,不知道应该如何去学习。随着工作的不断深入和积累,慢慢发现其实我们日常工作中,更多的是写业务代码,而对于技术层面的提升,单靠毅力是不行的,我更喜欢的方式是带着问题去学习,然后在解决问题之后复盘总结,所以我技术分享产出最多的时候,其实是刚入职那会。
在这种迷茫的情绪下,这四个月我虽然没有分享技术内容,但也按照自己的兴趣和主观意愿,做了一些事情:
python
脚本的能力有了很大的提升,效率也高了:得益于最近一段时间处理线上工单,经常要处理数据,导出数据B
站分享了一些arduino
项目linux card
那个项目,我已经打了五版了,目前串口和芯片都可以识别,但是uboot还有点问题,后面还要研究下- 整理了自己的读书笔记,后面有机会可以分享一些我的摘录
- 维修了一些小玩意:老旧的收音机,十年前买的卡片相机,更换了鼠标滚轮
- 读书,刷纪录片
虽然差不多四个月没更新内容了,但你问我还愿意去做技术分享吗?我的答案其实还是很确定的,我打心里愿意,作为一个热爱技术的人,我可以为了解决一个技术问题熬夜,查各种技术文档,甚至好几天都思考这个问题,在我看来这一切的付出都是值得的,因为在解决问题的那一瞬间,我可以享受到属于自己的喜悦、幸福和成就感。
在看到小伙伴的留言之后,我决定做点什么,我打算先把最近自己在其他平台发布的内容同步下,同时也打算开始不定期更新一些内容,内容包括但不限于java
、python
、arduino
、工具使用等等,最后非常感谢各位小伙伴的支持,让我们一起成长吧!
基于STM32与ESP8266的太空人WiFi天气时钟(代码开源)
前言:本文为手把手教学ESP8266著名开源项目——太空人WiFi天气时钟,不同的是本次项目采用的是STM32作为MCU。两者开发过程中有因为各自芯片的特点(时钟频率,内存大小等),导致开发程序大不相同,很多地方需要特殊设计一下。而作者使用STM32开发的原因很简单,ESP8266虽然计算能力等方面优于STM32F1xx,但是弊端也很明显。其所具备的引脚和外设太少,扩展性一般(ESP32算是二者优点兼备)。加之网上ESP8266的太空人WiFi天气时钟已经开源的很完善了,所以尝试用STM32实现一下,也方便后续利用STM32拓展开发。(文末有代码开源!)
实验硬件:STM32F103ZET6;7针1.3寸TFT-LCD(240×240);ESP8266
硬件实物图:
效果图:
引脚连接:
LCD显示引脚:
VCC --> 3.3V
GND --> GND
CLK --> PA5
DIN --> PA7
RES --> PB0
DC --> PB1
CS --> PA4
ESP8266模块引脚:
VCC --> 3.3V
GND --> GND
RX--> PB10
TX --> PB11
RST --> PB9
EN --> PB7
一、ESP8266简介与使用
1.1 ESP8266简介
ESP8266是一款超低功耗的UART-WiFi透传模块,拥有业内极富竞争力的封装尺寸和超低能耗技术,专为移动设备和物联网应用设计,可将用户的物理设备连接到Wi-Fi无线网络上,进行互联网或局域网通信,实现联网功能。
ESP8266是上海乐鑫信息科技(国产)设计的低功耗WiFi芯片,集成完整的TCP/IP协议栈和MCU(网上ESP8266型号很多,基本都具备联网功能,部分型号可以直接作为MCU使用)。而ESP8266模块是深圳安信可公司基于ESP8266芯片研发(增加必要外围电路、串口flash、板载天线等)的串口WiFi模块,成本低、使用简便、功能强大。
一般是模块固件损坏或者买回来里面可能被别人刷过固件需要擦除或者增加固件才用,作者的ESP8266是因为烧写了Arduino IDE的例程进去,不能识别AT指令,后来用不到了才想到刷回AT固件。刷固件有风险!!!(如果大家买的是ESP8266 nodeMCU可能就需要刷AT固件)
1.2 硬件与网络的桥梁——ESP8266
ESP8266模块和串口蓝牙JDY-31模块一样,串口WiFi模块也是扩展单片机功能的又一神器。小巧的 ESP8266 WiFi模块通过串口AT指令与单片机通讯,实现串口透传,非常好上手(部分型号ESP8266可以直接当MCU,无需再通过串口与其他MCU通讯)。
透传,又称透明传输,具体来说就是“输入即输出(如从WiFi模块串口输入的字符会透传到服务器端)”,数据不改变,不同协议之间的转换(如串口到WiFi、蓝牙等)由模块完成。使用者无需关心内部具体实现,因此模块对于使用者是“透明的”、似乎不存在的(因为可无视中间的实现原理)。一个高度封装的模块,应该隐藏内部实现细节,仅对外提供使用接口。
把硬件联网之后,就再也不是“玩单机”了。配合服务器端的Socket网络编程,可以玩许多东西。所以我觉得WiFi模块是连接软件(网络编程)与硬件(单片机)的桥梁,把所学的单片机(MCU)和Web知识联系起来了。
如今大火的物联网等概念都属于“智能硬件",ESP8266等模块的出现大大减少了网络开发的难度系数,也进一步促进了技术下放。而且,通过学习ESP8266/ESP32等模块,可以熟悉大量TCP/IP等网络协议,对后续Linux系统板网络开发也是极具意义的。
1.3 ESP8266使用——AT指令
AT指令最早在蓝牙模块上接触过,所谓AT指令实质上就是一些起控制作用的特殊字符串。模块可以通过AT指令控制搭配使用源代码API函数开发,总体开发速度快,难度较低。
说明:下面仅列举一些最常用的AT指令及用法,指令的详细参数及使用说明请参考官方文档:ESP8266 AT指令集。
基础AT指令
指令 | 描述 |
---|---|
AT | 测试AT启动 |
AT+RST | 重启模块 |
AT+GMR | 查看版本信息 |
AT 是最常用的指令,用于测试模块能否正常接受指令。在sscom中向串口发送指令 AT ,若收到模块返回的 OK 则说明模块的AT指令可正常工作。发送 AT+GMR 可查看AT指令及SDK的版本号,一般最新版指令会增加一些新功能,可随时关注官方的更新。
WiFi功能AT指令
WiFi是让硬件联网的基础,和其他功能一样,这里仅列举所需的常用指令,更详细指令说明还得查阅文档。
指令 | 描述 |
---|---|
AT+CWMODE | 设置WiFi模式(sta/AP/sta+AP) |
AT+CWLAP | 扫描附近的AP信息 |
AT+CWJAP | 连接AP |
AT+CWQAP | 与AP断开连接 |
AT+CWSAP | 设置ESP8266 softAP配置 |
AT+CWLIF | 获取连接到 ESP8266 softAP 的 station 的信息 |
关于WiFi模式这里要说明一下,sta模式下模块相当于客户端,像我们手机平板一样是要去连接路由器的,而AP模式下模块相当于路由器,是发射WiFi被别人连的。ESP8266支持两种模式并存(模块出厂默认的是AP模式) 。另外,扫描WiFi指令 AT+CWLAP 只能在sta模式下使用,否则会报ERRO错误, AT+CWJAP 和 AT+CWQAP 指令也同理。
sta模式连接WiFi演示
-
发送
AT+CWMODE=1
指令配置模块为sta模式(参数1,2,3分别对应模式sta,AP和sta/AP)。 -
发送
AT+CWLAP
指令扫描当前附近WiFi,模块会返回可用AP列表。 -
使用
AT+CWJAP="WiFi名称","WiFi密码"
连接到指定的路由器,比如我在图书馆的WiFi是 “Wang”,密码是“123456”,实际连接WiFi发送的指令就是AT+CWJAP="Wang","123456"
。 -
返回的“WIFI CONNECTED”说明连接成功,“WIFI GOT IP”代表模块分配到了IP。
-
最后可使用
AT+CWQAP
断开当前连接的WiFi。
TCP/IP相关AT指令
传输控制协议(英语:Transmission Control Protocol,缩写为 TCP)是一种面向连接的、可靠的、基于字节流的传输层通信协议,由IETF的RFC 793定义。在简化的计算机网络OSI模型中,它完成第四层传输层所指定的功能,用户数据报协议(UDP)是同一层内另一个重要的传输协议。在因特网协议族(Internet protocol suite)中,TCP层是位于IP层之上,应用层之下的中间层。不同主机的应用层之间经常需要可靠的、像管道一样的连接,但是IP层不提供这样的流机制,而是提供不可靠的包交换。
我们常说互联网互联网,那两个连接到互联网的设备该如何相互“交流”呢?TCP连接就是其中一种最常用的方式。TCP是面向连接的传输层协议,通信双方都要实现TCP协议,其中一方只需目标ip地址和端口号就能发起连接,连接一旦建立,就像在双方之间拉了一条管子,管子两端可进行全双工(双向同时收发)通信。
TCP是传输层协议,是在网络层IP协议的基础上封装而来。而这些封装的实现细节也是与我们无关,我们只需使用系统所提供的相关接口“拿来即用”,比如网络编程中的Socket。ESP8266模块中也实现了TCP/IP协议栈,模块作为客户端可轻松使用AT指令向服务端发起TCP连接。连接TCP服务器并开启透传模式后,模块串口收到的数据就会通过TCP连接透传到服务端,这样就完成了数据从硬件串口通过网络到程序进程的传输,实现软硬结合。
指令 | 描述 |
---|---|
AT+CIPSTATUS | 查询网络连接信息 |
AT+CIPMUX | 设置多连接模式 |
AT+CIPSTART | 建立TCP连接UDP传输或者SSL连接 |
AT+CIPCLOSE | 关闭TCP/UDP/SSL传输 |
AT+CIPMODE | 设置透传模式 |
AT+CIPSEND | 发送数据 |
把WiFi模块和电脑连接,在sscom确定AT指令能正常使用后,就可以开始配置TCP连接了,具体步骤如下:
-
根据上面“sta模式连接WiFi演示”一节把模块连上WiFi
-
输入指令
AT+CIPMUX=0
设置单连接 -
从“网络调试助手”得知本机IP和端口,输入指令
AT+CIPSTART="TCP","192.168.43.140",1234
(指令参数分别为连接类型、目标IP地址和端口号)向服务器发起TCP连接请求,握手成功并建立连接后,服务器端的“网络调试助手”就会显示客户端IP和端口信息,此时双方已做好收发数据的准备(根据实际需要连接的IP地址来) -
输入指令
AT+CIPMODE=1
开启透传模式 -
输入命令
AT+CIPSEND
进入透传模式,此时模块会把所有串口收到的数据都从TCP端口发送至服务器,同样的,从服务器收到的数据也会从模块串口发送出去打印到sscom上。这样WiFi模块就真正成为了连接硬件与网络的桥梁,实现了串口到TCP的协议转换
以上其实就是大概本次项目需要使用到的指令,ESP8266配置代码如下:
void esp8266_config(void)
char str[200];
sprintf(str, "AT+CWJAP=\\"%s\\",\\"%s\\"\\r\\n", WIFI_NAME, WIFI_PSW);
// SendATCmd("+++", 500); // 退出透传模式
SendATCmd("AT\\r\\n", 2000); // 测试ESP01模块是否存在
// SendATCmd("AT+GMR\\r\\n",3000); // 查看模块版本信息
SendATCmd("AT+CWMODE=1\\r\\n", 2000); // 开启STA+AP模式 ==================
SendATCmd("AT+RST\\r\\n", 3000);
SendATCmd(str, 10000); // 连接无线路由器或者手机热点,等待10秒 ============
SendATCmd("AT+CIPMUX=0\\r\\n", 2000); // 关闭多连接
SendATCmd("AT+CIPSTART=\\"TCP\\",\\"api.seniverse.com\\",80\\r\\n", 2000); // 连接心知 天气TCP服务器
SendATCmd("AT+CIPMODE=1\\r\\n", 500); // 开启透传模式
SendATCmd("AT+CIPSEND\\r\\n", 500); // 开始透传
二、知心天气API使用
本项目为WiFi天气时钟,自然离不开需要从网页上读取天气信息。这里我们使用业内比较著名的知心天气。
2.1 登陆心知天气官网,注册
没有账号的朋友可以自己去注册一下,流程很简单。不商用的话,知心天气是免费的,还是比较良心的(网站响应率也很高)。
点击“立即免费试用”
点击免费版的“免费申请”
申请后可查看到自己的私钥(自行保存后面需要用到)
2.1 API函数的使用
目前,大部分网络数据调用都是习惯性的调用数据提供商的API接口函数。
重新点击“产品”—>“天气数据”,点击“查看API文档”
点击"天气实况",打开对应的API接口文档
查看天气实况的接口地址,以及返回的数据结果示例(自行保存后面需要用到)
(1)上述知心天气API接口函数的寻找和使用通用性很高,大部分网络数据读取的流程与之类似。
(2)嵌入式开发大部分情况下一般都是C语言进行开发的,由于C语言的局限性,没有直接的字典类型处理(python),所以,对于服务器返回给ESP8266的JSON数据一般是无法直接解码读取的。目前有2种方法处理:①、移植CJSON去解码;②取巧去比对字符串(本次使用的方法);
项目使用过程中直接使用知心天气自带的API函数,项目大致流程:开启STA模式后,成功连上WiFi后,通过TCP协议去访问执行天气网站的服务器,在发送特定的API接口函数,服务器响应后返回需要的结果信息。
三、UART串口通讯
STM32作为MCU与ESP8266直接的通讯就是简单的UART(串口)通信,这一点依旧与蓝牙模块很类似。使用方法:通过串口UARTx_TX连接ESP8266的UART_RX,然后单片机通过串口发送AT指令集。ESP8266后续从服务器接受的数据信息也从ESP8266的UART_TX传输给单片机UARTx_RX。后续只需要使用自己的方法去解析串口接收到的数据,即可得到自己想要的数据信息。
可以初步使用电脑串口去读取MCU接收到ESP8266返回的信息:
四、CubeMX配置
1、RCC配置外部高速晶振(精度更高)——HSE;
2、SYS配置:Debug设置成Serial Wire(否则可能导致芯片自锁);
3、GPIO配置:此处模拟使用SPI通信,并且设置ESP8266的EN和RST;
4、RTC配置:年月日,时分秒;
5、UART1和UART3配置:MCU分别与电脑和ESP8266通讯(记得开启串口通信中断);
6、时钟树配置
7、工程配置
五、代码与解析
5.1 TFT-LCD显示代码
LCD显示部分其实都是非常基础的操作,不熟悉的可以去看看笔者另一篇文章了解一下。作者这里主要把工程中不一样的地方指出来一下。【强烈推荐】基于STM32的TFT-LCD各种显示实现(内容详尽含代码)_混分巨兽龙某某的博客-CSDN博客_lcd显示屏显示代码
5.1.1 UI设计
WiFi天气时钟中最要的点——UI设计,需要去设计很多界面图标,作者这里耗费了超级多的时间,翻遍了GitHub和视觉中国。最后找到了差不多符合作者要求的UI库(有需要的可以评论区留下邮箱),如下:
5.1.2 GIF动图实现
目前,由于STM32自身内存的缘故,其实STM32是不太适合实现GIF动图的。所以,网上这方面的资料和代码都很少。目前,较为主流的方法:(1)enWin或者Lvgl库实现GIF动图;(2)从SD卡读取数据去显示。
作者这里用了一直笨方法去实现了GIF显示,就是去循环遍历GIF动图的每一帧。
使用GIF分离器去分离GIF动图的每一帧;
再利用Image2Lcd 2.9(破解版)去提前图模;
将取模代码变为2维数组,第一维度为帧数,第二维度为每帧图片的取模。
之后循环显示该GIF数组的每一帧,即可实现GIF动图显示。
代码:
void showimage4(const unsigned char *p)
int i;
unsigned char picH,picL;
Address_set(180,146,228,195);
for(i=0;i<49*50;i++)
picL=*(p+i*2);
picH=*(p+i*2+1);
LCD_WR_DATA(picH<<8|picL);
for(int a=0;a<11;a++)
showimage4(gImage_1[a]);
5.2 ESP8266代码
EPS8266部分代码主要是配置后负责和目标服务器去实现通讯,当然还有需要解码服务器返回信息。
5.2.1 ESP8266配置代码(含UART处理)
UART回调处理函数:
/* USER CODE BEGIN 4 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
/* Prevent unused argument(s) compilation warning */
UNUSED(huart);
/* NOTE: This function Should not be modified, when the callback is needed,
the HAL_UART_TxCpltCallback could be implemented in the user file
*/
if(huart == &huart1)
g_uart1_rx.buf[g_uart1_rx.size++] = aRxBuffer_rx1;
if((g_uart1_rx.buf[g_uart1_rx.size-1] == 0x0A)&&(g_uart1_rx.buf[g_uart1_rx.size-2] == 0x0D))
HAL_UART_Transmit(&huart1, (uint8_t *)&g_uart1_rx.buf, g_uart1_rx.size,0xFFFF);
while(HAL_UART_GetState(&huart1) == HAL_UART_STATE_BUSY_TX);
g_uart1_rx.size = 0;
memset(g_uart1_rx.buf,0x00,sizeof(g_uart1_rx.buf));
HAL_UART_Receive_IT(&huart1, (uint8_t *)&aRxBuffer_rx1, 1);
if(huart == &huart3)
g_uart3_rx.buf[g_uart3_rx.size++] = aRxBuffer_rx3;
if((g_uart3_rx.buf[g_uart3_rx.size-1] == 'K')&&(g_uart3_rx.buf[g_uart3_rx.size-2] == 'O'))
HAL_UART_Transmit(&huart1, (uint8_t *)&g_uart3_rx.buf, g_uart3_rx.size,0xFFFF);
while(HAL_UART_GetState(&huart1) == HAL_UART_STATE_BUSY_TX);
g_uart3_rx.size = 0;
memset(g_uart3_rx.buf,0x00,sizeof(g_uart3_rx.buf));
else if((g_uart3_rx.buf[g_uart3_rx.size-2] == ']')&&(g_uart3_rx.buf[g_uart3_rx.size-1] == '')
&&(g_uart3_rx.buf[g_uart3_rx.size-3] == ''))
HAL_UART_Transmit(&huart1, (uint8_t *)&g_uart3_rx.buf, g_uart3_rx.size,0xFFFF);
while(HAL_UART_GetState(&huart1) == HAL_UART_STATE_BUSY_TX); //
strcpy(Data_buff,(char *)g_uart3_rx.buf);
temp = 1;
g_uart3_rx.size = 0;
memset(g_uart3_rx.buf,0x00,sizeof(g_uart3_rx.buf));
HAL_UART_Receive_IT(&huart3, (uint8_t *)&aRxBuffer_rx3, 1);
/* USER CODE END 4 */
ESP8266.h(AT控制):
#ifndef __ESP8266_H
#define __ESP8266_H
//#include "stdint.h"
//uint8_t aRxBuffer_rx1; //接收中断缓冲
//uint8_t aRxBuffer_rx3; //接收中断缓冲
//typedef struct
// uint16_t size;
// uint8_t buf[1022]; // 接收缓冲数组
// UART_RXDATA;
//UART_RXDATA g_uart1_rx;
//UART_RXDATA g_uart3_rx;
//char Data_buff[1022];
//char weather[10]; //存储天气
//uint8_t temperature[2]=0,0; //储存最高气温和最低气温
//uint8_t temp = 0;
//需要连接的wifi账号和密码,需要修改,且WiFi频段不支持5GHz
#define WIFI_NAME "Wang"
#define WIFI_PSW "123456"
心知天气api,注意key=后面需要替换成自己账号的密钥
//char *get="GET https://api.seniverse.com/v3/weather/daily.json?key=SkV9zIBpwJAOixrJZ&location=chongqing&language=en&unit=c\\r\\n";
//void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);
void SendATCmd(char *cmd, int waitms);
void esp8266_config(void);
#endif
ESP8266.c:
#include "esp8266.h"
#include "usart.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "lcd.h"
void SendATCmd(char *cmd, int waitms)
// 发送AT指令给串口3
if (NULL != cmd)
HAL_UART_Transmit(&huart3, (uint8_t *)cmd, strlen(cmd), 0xFFFF);
if (waitms > 0)
HAL_Delay(waitms); // 延时等待ESP01模块应答时间
void esp8266_config(void)
char str[200];
sprintf(str, "AT+CWJAP=\\"%s\\",\\"%s\\"\\r\\n", WIFI_NAME, WIFI_PSW);
// SendATCmd("+++", 500); // 退出透传模式
SendATCmd("AT\\r\\n", 2000); // 测试ESP01模块是否存在
// SendATCmd("AT+GMR\\r\\n",3000); // 查看模块版本信息
SendATCmd("AT+CWMODE=1\\r\\n", 2000); // 开启STA+AP模式 ==================
SendATCmd("AT+RST\\r\\n", 3000);
SendATCmd(str, 10000); // 连接无线路由器或者手机热点,等待10秒 ============
SendATCmd("AT+CIPMUX=0\\r\\n", 2000); // 关闭多连接
SendATCmd("AT+CIPSTART=\\"TCP\\",\\"api.seniverse.com\\",80\\r\\n", 2000); // 连接心知天气TCP服务器
SendATCmd("AT+CIPMODE=1\\r\\n", 500); // 开启透传模式
SendATCmd("AT+CIPSEND\\r\\n", 500); // 开始透传
SendATCmd("GET https://api.seniverse.com/v3/weather/daily.json?key=SkV9zIBpwJAOixrJZ&location=zhenjiang&language=en&unit=c\\r\\n", 2000);
注意,key=后面尽量换成自己的密钥,location=后面也可以换成自己所在城市的字母。
5.2.2 ESP8266信息解码
这部分作者取巧,使用了字符串对比和指针取值的操作。
strstr()函数:
atoi()函数:
代码:
char *p;
p = strstr(Data_buff,"text_day"); //查找天气
sscanf(p+11,"%[^\\"]",weather);
// LCD_ShowString(40,80,(uint8_t*)weather);
p = strstr(Data_buff,"high"); //查找气温
temperature[0]=atoi(p+7);
p = strstr(Data_buff,"low");
temperature[1]=atoi(p+6);
// LCD_ShowxNum2(45,40,temperature[1],2,24,0);
LCD_ShowxNum2(160,207,temperature[0],2,24,0);
//温度
value = (temperature[1]+temperature[0])/2;
LCD_ShowxNum2(52,160,value,2,24,0);
//湿度
p = strstr(Data_buff,"humidity");
humidity=atoi(p+11);
LCD_ShowxNum2(132,160,humidity,2,24,0);
LCD_ShowNew(161,160,'%',24,0);
if((strstr(weather,"Overcast")) || (strstr(weather,"Mostly Cloudy")) || (strstr(weather,"Partly Cloudy")) || strstr(weather,"Cloudy"))
Overcast();
if((strstr(weather,"Sunny")) || (strstr(weather,"Clear")) || (strstr(weather,"Fair"))) //ÇçÌì
Sunny();
if((strstr(weather,"Shower")))
Shower();
if((strstr(weather,"Thundershower")) || (strstr(weather,"Thundershower with Hail")))
Thundershower();
if((strstr(weather,"Light rain")) || (strstr(weather,"Moderate Rain")))
smallrain();
if((strstr(weather,"Heavy Rain")) || (strstr(weather,"Storm")) || (strstr(weather,"Heavy Storm")) || (strstr(weather,"Severe Storm")))
Bigrain();
if((strstr(weather,"Ice Rain")) || (strstr(weather,"Sleet")) || (strstr(weather,"Snow Flurry")) || (strstr(weather,"Light Snow")) || (strstr(weather,"Moderate Snow")) || (strstr(weather,"Heavy Snow")) || (strstr(weather,"Snowstorm")))
snow();
5.3 RTC代码
rtcdisplay.h:
#ifndef __RTCDISPLAY_H
#define __RTCDISPLAY_H
void RTC_display();
#endif
rtcdisplay.c:
#include "rtcdisplay.h"
#include "rtc.h"
#include "lcd.h"
RTC_DateTypeDef GetData; //获取日期结构体
RTC_TimeTypeDef GetTime; //获取时间结构体
void RTC_display() //RTC DISPLAY
/* Get the RTC current Time */
HAL_RTC_GetTime(&hrtc, &GetTime, RTC_FORMAT_BIN);
/* Get the RTC current Date */
HAL_RTC_GetDate(&hrtc, &GetData, RTC_FORMAT_BIN);
/* Display date Format : yy/mm/dd */
// OLED_ShowNum(0,0,2000+GetData.Year,4,16); //year
// OLED_ShowStr(35,30,".",2);
// OLED_ShowNum(45,0,GetData.Month,2,16); //month
// OLED_ShowStr(60,30,".",2);
// OLED_ShowNum(70,0,GetData.Date,2,16); //date
/* Display time Format : hh:mm:ss */
LCD_ShowxNum2(15,75,GetTime.Hours,2,60,0); //hour
// LCD_ShowNew(75,65,':',60,0);
LCD_ShowxNum2(105,75,GetTime.Minutes,2,60,0); //min
LCD_ShowxNum2(180,105,GetTime.Seconds,2,32,0); //seconds
这里RTC的时钟显示,作者也去网上找了专门的LED数字字体,如果需要LED数字字体库的也可以评论留言,作者把安装脚本发你。
六、项目效果
太空人WIFI天气时钟
七、项目代码
代码地址: 基于STM32与ESP8266的太空人WiFi天气时钟(TFT-LCD)-嵌入式文档类资源-CSDN文库
如果积分不够的朋友,点波关注,评论区留下邮箱,作者无偿提供源码和后续问题解答。求求啦关注一波吧 !!!
以上是关于esp8266制作太空人天气时钟的主要内容,如果未能解决你的问题,请参考以下文章
利用ESP8266+OLED(I2C)打造智能时钟(网络校时+实时天气+天气预报)
基于STM32的ESP8266天气时钟--------MCU获取天气数据