基于STM32和FreeRTOS的实时天气系统设计与实现
免费开源,本文项目源码可见文末
项目背景
随着物联网(IoT)技术的发展,实时数据监测系统逐渐成为日常生活和工业环境中不可或缺的组成部分。其中,气象监测系统不仅可以提供温度、湿度、天气状况等信息,还可以通过数据分析为农业、城市管理和个人生活提供智能化建议。
本项目以STM32F407为核心控制器,结合FreeRTOS实时操作系统和ESP8266 Wi-Fi模块,实现一套高可靠、实时更新的智能气象监测系统。同时,系统集成了计时功能,通过串口屏将实时数据可视化展示,为用户提供直观的操作体验。
硬件架构
本系统硬件结构简洁而实用,主要包括:
- STM32F407:主控制器,负责任务调度、数据处理和外设控制。
- ESP8266:Wi-Fi模块,用于联网获取天气数据。
- 淘晶驰串口屏:用于数据可视化展示。
串口连接方案:
- 串口1:调试与状态输出。
- 串口2:ESP8266数据通信。
- 串口3:串口屏显示控制。
硬件连接示意图如下:
STM32F407
│
├─串口1→串口打印(调试)
├─串口2→ESP8266(天气数据)
└─串口3→串口屏(数据展示)
软件架构与设计
1. FreeRTOS任务划分
本系统使用FreeRTOS进行任务调度,实现多任务并发处理。主要任务包括:
数据获取任务
- 功能:通过ESP8266发送AT指令,获取天气服务器的JSON数据。
- 优点:通过任务独立运行,保证网络请求不会阻塞其他操作。
数据解析任务
- 功能:使用cJSON库解析服务器返回的JSON数据,提取温度、天气状态等信息。
- 注意:FreeRTOS和cJSON默认内存管理可能冲突,需要替换cJSON的内存分配函数为
pvPortMalloc
,并且每次解析完成后必须释放内存,防止内存泄漏导致解码卡死。
显示刷新任务
- 功能:将解析后的数据通过串口屏进行显示,支持温度、天气状态以及计时信息。
- 优点:独立任务更新显示,保证界面刷新流畅,不受数据获取延迟影响。
计时任务
- 功能:提供系统运行时间或者定时提醒功能。
- 优点:利用FreeRTOS的延时与任务调度功能,实现精确计时。
2. ESP8266联网与AT指令控制
ESP8266通过串口与STM32通信,整个通信流程如下:
初始化AT指令
- 设置Wi-Fi模式:
AT+CWMODE=1
- 连接指定Wi-Fi:
AT+CWJAP="SSID","PASSWORD"
- 设置Wi-Fi模式:
发起HTTP请求
- 使用
AT+CIPSTART
建立TCP连接 发送HTTP GET请求获取天气数据,例如:
GET /weather?city=Shanghai HTTP/1.1 Host: api.weather.com
- 接收服务器返回的JSON数据
- 使用
数据传输与确认
- 使用
AT+CIPSEND
发送数据 - 读取返回状态,确保数据完整
- 使用
小技巧:在FreeRTOS任务中操作ESP8266时,需要考虑任务阻塞与超时,避免网络延迟影响其他任务。
3. cJSON解析与内存管理
cJSON是轻量级JSON解析库,但在FreeRTOS环境下,需要注意内存分配策略:
// 替换cJSON的内存管理函数
cJSON_Hooks hooks;
hooks.malloc_fn = pvPortMalloc;
hooks.free_fn = vPortFree;
cJSON_InitHooks(&hooks);
解析JSON示例:
char *jsonData = getWeatherJSON(); // 从ESP8266获取的JSON
cJSON *root = cJSON_Parse(jsonData);
if(root != NULL){
cJSON *temp = cJSON_GetObjectItem(root, "temperature");
cJSON *weather = cJSON_GetObjectItem(root, "description");
if(temp && weather){
printf("Temperature: %d°C\n", temp->valueint);
printf("Weather: %s\n", weather->valuestring);
}
cJSON_Delete(root); // 释放内存
}
注意事项:
- 每次解析完成必须调用
cJSON_Delete
释放内存 - FreeRTOS堆大小建议设置为至少 4096 字节
- 避免长字符串连续解析,可能导致任务阻塞
4. 串口屏显示逻辑
串口屏用于将获取的天气信息进行直观显示,显示内容包括:
- 当前温度(实时更新)
- 天气状况(晴/雨/阴等)
- 系统计时器(运行时间)
显示控制逻辑:
void DisplayWeather(int temp, const char* weather){
// 刷新温度
USART_SendString(UART3, "t0.txt=\"");
USART_SendInt(UART3, temp);
USART_SendString(UART3, "°C\"");
// 刷新天气状态
USART_SendString(UART3, "t1.txt=\"");
USART_SendString(UART3, weather);
USART_SendString(UART3, "\"");
}
通过任务周期性调用该函数,实现屏幕内容动态刷新。
系统实现效果
系统通过FreeRTOS实现任务并发,ESP8266实时获取天气信息,cJSON解析数据,串口屏显示结果如下:
用户可以实时查看当前温度和天气状况,同时计时器记录系统运行时间,整体操作直观、稳定。
系统优化建议
任务优先级优化
- 数据获取任务和解析任务设置中高优先级,保证数据实时性
- 显示任务和计时任务设置低优先级,保证界面刷新平滑
内存管理优化
- FreeRTOS堆大小建议设置为4096以上
- cJSON解析后必须释放内存,避免堆碎片导致系统卡死
网络稳定性
- ESP8266网络请求建议加入重试机制
- 超时设置合理,避免任务长时间阻塞
扩展功能
- 增加湿度、风速等气象数据
- 支持多城市切换
- 数据可上传云端,实现远程监控
总结
本项目通过STM32F407、FreeRTOS和ESP8266实现了一套实时天气监测系统,实现了:
- 多任务实时调度
- Wi-Fi联网获取天气信息
- JSON数据解析与显示
- 系统计时功能
整个系统架构清晰,操作稳定,并具备一定的扩展性和可维护性。通过对FreeRTOS任务管理和cJSON解析的优化,保证了系统在资源有限的单片机环境下仍能高效运行。
这套方案可以作为物联网环境下实时数据采集和显示系统的基础模板,为更多智能监测项目提供参考。
开源源码
https://blog.csdn.net/weixin_52908342/article/details/150592612