STM32-心知天气项目
一、项目需求
二、项目框图

三、cjson作用
https://github.com/DaveGamble/cJSON/releases/tag/v1.7.18
cjson可以把json代码来回解析和打包
cjson的移植
1、把cjson拷贝到项目文件中
2、#include添加cjson头文件
3、根据自己的需求修改堆栈
四、项目实现
4.1 项目前期准备

加载文件
在主函数中写入头文件和初始化函数

4.2 修改oled文件
先从oled开始修改

取字模



在心知天气平台中可以看到有39种天气

这里只取晴、多云、阴、雨,雪五种天气,也可以按需求自己取天气
生成字模,放到font.h文件中

修改oled中显示汉字的代码

别忘了修改.h文件

编译之后--无错误

接下来将oled的排版排一下
重新定义一个函数

别忘了在oled.h文件中加入函数
主函数中调用一下函数名,就可以显示(可以先把esp8266的初始化函数先注释掉,太浪费时间)
显示结果如下:

4.3 修改esp8266文件
剩下的信息就要从json包中获取了
日期、天气状态、温度
需要修改esp8266代码,通过http协议访问心知天气平台,利用cjosn包解析想要的信息
esp8266是通过串口2来传递信息的,所以在uart1.c文件中需要加入串口2的应用
打开项目文件36-编程实现ESP8266连接TCP服务器
复制这段代码到本项目中的uart1.c

如何获取心知天气的天气呢?
在心知天气中,可以获取一个关于天气的api
将这个api丢到浏览器上,就可以看到关于天气的json包
这个过程就是http请求。
那么esp8266如何发起一个http的请求呢?
直接通过esp8266把api给发送(send)出去
代码如下:
//获取天气的信息,从天这个单位来获取,某一天day
uint8_t esp8266_get_weather(uint8_t day)
{//4、定义一个变量判断返回值是否是正确的uint8_t ret = ESP8266_ERROR;//默认返回值为error//1、构建HTTP请求的数据包,存放api的char http_request[200] = {0};//2、使用sprintf将api丢到数据包数组中,前面加一个GET,获取这个API包sprintf(http_request,"GET https://api.seniverse.com/v3/weather/daily.json?key=S35Rrryu2DExg-Hku&location=beijing&language=zh-Hans&unit=c&start=%d&days=3\r\n",day);//3、如何判断发给服务器的数据发送成功?//进入到获取数据这部分了,通过串口将数据发送到服务器上,ret = esp8266_send_command(http_request,"results");//同时期待返回值results//打印出来结果printf("%s\r\n",esp8266_rx_buf);if(ret == ESP8266_EOK)//判断返回值是否是okreturn ESP8266_EOK;elsereturn ESP8266_ERROR;}//复制RX引脚接收到的信息--目的是避免使用了extern
uint16_t esp8266_copy_rxdata(char *data)
{//将数据复制到data中memcpy(data, esp8266_rx_buf, esp8266_cntPre);return esp8266_cntPre;
}
要修改心知天气的地址和端口号

主函数

扩大长度

结果如下所示:

4.4 解析提取JSON数据包中需要的信息
根据自己的需求修改堆栈

新建文件weather

加载项目文件
头文件
新建的weather是用来书写天气的信息的


代码如下:
void get_3days_weather(void)
{uint8_t i = 0;for(i = 0; i < 3; i++){memset(weather_data, 0, sizeof(weather_data));esp8266_get_weather(i);esp8266_copy_rxdata(weather_data);//1. 将JSON字符串转换成JSON结构体cJSON *cjson = cJSON_Parse((const char *)weather_data);//2. 解析JSON各个字段//2.1 获取根对象里的results字段的值(数组1)cJSON *results = cJSON_GetObjectItem(cjson, "results");//2.2 获取数组1的第一个元素(对象1)cJSON *first_result = cJSON_GetArrayItem(results, 0);//2.3 获取对象1中的daily字段的值(数组2)cJSON *daily = cJSON_GetObjectItem(first_result, "daily");//2.4 获取数组2中的第一个元素(对象2)cJSON *first_daily = cJSON_GetArrayItem(daily, 0);//2.5 获取对象2中的data字段的值cJSON *date = cJSON_GetObjectItem(first_daily, "date");const char *date_str = date->valuestring;printf("date: %s\r\n", date_str);strcpy(three_day_weather[i].date, date_str);//2.6 获取对象2中的code_day字段的值cJSON *code_day = cJSON_GetObjectItem(first_daily, "code_day");const char *code_day_str = code_day->valuestring;printf("code_day: %s\r\n", code_day_str);strcpy(three_day_weather[i].code_day, code_day_str);//2.7 获取对象2中的high字段的值cJSON *high = cJSON_GetObjectItem(first_daily, "high");const char *high_str = high->valuestring;printf("high: %s\r\n", high_str);strcpy(three_day_weather[i].high, high_str);//2.8 获取对象2中的low字段的值cJSON *low = cJSON_GetObjectItem(first_daily, "low");const char *low_str = low->valuestring;printf("low: %s\r\n\r\n", low_str);strcpy(three_day_weather[i].low, low_str);//3. 清除JSON结构体cJSON_Delete(cjson);delay_ms(1000);}
}
在主函数中和.h文件中调用一下,应该会产生的结果是:

这里注意,如果产生的结果全部是乱码,或者部分信息是乱码,如下图所示:

这就有可能是你的堆栈没有设置足够
详情见下面链接
CSDN
扩大堆的空间只后,即可正确显示数据
最后我这里堆增加到了0x00001C00
4.5 显示天气
接下来就是显示天气,在主函数的while循环中判断按下的key键
代码如下:
void show_weather(uint8_t day)
{oled_show_init();oled_show_string(10,0,three_day_weather[day].date,16);//将字符串的”11“转变成数字的”11 “uint8_t code_day = atoi(three_day_weather[day].code_day);switch(code_day){case 0:case 1:case 2:case 3:oled_show_chinese(77, 2, 8); //晴break;case 4:case 5:case 6:case 7:case 8:oled_show_chinese(77, 2, 9); //多oled_show_chinese(90, 2, 10); //云break;case 9:oled_show_chinese(77, 2, 11); //阴break;case 10:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 20:oled_show_chinese(77, 2, 12); //雨break;case 21:case 22:case 23:case 24:case 25:oled_show_chinese(77, 2, 13); //雪break;default:break; }oled_show_string(77,4,three_day_weather[day].high,16);oled_show_string(77,6,three_day_weather[day].low,16);
}
主函数代码如下:
uint8_t key_num = 0;uint8_t day = 0;while(1){ key_num = key_scan();if(key_num == 1)//切换天气{day++;day %= 3;show_weather(day);}else if(key_num == 2)//更新天气{printf("更新天气\r\n");get_3days_weather();show_weather(0);day = 0;}}
相关文章:
STM32-心知天气项目
一、项目需求 使用 ESP8266 通过 HTTP 获取天气数据(心知天气),并显示在 OLED 屏幕上。 按键 1 :循环切换今天 / 明天 / 后天天气数据; 按键 2 :更新天气。 二、项目框图 三、cjson作用 https://gi…...
cs106x-lecture14(Autumn 2017)-SPL实现
打卡cs106x(Autumn 2017)-lecture14 (以下皆使用SPL实现,非STL库,后续课程结束会使用STL实现) 1、min Write a function named min that accepts a pointer to a ListNode representing the front of a linked list. Your function should return the …...
基于STM32的智能家居语音系统(单片机毕设)
前言 源代码下载链接: https://download.csdn.net/download/m0_74712453/90071680 需要实物的可以私信博主或者在文章最下方添加好友。 目录 一、项目介绍和演示视频 二、硬件实现 1. 材料材料 2. 原理图和PCB 三、软件实现 1. 代码解析 1.1 main函数 1.2…...
ASP.NET Core 简单文件上传
使用异步 JavaScript 和 XML(AJAX)进行简单的文件上传;用 C# 编写的服务器端代码。 使用AJAX和ASP.NET Core MVC上传文件再简单不过了。这不依赖于jQuery。此代码允许上传多个文件,并与 .NET Core 3.1、.NET 6和.NET 8兼容。 如果…...
2502C++,C++继承的多态性
构 A{单 向量<串>记;元<类 T>静 空 ff(串&a){清理(记);名向量(a,记);串 b{"---ff---"};打印(b);T::g();} };构 B:公 A{元<类 T>静 空 f(){串 a{"错误.txt"};ff<T>(a);} };构 C:公 A{元<类 T>静 空 f(){串 a{"a12.c…...
【机器学习】13.十大算法之一K均值算法(K-means)聚类详细讲解
【机器学习】13.十大算法之一K均值算法(K-means)聚类详细讲解 一摘要二个人简介三K-均值聚类(K-means)3.1-K均值算法的基本原理3.1.1- 聚类分析的目标3.1.2- K - means算法算法原理 四K-means聚类算法的收敛性五证明K均值算法的收…...
Spring扩展点之Mybatis整合模拟
Spring扩展点之Mybatis整合 单独使用MyBaitis模拟整合MyBatis到Spring 单独使用MyBaitis 通过配置文件生成sqlSessionFactory,用sqlSessionFactory开启session。通过session获取到mapper执行对应的sql。 InputStream inputStream Resources.getResourceAsStream(…...
.NET MVC实现电影票管理
.NET MVC(Model-View-Controller)是微软推出的基于 Model-View-Controller 设计模式的 Web 应用框架,属于 ASP.NET Core 的重要组成部分。其核心目标是通过清晰的分层架构实现 高内聚、低耦合 的开发模式,适用于构建可扩展的企业级…...
自媒体账号管理工具:创作罐头使用指南
创作罐头使用指南 1. 关于创作罐头 创作罐头是免费的一站式自媒体运营工具,支持各大自媒体平台多账号管理、全网爆文库、原创检测、视频一键分发、团队管理、各平台数据分析等功能。 2. 安装与注册 2.1. 如何安装创作罐头 从我们的官网下载并安装软件 www.czgts.…...
基于数据可视化+SpringBoot+安卓端的数字化OA公司管理平台设计和实现
博主介绍:硕士研究生,专注于信息化技术领域开发与管理,会使用java、标准c/c等开发语言,以及毕业项目实战✌ 从事基于java BS架构、CS架构、c/c 编程工作近16年,拥有近12年的管理工作经验,拥有较丰富的技术架…...
VSCode离线安装插件
最近在其他电脑设备上部署vscode环境出现问题,在vscode里直接安装插件失败,软件提示如下:(此前已经用此方法安装过中文插件) 这里我们选择手动下载,会自动在浏览器中跳转到该插件的下载链接并自动下载插件&…...
基于Hadoop的汽车大数据分析系统设计与实现【爬虫、数据预处理、MapReduce、echarts、Flask】
文章目录 有需要本项目的代码或文档以及全部资源,或者部署调试可以私信博主 项目介绍爬虫数据概览HIve表设计Cars Database Tables 1. cars_data2. annual_sales_volume3. brand_sales_volume4. city_sales_volume5. sales_volume_by_year_and_brand6. sales_distri…...
SHELL32!Shell_MergeMenus函数分析
SHELL32!Shell_MergeMenus函数分析 UINT Shell_MergeMenus( [in] HMENU hmDst, [in] HMENU hmSrc, UINT uInsert, UINT uIDAdjust, UINT uIDAdjustMax, ULONG uFlags ); 参数 [in] hmDst 类型: HMENU 要向其添加 hmSrc…...
华为云deepseek大模型平台:deepseek满血版
华为云硅基流动使用Chatbox接入DeepSeek-R1满血版671B 1、注册: 华为云deepseek大模型平台注册:https://cloud.siliconflow.cn/i/aDmz6aVN 说明:填写邀请码的话邀请和被邀请的账号都会获得2000 万 Tokens;2个帐号间不会与其他关联…...
AutoGen 技术博客系列 八:深入剖析 Swarm—— 智能体协作的新范式
本系列博文在掘金同步发布, 更多优质文章,请关注本人掘金账号: 人肉推土机的掘金账号 AutoGen系列一:基础介绍与入门教程 AutoGen系列二:深入自定义智能体 AutoGen系列三:内置智能体的应用与实战 AutoGen系列四&am…...
从零开始开发纯血鸿蒙应用之网页浏览
从零开始开发纯血鸿蒙应用 〇、前言一、优化菜单交互1、BuilderFunction.ets2、改造 PageTitleBar 二、网址打开1、方式选择1、使用浏览器打开2、内部打开2.1、声明权限2.2、封装 WebViewPage2.2.1、组件字段2.2.2、aboutToAppear2.2.3、onBackPress2.2.4、标题栏2.2.4、网页内…...
【大模型LLM】DeepSeek LLM Scaling Open-Source Language Models with Longtermism
深度探索LLM:以长期主义扩展开源语言模型 0.论文摘要 开源大语言模型(LLMs)的快速发展确实令人瞩目。然而,以往文献中描述的扩展规律得出了不同的结论,这为LLMs的扩展蒙上了一层阴影。我们深入研究了扩展规律&#…...
分布式事务-本地消息表学习与落地方案
本文参考: 数据库事务系列04-本地消息表实现分布式事务 基础概念 本地消息表实现分布式事务最终一致性的核心:是通过上游本地事务的原子性持久性,配合中间件的重试机制,从而实现调用下游的最终一致性。 这里有几个要点可以解析一…...
Debezium系列之:记录一次源头数据库刷数据,造成数据丢失的原因
Debezium系列之:记录一次源头数据库刷数据,造成数据丢失的原因 一、背景二、查看topic日志信息三、结论四、解决方法一、背景 源头数据库在很短的时间内刷了大量的数据,部分数据在hdfs丢失了 理论上debezium数据采集不会丢失,就需要排查数据链路某个节点是否有数据丢失。 …...
PHP约课健身管理系统小程序源码
🏋️♂️ 约课健身管理系统小程序:重塑健身预约体验,引领数字化健身新时代 一款基于ThinkPHPUniapp框架,由米扬精心雕琢的约课健身管理系统小程序,专为健身房、健身工作室、运动会所、运动场馆、瑜伽馆、拳馆等泛健…...
IDEA运行Tomcat出现乱码问题解决汇总
最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…...
在软件开发中正确使用MySQL日期时间类型的深度解析
在日常软件开发场景中,时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志,到供应链系统的物流节点时间戳,时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库,其日期时间类型的…...
Admin.Net中的消息通信SignalR解释
定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...
.Net框架,除了EF还有很多很多......
文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...
FFmpeg 低延迟同屏方案
引言 在实时互动需求激增的当下,无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作,还是游戏直播的画面实时传输,低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架,凭借其灵活的编解码、数据…...
Objective-C常用命名规范总结
【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名(Class Name)2.协议名(Protocol Name)3.方法名(Method Name)4.属性名(Property Name)5.局部变量/实例变量(Local / Instance Variables&…...
深入理解JavaScript设计模式之单例模式
目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式(Singleton Pattern&#…...
DBAPI如何优雅的获取单条数据
API如何优雅的获取单条数据 案例一 对于查询类API,查询的是单条数据,比如根据主键ID查询用户信息,sql如下: select id, name, age from user where id #{id}API默认返回的数据格式是多条的,如下: {&qu…...
06 Deep learning神经网络编程基础 激活函数 --吴恩达
深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...
什么是Ansible Jinja2
理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具,可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板,允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板,并通…...
