STM32项目分享:智能大棚(蓝牙版)

目录

一、前言

二、项目简介

1.功能详解

2.主要器件

三、原理图设计

四、PCB硬件设计

PCB图 

五、程序设计 

六、实验效果 

七、资料内容

项目分享


一、前言

项目成品图片:

哔哩哔哩视频链接:

STM32智能大棚(蓝牙版)

(资料分享见文末) 

二、项目简介

1.功能详解

基于STM32的智能大棚(蓝牙版)

功能如下:

  1. STM32F103C8T6单片机作为主控制器
  2. 防水式DS18B20检测土壤温度,当温度大于设置最大值,进行声光报警,并同时开启风扇进行降温;当温度小于设置最小值,进行声光报警,并同时开启加热片进行升温
  3. 土壤湿度模块检测土壤湿度,当湿度小于设置最小值,进行声光报警,并同时开启水泵进行加水,直到湿度大于设置最大值;
  4. 光敏电阻检测光照值,当光照值低于设置最小值进行补光
  5. 通过按键设置各阈值
  6. OLED显示屏显示测量值
  7. 蓝牙模块将测量数据发送到手机端

2.主要器件

  • STM32F103C8T6单片机
  • OLED 屏幕
  • DS18B20温度传感器
  • 光敏传感器
  • 土壤湿度传感器
  • BT04A蓝牙模块
  • 继电器
  • 有源蜂鸣器
  • 加热片
  • 水泵
  • 风扇模块
  • LED照明灯模块

三、原理图设计

四、PCB硬件设计

PCB图 

五、程序设计 

#include "sys.h"
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
#include "math.h"
#include "delay.h"
#include "gpio.h"
#include "key.h"
#include "oled.h"
#include "usart.h"
#include "ds18b20.h"
#include "adc.h"


int main(void)
{
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //配置中断优先分组
	Delay_Init();	    	 								//延时初始化	  
	Gpio_Init();		  									//IO初始化
	Key_Init();		  										//按键初始化
	Oled_Init();		  									//OLED初始化
	Oled_Clear_All();										//清屏
	Usart1_Init(9600);    							//串口1初始化
	DS18B20_Init();											//DS18B20初始化
	Adc_Init();													//ADC初始化
	Delay_ms(1000);
	Delay_ms(1000);
	
	while(1)
	{
key_num = Chiclet_Keyboard_Scan(0);		//按键扫描
	if(key_num != 0)											//有按键按下
	{
		switch(key_num)
		{
			case 1:								            //按键1,切换设置界面
				flag_display++;
				if(flag_display >= 6)
					flag_display = 0;
				
				Oled_Clear_All();					      //清屏
			break;

			case 2:											      //按键2
				switch(flag_display)
				{					
					case 1:												//界面1:温度最大值+1
						if(temp_max < 99)
							temp_max++;
					break;
					
					case 2:												//界面2:温度最小值+1
						if(temp_min < temp_max-1)
							temp_min++;
					break;
					
					case 3:												//界面3:湿度最大值+1
						if(soil_max < 99)
							soil_max++;
					break;
					
					case 4:												//界面4:湿度最小值+1
						if(soil_min < soil_max-1)
							soil_min++;
					break;
					
					case 5:												//界面5:光照最小值
						if(light_min < 99)
							light_min++;
					break;
					
					default:
					break;
				}
			break;

			case 3:														//按键3
				switch(flag_display)
				{					
					case 1:												//界面1:温度最大值-1
						if(temp_max > temp_min+1)
							temp_max--;
					break;
					
					case 2:												//界面2:温度最小值-1
						if(temp_min > 0)
							temp_min--;
					break;
					
					case 3:												//界面3:湿度最大值-1
						if(soil_max > soil_min+1)
							soil_max--;
					break;
					
					case 4:												//界面4:湿度最小值-1
						if(soil_min > 0)
							soil_min--;
					break;
					
					case 5:												//界面5:光照最小值-1
						if(light_min > 0)
							light_min--;
					break;
					
					default:
					break;
				}
			break;

			default:
				
			break;
		}
	}
if(flag_display == 0)									//测量界面
	{
		if(time_num % 5 == 0)								//获取数据
		{
			temp_value = DS18B20_Get_Temp();
			light_value = 99-30*(Get_Adc_Average(0,3)*3.3/4096.0);	
			soil_value = 99-30*(Get_Adc_Average(1,3)*3.3/4096.0);	
		}
		
		if(time_num % 30 == 0)							//发送数据
		{
			UsartPrintf(USART1,"温度:%d.%dC\r\n",temp_value/10,temp_value%10);
			UsartPrintf(USART1,"湿度:%d%%\r\n",soil_value);
			UsartPrintf(USART1,"光照:%dLux\r\n",light_value);
		}
	}
		switch(flag_display)									//根据不同的显示模式标志位,显示不同的界面
	{
		case 0:									      			//界面0:显示温度,湿度,光照的数值
			Oled_ShowCHinese(1,1,"土壤环境监测");
		
			Oled_ShowCHinese(2,0,"温度:");
			sprintf(display_buf,"%d.%dC  ",temp_value/10,temp_value%10);
			Oled_ShowString(2,6,display_buf);
		
			Oled_ShowCHinese(3,0,"湿度:");
			sprintf(display_buf,"%d%%  ",soil_value);
			Oled_ShowString(3,6,display_buf);

			Oled_ShowCHinese(4,0,"光照:");
			sprintf(display_buf,"%dLux  ",light_value);
			Oled_ShowString(4,6,display_buf);
		break;
		
		case 1:															//界面1:设置温度最大值
			Oled_ShowCHinese(1,0,"设置温度最大值");
			if(time_num % 5 == 0)
			{
				sprintf(display_buf,"%d  ",temp_max);
				Oled_ShowString(2, 7, display_buf);
			}
			if(time_num % 10 == 0)
			{
				Oled_ShowString(2, 7, "    ");
			}
		break;
		
		case 2:															//界面2:设置温度最小值
			Oled_ShowCHinese(1,0,"设置温度最小值");
			if(time_num % 5 == 0)
			{
				sprintf(display_buf,"%d  ",temp_min);
				Oled_ShowString(2, 7, display_buf);
			}
			if(time_num % 10 == 0)
			{
				Oled_ShowString(2, 7, "    ");
			}
		break;
		
		case 3:															//界面3:设置湿度最大值
			Oled_ShowCHinese(1,0,"设置湿度最大值");
			if(time_num % 5 == 0)
			{
				sprintf(display_buf,"%d  ",soil_max);
				Oled_ShowString(2, 7, display_buf);
			}
			if(time_num % 10 == 0)
			{
				Oled_ShowString(2, 7, "    ");
			}
		break;
		
		case 4:														//界面4:设置湿度最小值
			Oled_ShowCHinese(1,0,"设置湿度最小值");
			if(time_num % 5 == 0)
			{
				sprintf(display_buf,"%d  ",soil_min);
				Oled_ShowString(2, 7, display_buf);
			}
			if(time_num % 10 == 0)
			{
				Oled_ShowString(2, 7, "    ");
			}
		break;

		case 5:														//界面5:设置光照最小值
			Oled_ShowCHinese(1,0,"设置光照最小值");
			if(time_num % 5 == 0)
			{
				sprintf(display_buf,"%d  ",light_min);
				Oled_ShowString(2, 7, display_buf);
			}
			if(time_num % 10 == 0)
			{
				Oled_ShowString(2, 7, "    ");
			}
		break;
		
		default:
			
		break;
	}

	if(flag_display == 0)                  //测量界面
	{
		if(temp_value < temp_min*10)				//温度小于最小值,开启加热,和声光报警
		{
			flag_temp_min = 1;
			flag_temp_max = 0;
			FS = 0;
			JR = 1;		
		}
		else if(temp_value > temp_max*10) 	//温度大于最大值,开启风扇,和声光报警
		{
			flag_temp_min = 0;
			flag_temp_max = 1;
			FS = 1;
			JR = 0;			
		}
		else																//温度在两者之间关闭风扇和加热和声光报警
		{
			flag_temp_min = 0;
			flag_temp_max = 0;
			FS = 0;
			JR = 0;			
		}
		if(soil_value < soil_min)						//湿度小于最小值开启水泵和声光报警
		{
			flag_soil_min = 1;
			JS = 1;
		}
		else if(soil_value > soil_max)			//湿度大于最大值关闭水泵和声光报警
		{
			flag_soil_min = 0;
			JS = 0;		
		}
		else																//湿度在两者之间关闭声光报警
		{
			flag_soil_min = 0;	
		}
		if(light_value < light_min)					//光照小于最小值开启补光
			BG = 1;
		else																//光照大于最小值关闭补光
			BG = 0;
		
		if(flag_temp_min == 1 || flag_temp_max == 1 || flag_soil_min == 1) 
		{
			if(time_num % 3 == 0)							//开启声光报警											
			{
				LED = ~LED;
				BEEP = ~BEEP;
			}
		}
		else																//关闭声光报警	
		{
			LED = 1;
			BEEP = 0;
		}		
	}
	else													         //设置界面
	{
		LED = 1;
		BEEP = 0;
		FS = 0;
		JS = 0;
		JR = 0;
		BG = 0;		
	}

		time_num++;												//计时变量+1
		Delay_ms(10);
		if(time_num %10 == 0)
			LED_SYS = ~LED_SYS;
		if(time_num >= 5000)
		{
			time_num = 0;
		}
	}
}

六、实验效果 

七、资料内容

项目分享