一、功能简介

本项目使用STM32F103C8T6单片机控制器,使用IIC OLED液晶、28BYJ48步进电机模块、
MQ135空气质量传感器、DHT11温湿度、光敏传感器、按键模块、蜂鸣器、继电器模块
ESP8266 WIFI模块等。
主要功能:
系统运行后,OLED液晶显示环境温湿度、光照强度、空气质量以及窗户、空调、灯的
开关状态和模式状态;系统默认为自动模式,可通过K3键进入阈值设置模式,K3切换
阈值位置,K1和K2调节,K4确认。当检测温度高于上限,空调打开;温度低于下限,
空调关闭;当检测空气质量高于阈值,窗户打开,低于阈值,窗户关闭;
当光照强度低于阈值,打开灯,高于阈值关闭灯;
可通过K4键切换为手动模式,K1控制窗户开关,K2控制空调开关,K3控制灯开关;
系统将检测数据及设备状态通过ESP8266实时上传至机智云平台,可在电脑端机智云
或手机机智云APP端查看当前数据或控制设备状态、参数阈值和系统工作模式;


二、软件设计

/*
作者:嗨小易(QQ技术交流群:570487280)

*/





//协议初始化
void Gizwits_Init(void)
{
	TIM4_Init(9,7199);//1MS系统定时
    USART3_Init(9600);//WIFI初始化
	memset((uint8_t*)&currentDataPoint, 0, sizeof(dataPoint_t));//设备状态结构体初始化
	gizwitsInit();//缓冲区初始化
}


//系统参数初始化
void sys_parm_init(void)
{
	sys_ctrl.mode=0;
	sys_ctrl.set_temp[0]=25;sys_ctrl.set_temp[1]=30;
	sys_ctrl.set_gas=100;
	sys_ctrl.set_light=40;
	sys_ctrl.win_flag=0;
	sys_ctrl.kt_flag=0;
	sys_ctrl.led_flag=0;
	sys_ctrl.autoflag=0;
	
	sys_ctrl.wifi_sta=0;
}

//系统开机界面显示
void sys_open_show(void)
{
	OLED_Clear();
	//温度
	OLED_ShowFontHZ(0,0,0,16,1);
	OLED_ShowFontHZ(16,0,2,16,1);
	OLED_ShowString(16*2,0,":  C",16);
	//窗户开关
	OLED_ShowFontHZ(16*4+8,0,9,16,1);
	OLED_ShowFontHZ(16*5+8,0,10,16,1);
	OLED_ShowString(16*6+8,0,":",16);
	OLED_ShowFontHZ(16*7,0,15,16,1);
	//湿度
	OLED_ShowFontHZ(0,16,1,16,1);
	OLED_ShowFontHZ(16,16,2,16,1);
	OLED_ShowString(16*2,16,":  %",16);
	//空调开关
	OLED_ShowFontHZ(16*4+8,16,12,16,1);
	OLED_ShowFontHZ(16*5+8,16,13,16,1);
	OLED_ShowString(16*6+8,16,":",16);
	OLED_ShowFontHZ(16*7,16,15,16,1);
	//空气
	OLED_ShowFontHZ(0,32,3,16,1);
	OLED_ShowFontHZ(16,32,4,16,1);
	OLED_ShowString(16*2,32,":    ppm",16);
	//模式
	OLED_ShowFontHZ(16*7,32,18,16,1);
	//光线
	OLED_ShowFontHZ(0,48,5,16,1);
	OLED_ShowFontHZ(16,48,6,16,1);
	OLED_ShowString(16*2,48,":  %",16);
	//灯开关
	OLED_ShowFontHZ(16*5+8,48,11,16,1);
	OLED_ShowString(16*6+8,48,":",16);
	OLED_ShowFontHZ(16*7,48,15,16,1);
	
	OLED_Refresh_Gram();//刷新显示缓存
}

//系统参数设置界面显示
void sys_parm_set_show(void)
{
	OLED_Clear();
	//温度阈值
	OLED_ShowFontHZ(0,0,0,16,1);
	OLED_ShowFontHZ(16,0,2,16,1);
	OLED_ShowFontHZ(16*2,0,16,16,1);
	OLED_ShowFontHZ(16*3,0,17,16,1);
	OLED_ShowString(16*4,0,":  -  C",16);
	//空气阈值
	OLED_ShowFontHZ(0,16,3,16,1);
	OLED_ShowFontHZ(16,16,4,16,1);
	OLED_ShowFontHZ(16*2,16,16,16,1);
	OLED_ShowFontHZ(16*3,16,17,16,1);
	OLED_ShowString(16*4,16,":   ppm",16);
	//光线阈值
	OLED_ShowFontHZ(0,32,5,16,1);
	OLED_ShowFontHZ(16,32,6,16,1);
	OLED_ShowFontHZ(16*2,32,16,16,1);
	OLED_ShowFontHZ(16*3,32,17,16,1);
	OLED_ShowString(16*4,32,":  %",16);
	
	OLED_Refresh_Gram();//刷新显示缓存
}

//系统数据获取
void sys_data_get(void)
{
	while(1)
	{
		//获取温湿度
		DHT11_Read_Data(&sys_ctrl.temp,&sys_ctrl.humi);
		//获取空气质量
		sys_ctrl.gas=mq135_get_ppm(Get_ADC_Value(ADC_Channel_9,10));
		//获取光照强度
		sys_ctrl.light=99-Get_ADC2_Value(ADC_Channel_0,5)/41;
		
		break;
	}
}

//系统数据显示
void sys_data_show(void)
{
	while(1)
	{
		//正常模式显示
		if(sys_ctrl.mode==0)
		{
			//温度显示
			OLED_ShowNum(16*2+8,0,sys_ctrl.temp,2,16);
			//湿度显示
			OLED_ShowNum(16*2+8,16,sys_ctrl.humi,2,16);
			//空气质量显示
			OLED_ShowNum(16*2+8,32,sys_ctrl.gas,4,16);
			//光照强度
			OLED_ShowNum(16*2+8,48,sys_ctrl.light,2,16);
			
			//窗户开关状态显示
			if(sys_ctrl.win_flag==0)OLED_ShowFontHZ(16*7,0,15,16,1);
			else OLED_ShowFontHZ(16*7,0,14,16,1);
			//空调开关状态显示
			if(sys_ctrl.kt_flag==0)OLED_ShowFontHZ(16*7,16,15,16,1);
			else OLED_ShowFontHZ(16*7,16,14,16,1);
			//自动手动模式
			if(sys_ctrl.autoflag==0)OLED_ShowFontHZ(16*7,32,18,16,1);
			else OLED_ShowFontHZ(16*7,32,19,16,1);
			//灯开关状态显示
			if(sys_ctrl.led_flag==0)OLED_ShowFontHZ(16*7,48,15,16,1);
			else OLED_ShowFontHZ(16*7,48,14,16,1);
		}
		//参数设置模式显示
		else
		{
			switch(sys_ctrl.mode)
			{
				case 1://温度下
					//温度阈值
					OLED_ShowxNum(16*4+8,0,sys_ctrl.set_temp[0],2,16,0,0);
					OLED_ShowxNum(16*4+8*4,0,sys_ctrl.set_temp[1],2,16,0,1);
					//空气阈值
					OLED_ShowxNum(16*4+8,16,sys_ctrl.set_gas,3,16,0,1);
					//光线阈值
					OLED_ShowxNum(16*4+8,32,sys_ctrl.set_light,2,16,0,1);
					break;
				case 2://温度上
					OLED_ShowxNum(16*4+8,0,sys_ctrl.set_temp[0],2,16,0,1);
					OLED_ShowxNum(16*4+8*4,0,sys_ctrl.set_temp[1],2,16,0,0);
					break;
				case 3://空气阈值
					OLED_ShowxNum(16*4+8*4,0,sys_ctrl.set_temp[1],2,16,0,1);
					OLED_ShowxNum(16*4+8,16,sys_ctrl.set_gas,3,16,0,0);
					break;
				case 4://光线阈值
					OLED_ShowxNum(16*4+8,16,sys_ctrl.set_gas,3,16,0,1);
					OLED_ShowxNum(16*4+8,32,sys_ctrl.set_light,2,16,0,0);
					break;
			}
		}
		
		OLED_Refresh_Gram();//刷新显示缓存
		break;
	}
}

//系统数据设置
void sys_data_set(void)
{
	u8 key=0;
	static u8 oneflag=0;
	
	key=KEY_Scan(0);
	//提示音
	if(key!=0)BEEP_Alarm(1000,100);
	
	//自动
	if(sys_ctrl.autoflag==0)
	{
		//参数设置
		if(key==KEY3_PRESS)
		{
			sys_ctrl.mode++;
			if(sys_ctrl.mode>4)sys_ctrl.mode=1;
			if(oneflag==0)
			{
				oneflag=1;
				sys_parm_set_show();//系统参数设置界面显示
			}
		}
		//加
		else if(key==KEY1_PRESS)
		{
			switch(sys_ctrl.mode)
			{
				case 0://Air-link模式接入
					gizwitsSetMode(WIFI_AIRLINK_MODE);
					break;
				case 1://温度下
					sys_ctrl.set_temp[0]++;
					if(sys_ctrl.set_temp[0]>99)sys_ctrl.set_temp[0]=0;
					break;
				case 2://温度上
					sys_ctrl.set_temp[1]++;
					if(sys_ctrl.set_temp[1]>99)sys_ctrl.set_temp[1]=0;
					break;
				case 3://空气上
					sys_ctrl.set_gas+=50;
					if(sys_ctrl.set_gas>900)sys_ctrl.set_gas=0;
					break;
				case 4://光线下
					sys_ctrl.set_light++;
					if(sys_ctrl.set_light>99)sys_ctrl.set_light=0;
					break;
			}
		}
		//减
		else if(key==KEY2_PRESS)
		{
			switch(sys_ctrl.mode)
			{
				case 0://WIFI复位
					gizwitsSetMode(WIFI_RESET_MODE);
					break;
				case 1://温度下
					sys_ctrl.set_temp[0]--;
					if(sys_ctrl.set_temp[0]<0)sys_ctrl.set_temp[0]=99;
					break;
				case 2://温度上
					sys_ctrl.set_temp[1]--;
					if(sys_ctrl.set_temp[1]<0)sys_ctrl.set_temp[1]=99;
					break;
				case 3://空气上
					sys_ctrl.set_gas-=50;
					if(sys_ctrl.set_gas<0)sys_ctrl.set_gas=900;
					break;
				case 4://光线下
					sys_ctrl.set_light--;
					if(sys_ctrl.set_light<0)sys_ctrl.set_light=99;
					break;
			}
		}
		//确定
		else if(key==KEY4_PRESS)
		{
			if(sys_ctrl.mode==0)//手动
			{
				sys_ctrl.autoflag=1;
			}
			else
			{
				sys_ctrl.mode=0;
				oneflag=0;
				sys_open_show();//系统开机界面显示
			}
		}
	}
	//手动
	else
	{
		//窗户开关
		if(key==KEY1_PRESS)
		{
			sys_ctrl.win_flag=!sys_ctrl.win_flag;
		}
		//空调开关
		else if(key==KEY2_PRESS)
		{
			sys_ctrl.kt_flag=!sys_ctrl.kt_flag;
		}
		//灯开关
		else if(key==KEY3_PRESS)
		{
			sys_ctrl.led_flag=!sys_ctrl.led_flag;
		}
		//自动
		else if(key==KEY4_PRESS)
		{
			sys_ctrl.autoflag=0;
		}
	}
}

//应用控制系统
void app_sys_ctrl_demo(void)
{
	u8 i=10;
	
	sys_parm_init();//系统参数初始化
	LED_Init();
	USART1_Init(115200);
	OLED_Init();
	KEY_Init();
	BEEP_Init();
	STEP_Motor_Init();
	ctrl_pin_init();
	DHT11_Init();
	//获取稳定数据
	while(i--)
	{
		DHT11_Read_Data(&sys_ctrl.temp,&sys_ctrl.humi);
		delay_ms(100);
	}
	ADCx_Init();
	Gizwits_Init();//协议初始化
	sys_open_show();//系统开机界面显示

	while(1)
	{
		sys_data_get();//系统数据获取
		sys_data_show();//系统数据显示
		sys_data_set();//系统数据设置
		sys_fun_ctrl();//系统功能控制
		
		userHandle();//用户采集
		gizwitsHandle((dataPoint_t *)&currentDataPoint);//协议处理
	}
}





三、实验现象

B站演示视频:https://space.bilibili.com/444388619

在这里插入图片描述
在这里插入图片描述

联系作者

视频地址:https://space.bilibili.com/444388619/video
专注于51单片机、STM32、国产32、DSP、Proteus、arduino、ESP32、物联网软件开发,PCB设计,视频分享,技术交流。

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐