• 【毕业设计】基于STM32的天气预报盒子 - 嵌入式 单片机 物联网



    0 前言

    🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。

    为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天要分享的是

    🚩 基于STM32的天气预报盒子

    🥇学长这里给一个题目综合评分(每项满分5分)

    • 难度系数:3分
    • 工作量:4分
    • 创新点:4分

    🧿 选题指导, 项目分享:

    https://gitee.com/dancheng-senior/project-sharing-1/blob/master/%E6%AF%95%E8%AE%BE%E6%8C%87%E5%AF%BC/README.md


    1 简介

    一个获取天气状态的小盒子。

    2 主要器件

    • STM32F103RDT6
    • ESP8266模块
    • MICRO USB模块
    • 1.8寸彩屏模块

    3 实现效果

    在这里插入图片描述
    在这里插入图片描述
    功能介绍

    • 可以获取当前实时气温和3天内天气预报。板载气压传感器和温湿度传感器监测环境状态。
    • 使用了ESP8266模块,支持长按一键配网,使用安信可科技配网工具。
    • 监测电池电压,可以给电池充电。
    • MICRO USB引出可以给电池充电,支持STM32串口ISP下载与调试输出,串口芯片连接异常增加了电源输出滤波电容,PCB已更新。
    • 接插1.8寸彩屏模块(st7735驱动)。

    4 设计原理

    硬件原理图
    在这里插入图片描述
    STM32F103RDT6

    在这里插入图片描述

    主体代码

    在这里插入图片描述

    ESP8266模块
    ESP8266是一款适用于物联网和家庭自动化项目的 Wi-Fi 模块。

    ESP8266系列一般具有两种开发方式:AT指令开发和SDK开发。

    • AT指令:厂家出厂时预先在ESP8266芯片烧入好固件,封装好WiFi的协议栈,内部已经实现透传,而用户只需要使用一个USB转TTL的模块或者单片机的串口就能实现与WiFi模块的通信,发送AT指令来对WiFi模块进行控制。(和蓝牙透传模块类似)

    • SDK开发:由于ESP8266本身即是可编程的芯片,可以把它视为一个带有无线通信的单片机,而用户需要在专门的IDE中编写对应的程序,然后通过烧写固件的方式将程序写入到芯片中,因此,想要实现WiFi通信,需要自定义WiFi协议栈,对用户掌握的相关知识要求更高。

    部分代码

    /*-------------------------------------------------
    功能:ESP8266发送数据
    形参:id-连接序号(0-7),databuff-发送数据,data_len-数据长度
    返回值:0:无错误                                
            1:等待">"超时      
    				2:未连接
    				3:发送完成超时
    -------------------------------------------------*/
    u8 ESP8266_SendData(u8 id, char *databuff, u32 data_len)
    {
    	u32 i;
    	u8 timeout=50;
    	Clear_Buffer();
    	USART2_printf("AT+CIPSEND=%d,%d\r\n",id,data_len);		
    	while(timeout--)
    	{  
    		Delay_10ms();
    		if(strstr((const char*)USART2_ReceiveData,(const char*)">"))                   //如果接收到>表示成功
    			break;       						      //主动跳出while循环		
    	}
    	if(timeout==0)
    		return 1;
    	else
    	{
    		timeout=50;
    //		Clear_Buffer();                     	  
    			for(i=0;i<data_len;i++)
    				USART2_printf(databuff); //发送数据	
    			while(timeout--)
    			{  
    				Delay_10ms();
    				if(strstr((const char*)USART2_ReceiveData,(const char*)"SEND OK"))
    					return 0;		
    											
    				if(strstr((const char*)USART2_ReceiveData,(const char*)"link is not valid"))		
    					return 0;		
    						
    			}
    			return 3;
    	}
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    5 部分核心代码

    在这里插入图片描述

    void WIFI_Send_Cmd_And_Wait_OK(uint8_t *cmd){
    	Weather_Buffer_Clear();
    	UART_Send_Data(&huart3,cmd,strlen((char*)cmd));	
    	while(1){
    		if(UART3_REC_State == Uart_Status_Ready){
    			Weather_Data_Handler(Uart3_Rec_Buffer,UART3_Rec_Cnt);
    			if(strstr((char*)Uart3_Rec_Buffer,"OK") != NULL){
    				Weather_Buffer_Clear();
    				break;
    			}
    			Weather_Buffer_Clear();
    		}
    		osDelay(10);
    	}
    }
    
    void Check_Smart_Config(){
    	if(ESP_Smart_Config_Flag == 1){
    		printf("智能配网模式\r\n");
    		ESP_Smart_Config_Flag = 0;
    		osDelay(200*2);
    		WIFI_Send_Cmd_And_Wait_OK(Config_Cmd[0]);
    		WIFI_Send_Cmd_And_Wait_OK(Config_Cmd[1]);
    		ESP_Smart_Config_Dis = 1;
    	}
    }
    
    void WIFI_Mode_Init(){
    	LCD_Data.Connect = 0;
    	HAL_GPIO_WritePin(ESP_RST_GPIO_Port, ESP_RST_Pin, GPIO_PIN_SET);
    	while(1){
    		Check_Smart_Config();
    		if(UART3_REC_State == Uart_Status_Ready){
    			Weather_Data_Handler(Uart3_Rec_Buffer,UART3_Rec_Cnt);
    			if(strstr((char*)Uart3_Rec_Buffer,"WIFI GOT IP") != NULL){
    				LCD_Data.Connect = 1;
    				printf("WIFI已连接\r\n");
    				Weather_Buffer_Clear();
    				break;
    			}
    			else if(strstr((char*)Uart3_Rec_Buffer,"WIFI DISCONNECT") != NULL || strstr((char*)Uart3_Rec_Buffer,"FAIL") != NULL){
    				WIFI_Send_Cmd_And_Wait_OK(WEATHER_Cmd[1]);//重新配置模式
    			}
    			Weather_Buffer_Clear();
    		}
    		osDelay(10);
    	}
    }
    
    void Analysis_Current_Weather(uint8_t * data,uint32_t len){
    	
    	/*
    	{"results":[{"location":{"id":"WTSQQYHVQ973","name":"Nanjing","country":"CN","path":"Nanjing,Nanjing,Jiangsu,China","timezone":"Asia/Shanghai","timezone_offset":"+08:00"},
    "now":{"text":"Cloudy","code":"4","temperature":"37"},
    "last_update":"2022-07-13T16:00:13+08:00"}]}
    	*/
    	char *str = NULL;
    	str = strstr((char*)data,"name");
    	sscanf(str+7,"%[^\"]",LCD_Data.Location);
    	
    	str = strstr((char*)data,"last_update");
    	sscanf(str+14,"%[^T]",LCD_Data.Date);
    	
    	str = strstr((char*)data,"code");
    	sscanf(str+7,"%u",&LCD_Data.Weather_C);
    	
    	str = strstr((char*)data,"temperature");
    	sscanf(str+14,"%u",&LCD_Data.Temp_C);
    }
    
    void Analysis_Weather_Report(uint8_t * data,uint32_t len){
    	
    	/*
    	{"results":[{"location":{"id":"WTSQQYHVQ973","name":"Nanjing","country":"CN","path":"Nanjing,Nanjing,Jiangsu,China","timezone":"Asia/Shanghai","timezone_offset":"+08:00"},"daily":[
    {"date":"2022-07-13","text_day":"Cloudy","code_day":"4","text_night":"Cloudy","code_night":"4","high":"39","low":"29",
    "rainfall":"0.00","precip":"0.00","wind_direction":"W","wind_direction_degree":"270","wind_speed":"32.8","wind_scale":"5","humidity":"66"},
    {"date":"2022-07-14","text_day":"Cloudy","code_day":"4","text_night":"Cloudy","code_night":"4","high":"39","low":"30",
    "rainfall":"0.00","precip":"0.00","wind_direction":"W","wind_direction_degree":"270","wind_speed":"23.4","wind_scale":"4","humidity":"67"},
    {"date":"2022-07-15","text_day":"Cloudy","code_day":"4","text_night":"Cloudy","code_night":"4","high":"37","low":"28",
    "rainfall":"0.00","precip":"0.00","wind_direction":"NW","wind_direction_degree":"315","wind_speed":"15.3","wind_scale":"3","humidity":"71"}],
    "last_update":"2022-07-13T08:00:00+08:00"}]}
    	*/
    	char *s = NULL;
    	char *str[3] = {NULL,NULL,NULL};
    	uint32_t te = 0;
    	
    	str[0] = strstr((char*)data,"date");
    	str[1] = strstr(str[0]+10,"date");
    	str[2] = strstr(str[1]+10,"date");
    	
    	for(uint8_t i=0;i<3;i++){
    		s = strstr((char*)str[i],"date");
    		sscanf(s+7,"%[^\"]",Weather_Data[i].Date);
    	}
    	
    	for(uint8_t i=0;i<3;i++){
    		s = strstr((char*)str[i],"code_day");
    		sscanf(s+11,"%u",&Weather_Data[i].Weather);
    	}
    	
    	for(uint8_t i=0;i<3;i++){
    		s = strstr((char*)str[i],"high");
    		sscanf(s+7,"%u",&Weather_Data[i].Temp_H);
    	}
    	
    	for(uint8_t i=0;i<3;i++){
    		s = strstr((char*)str[i],"low");
    		sscanf(s+6,"%u",&Weather_Data[i].Temp_L);
    	}
    	
    	for(uint8_t i=0;i<3;i++){
    		s = strstr((char*)str[i],"humidity");
    		sscanf(s+11,"%u",&Weather_Data[i].Humi);
    	}
    	
    	for(uint8_t i=0;i<3;i++){
    		s = strstr((char*)str[i],"wind_scale");
    		sscanf(s+13,"%u",&Weather_Data[i].Wind);
    	}
    	
    
    }
    
    void Weather_Run(){
    		
    		WIFI_Send_Cmd_And_Wait_OK(WEATHER_Cmd[3]);//连接心知天气
    		WIFI_Send_Cmd_And_Wait_OK(WEATHER_Cmd[4]);//设置透传模式
    		WIFI_Send_Cmd_And_Wait_OK(WEATHER_Cmd[5]);//进入透传模式
    		
    		UART_Send_Data(&huart3,Querry_Current_Weather,strlen((char*)Querry_Current_Weather));	
    		while(1){
    			if(UART3_REC_State == Uart_Status_Ready){
    				Weather_Data_Handler(Uart3_Rec_Buffer,UART3_Rec_Cnt);
    				Analysis_Current_Weather(Uart3_Rec_Buffer,UART3_Rec_Cnt);
    				Weather_Buffer_Clear();
    				break;
    			}
    			osDelay(10);
    		}
    		osDelay(200);
    		UART_Send_Data(&huart3,Querry_Weather_Report,strlen((char*)Querry_Weather_Report));	
    		while(1){
    			if(UART3_REC_State == Uart_Status_Ready){
    				Weather_Data_Handler(Uart3_Rec_Buffer,UART3_Rec_Cnt);
    				Analysis_Weather_Report(Uart3_Rec_Buffer,UART3_Rec_Cnt);
    				Weather_Buffer_Clear();
    				break;
    			}
    			osDelay(10);
    		}
    		
    		HAL_GPIO_WritePin(ESP_RST_GPIO_Port, ESP_RST_Pin, GPIO_PIN_RESET);//关闭WIFI
    		
    }
    
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158

    6 最后

  • 相关阅读:
    【项目管理】敏捷项目每日站会中的四大“坑”
    举例说明计算机视觉(CV)技术的优势和挑战
    多态的概念
    vue中minxin和hooks区别
    docker export、import、save、load 区别
    笔试刷题Day—1
    Dynamsoft Barcode Reader SDK JAVA.9.2.X
    redis 登录案例
    使用一个文件集中管理你的 Nuget 依赖版本号
    前后缀表达式求值顺序栈C语言
  • 原文地址:https://blog.csdn.net/m0_71572576/article/details/126263849