STM32项目分享:基于STM32的智能家居系统

基于stm32的智能家居项目 之前学完stm32之后,决定跟着网上的教程做一个智能家居项目。其中用到的硬件主要是正点原子stm32的ZET6精英板,DHT11温湿度传感器、光敏传感器、ESP8266模块。对stm32了解加深了一些https。 阅读详情
AI摘要

本文介绍了一个基于STM32F103C8T6的智能家居系统,集成多种传感器与通信模块。系统具备环境监测、报警提示、语音控制、视觉识别及远程APP控制等功能,通过ESP8266实现联网,结合K210进行人脸识别,实现了多模态智能交互与自动化响应。

目录

一、前言

二、项目简介

三、原理图设计

四、PCB设计

五、程序设计

六、资料内容

七、资料获取


一、前言

项目成品图品:

哔哩哔哩视频链接:

【开源】基于STM32的智能家居系统

二、项目简介

1、主要器件

主控:STM32F103C8T6(最小系统版本)  

模块: 826601s + 步进电机(28) + LED(蓝色) + LED(黄色) + SG90舵机+K210+温湿度DHT11+MQ135+火焰传感器+蜂鸣器LED(红色)+MQ4  + ESP32CAM + OLED(0.96) 显示数据 + 按键界面切换 * 4   + 语音控制SU30T

2、功能详解

1、STM32循环读取所有传感器(DHT11, MQ135, MQ4)的数据。 在OLED上更新显示当前选定的界面数据。

2、检测按键操作,执行界面切换或其他功能。

3、环境异常:当任何传感器值超过阈值(如检测到火焰、CO浓度过高),STM32会:点亮红色LED,启动蜂鸣器报警。

4、通过ESP8266向手机App或云平台发送报警信息。

5、语音控制:SU-03T接收到特定指令后,通过串口通知STM32,STM32执行相应动作(如控制舵机转动、LED、步进电机)。

6、视觉识别:K210完成识别后,将结果(如“识别到人脸”)发送给STM32,STM32根据结果决定下一步动作(如舵机转动跟踪、蜂鸣器响一声)。

7、远程指令(APP):STM32通过ESP8266接收云端指令,控制电机、LED等设备。

三、原理图设计

四、PCB设计

PCB图

3D图

五、程序设计

#include "delay.h"
#include "sys.h"
#include "led.h" //控制器
#include "oled.h"
#include "esp8266.h"
#include "Timer.h"
#include "Key.h"
#include "stmflash.h"
#include "su_03t.h"


// 传感/执行模块
#include "dht11.h"
#include "adc.h"
#include "../HARDWARE/Step_motor/MOTOR.h"
#include "../HARDWARE/Fire Sensor/Fire.h"

//C库
#include <string.h>
#include "stdio.h"
#include "math.h"
#include "stdbool.h"
#include "pwm.h"      // 舵机控制
#include "Usart.h"    // 串口通信


/*********************************** 变量声明**********************************/
extern unsigned char esp8266_buf[buf_len];
// 定义在头文件中声明的外部变量
control_mode MODE = manual_mode;  // 初始化为手动模式
//阈值结构体
struct Set_data
{
  u16 temp_H;  //温度上限
	u16 temp_L;  //温度下限
	u16 air_H;  //空气质量上限
	u16 co_H;   //一氧化碳上限
};

struct Set_data Out_data={30,20,30,40};//初始化阈值

//数据获取
u16 temp_value=0;
u16 humi_value=0;
u16 co_value=0;
float air_value=0;

DHT11_Data_TypeDef DHT11_Data;//dht11添加变量 

////按键相关的变量
u8 key_num=0,Page_flag=1;
char TIMER_IT=0,WiFiInit_time,Flagout=1;

//oled相关变量
u8 oled_Fill_flag=1;//OLED清屏标志
char oled_str[100];//OLED显示缓存
char date[200];//esp8266发送缓存

bool beep_flag=false;//蜂鸣器标志位
//DOOR=false;//门锁状态
u8 alarm_flag=0;//报警标志位

u8 air_alarm;
u8 co_alarm;

u8 face_state;//人脸状态  是否成功识别

u16 face_num; //识别次数
u8 success_sent;

uint16_t fire_val;
bool has_fire; // 若传感器为高电平触发
u8 fire_flag=0;//火灾播报标志位
u8 co_flag=0;
u8 air_flag=0;
int num;
/********************************函数声明**********************************/
// 在main函数前添加函数声明
void Page_data(void);    // 数据显示界面
void Page_control(void);    //控制外设
void Page_setting(void); // 设置界面
void APP_Control(void); //APP数据下发
void BI_BI(void); //哔哔提醒数据下发


int main(void){
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	Adc_Init();//可燃气  空气质量
	DHT11_Init();//初始化DHT11
	
	LED_Init();
	Servo_Init();  // 初始化舵机
	Serial_Iint(9600);  // 初始化串口3用于K210通信
	
	COLD=OFF;//制冷关闭
	HOT=OFF;//制热关闭
	LED=OFF;//LED关闭
	BEEP=OFF;//蜂鸣器关闭
	DOOR=OFF;//关门
		
  Key_Init();//按键初始化
  SU_03T_Iint(9600);//SU03T  语言
  motor_init(); // 步进电机初始化
	FIRE_Init();     // 火焰传感器初始化
	SU_03T_Iint(9600);//语音模块

	
  OLED_Init();//OLED初始化
  OLED_Clear(0);
	    
	do
	{
			OLED_ShowText(0, 0,(u8*) "是否需要联网?", 0);
			OLED_ShowText(8, 4,(u8*) "1.是  2.否", 0);
			key_num=KEY_Scan(0);//按键扫描
			if(key_num==1)//需要联网
			{
					OLED_Clear(0);
					Timer_Init();
					ESP8266_Init(115200);
					break;
			}
	}while(key_num!=2); 
		
   OLED_Clear(0);

    /*读出内存数据*/
    STMFLASH_Read(FLASH_SAVE_ADDR,    &Out_data.temp_H,1);
    delay_ms(100);
		STMFLASH_Read(FLASH_SAVE_ADDR+2,  &Out_data.temp_L,1);
    delay_ms(100);
    STMFLASH_Read(FLASH_SAVE_ADDR+4,  &Out_data.air_H,1);
    delay_ms(100);
		STMFLASH_Read(FLASH_SAVE_ADDR+6,  &Out_data.co_H,1);
    delay_ms(100);
   
   

	while(1)
	{
     /*********************************数据处理区*********************************/ 
		
					//获取温湿度 
					Read_DHT11(&DHT11_Data);    
					temp_value= DHT11_Data.temp_int; //获取温度
					humi_value= DHT11_Data.humi_int; //获取湿度
		
		     //获取一氧化碳
		
		     co_value= GetMQ4Value();
		
				//获取空气质量
				
		     air_value=MQ135_GetData_PPM();
		
		    
		    /***************判断是否有火**************************/
			
         fire_val = FIRE_GetData();
				 has_fire = (fire_val == 1); // 若传感器为低电平触发
		
        /*******************向巴法云发送数据***************************************/
        if(TIMER_IT)
        {
            TIMER_IT=0;
            sprintf(date,"cmd=2&uid=%s&topic=data&msg=#%d#%d#%d#%d#%d#%d#%d#%d#sensordata#\r\n",\
            BEMFA_ID,
            MODE,(int)temp_value,(int)humi_value,(int)air_value,(int)co_value,(int)co_alarm,(int)air_alarm,(int)fire_val);
            ESP8266_SendData((unsigned char *)date);//ESP8266发送数据
        }	
   /*********************************人机交互区**************************************************/      
				key_num=KEY_Scan(0);//按键扫描
        if(key_num==1)//界面切换键
        {
            Page_flag++;
            Page_flag=Page_flag%3;
            OLED_Clear(0);//清屏
        }      
        //界面切换功能
        switch(Page_flag)
        {    
            case 1: 
                Page_data();    // 第一界面 - 数据显示
                break;
            case 2: 
                Page_control();    //控制外设; // 第三界面 - 设置界面
                break;
            case 0: 
                Page_setting(); // 第三界面 - 设置界面
                break;
        }

	/*********************************模式控制区*********************************/
  
	/******************APP指令下发********************************/
  APP_Control();//阈值下发  模式转换
    			
	/********************自动模式******************************/
				
			/*当环境温度过高打开空调制冷,
			
			当环境温度过低打开空调制热,
				
	*/			
	if(MODE==auto_mode){
			//温度控制
			if(temp_value>Out_data.temp_H)
			{
				COLD=ON;
				HOT=OFF;
			}
			else if(temp_value<Out_data.temp_L)
			{
				COLD=OFF;
				HOT=ON;
			}
			else
			{
				COLD=OFF;
				HOT=OFF;
			}
			
				
			// 火焰传感器联动蜂鸣器:有火则鸣叫,无火则静音
			
      if(fire_val==1){
      
        beep_flag=true;
        
        if(fire_flag==1){
        SU_03T_SendArray(fire_TxPacket, 5);
        fire_flag=0;
        
        }
      }else{ beep_flag = false;}



    
       


       // 空气质量超标控制  
       if(air_value > Out_data.air_H)
       {
					  air_alarm=1;
           // 空气质量差时开启窗帘通风
           if(StateCurtain == 0) // 窗帘关闭状态
           {
               Motor_Ctrl_Angle_Z(90, MOTOR_SPEED); // 打开窗帘
               StateCurtain = 1;
           }
           // 开启制冷改善空气质量
           COLD = ON;
					 
					  if(air_flag==1){
					  SU_03T_SendArray(air_TxPacket, 5);
						air_flag=0;
						 
					 }
       }
			 else {  air_alarm=0;}


				
			  // CO浓度超标控制
       if(co_value > Out_data.co_H)
       {
          co_alarm=1;
				 // CO超标时开启窗帘通风
//           if(StateCurtain == 0) // 窗帘关闭状态
//           {
//               Motor_Ctrl_Angle_Z(90, MOTOR_SPEED); // 打开窗帘
//               StateCurtain = 1;
//           }
//           // 开启制冷降低室内温度
//           COLD = ON;
           // 触发报警
           beep_flag = true;
					
					 
					 if(co_flag==1){
					  SU_03T_SendArray(co_TxPacket, 5);
						co_flag=0;
						 
					 }
       }else{co_alarm=0;}

			 
		if (Serial_RxFlag == 1)
        {
					
					   success_sent = 1;
            Serial_RxFlag = 0;
            if (strcmp(Serial_RxPacket, "success") == 0)
                {
                  
                   
										
                    if(!DOOR) {Servo_SetAngle(90); DOOR=ON;  
										SU_03T_SendArray(success_TxPacket, 5);
										face_state=1;
                    face_num+=1;}                 // 舵机转到90度位置开门
                  
                
            }
            else if (strcmp(Serial_RxPacket, "Err") == 0)
                       {
                           static int err_count = 0;
                          // static int error_sent = 0;
												 
                           if(DOOR){Servo_SetAngle(0); DOOR=OFF;
													 face_state=0;
                           face_num+=1;} // 舵机转回0度位置关门 
													 
													 
                           err_count++;
                        
                           if (err_count >= 20) {
														 
                             SU_03T_SendArray(nosuccess_TxPacket, 5);
                              // error_sent++;
                               BEEP = ON;                          // 报警提示
                               delay_ms(500);
                               BEEP = OFF;
                               delay_ms(500);
                               BEEP = ON;                          
                               delay_ms(500);
                               BEEP = OFF;                         // 连续报警三声
                               delay_ms(500);
                               BEEP = ON;                          
                               delay_ms(500);
                               BEEP = OFF;     
                               err_count = 0; // 复位计数
                           }
                       }
											 
											 
						memset(Serial_RxPacket, 0, 50);
						static u16 last_sent_face_num = 0;
											 
						if(face_num != last_sent_face_num  && success_sent == 1) {
						sprintf(date,"cmd=2&uid=%s&topic=data&msg=#%d#%d#costdata#\r\n",\
						BEMFA_ID, face_state,face_num);
						ESP8266_SendData((unsigned char *)date);//ESP8266发送数据
						last_sent_face_num = face_num;
						success_sent = 0;
             }	
							
							
							
			       }
						
			
	
						 
						 
			
		}//自动模式
		
	
		
  /********************手动模式*****************************/
			
	if(MODE==manual_mode)//手动模式
		{
			
					
				 // 检查是否需要发送空气质量
		if(SU_03T_GetSendAirFlag==1)
		{
				// 发送帧头
				SU_03T_SendByte(0xAA);
				SU_03T_SendByte(0x55);
				
				// 发送命令字
				SU_03T_SendByte(0x06);
				
				// 发送年月日时分秒数据
				int air_data[1];
				air_data[0] = (int)air_value;  //空气质量
			
				// 调整发送顺序为低字节在后
				// 发送每个时间值(4字节)
				for(int i = 0; i < 1; i++)
				{
						// 调整发送顺序为低字节在后
						SU_03T_SendByte(air_data[i] & 0xFF);          // 最低字节
						SU_03T_SendByte((air_data[i] >> 8) & 0xFF);   // 次低字节
						SU_03T_SendByte((air_data[i] >> 16) & 0xFF);  // 次高字节
						SU_03T_SendByte((air_data[i] >> 24) & 0xFF);  // 最高字节
				}
			
					
				// 发送帧尾
				SU_03T_SendByte(0x55);
				SU_03T_SendByte(0xAA);
			
				SU_03T_GetSendAirFlag=0;  //重置标志位
			
		}	 
			
			
			/****************APP控制***************************/
				//LED控制
				if(strstr((const char *)esp8266_buf,"LED_ON")!=0)
				{
							 LED=ON;
								 BI_BI();//哔哔提醒
				}
				else if(strstr((const char *)esp8266_buf,"LED_OFF")!=0)
				{
							LED=OFF;
						 BI_BI();//哔哔提醒
				} 
				//制冷控制
				if(strstr((const char *)esp8266_buf,"COLD_ON")!=0)
				{
							 COLD=ON;
						 BI_BI();//哔哔提醒
				}
				else if(strstr((const char *)esp8266_buf,"COLD_OFF")!=0)
				{
							COLD=OFF;
						 BI_BI();//哔哔提醒
				}
				//制热控制
				if(strstr((const char *)esp8266_buf,"HOT_ON")!=0)
				{
							 HOT=ON;
						 BI_BI();//哔哔提醒
				}
				else if(strstr((const char *)esp8266_buf,"HOT_OFF")!=0)
				{
							HOT=OFF;
						 BI_BI();//哔哔提醒
				}

          // 手动模式下的窗帘控制
      if( strstr((const char *)esp8266_buf,"CT_ON")!=0 ) // 窗帘打开
      { 
					 BI_BI();//哔哔提醒
          if(StateCurtain == 0)
          {
              Motor_Ctrl_Angle_Z(90, MOTOR_SPEED);
              StateCurtain = 1;
          }
          BI_BI();//哔哔提醒
          ESP8266_Clear();//清除缓存
      }
      else if( strstr((const char *)esp8266_buf,"CT_OFF")!=0 ) // 窗帘关闭
      {
					 BI_BI();//哔哔提醒
          if(StateCurtain == 1)
          {
              Motor_Ctrl_Angle_F(90, MOTOR_SPEED);
              StateCurtain = 0;
          }
          BI_BI();//哔哔提醒
          ESP8266_Clear();//清除缓存
      }
          
					//制热控制
				if(strstr((const char *)esp8266_buf,"DOOR_ON")!=0)
				{
						 if(!DOOR){Servo_SetAngle(90); DOOR=ON;}
						 BI_BI();//哔哔提醒
				}
				else if(strstr((const char *)esp8266_buf,"DOOR_OFF")!=0)
				{
							 if(DOOR){Servo_SetAngle(0); DOOR=OFF;}
						 BI_BI();//哔哔提醒
				}
				
				 ESP8266_Clear();//清除缓存

				
		}//手动模式

     
    }//while
}//main



void TIM2_IRQHandler(void)
{
 if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)
    {
			if(num>=5){
			 fire_flag=1;//火灾播报标志位
			 co_flag=1;
			 air_flag=1;  
			 num=0;
			
			}
				num++;
        TIMER_IT=1;
        
        if(beep_flag)
        {
            BEEP=!BEEP;
        }
        else
        {
            BEEP=0;
        }
        
        TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
    }
}


void APP_Control(void)
{
   //模式切换
   if( strstr((const char *)esp8266_buf,"ZD")!=0 )
   { 
       MODE=auto_mode;
       BI_BI();//哔哔提醒
       ESP8266_Clear();//清除缓存
   }
   else if( strstr((const char *)esp8266_buf,"SD")!=0 )
   {
       MODE=manual_mode;
       beep_flag=false;
       BEEP=OFF;
       HOT=OFF;
       COLD=OFF;
       LED=OFF;
   
      if(DOOR){Servo_SetAngle(0); DOOR=OFF;}  
		   BI_BI();//哔哔提醒
       ESP8266_Clear();//清除缓存
   } 
   

  
   
   char *jj_ptr = strstr((char *)esp8266_buf, "TH");
   if (jj_ptr != NULL && sscanf(jj_ptr + 2, "=%hu", &Out_data.temp_H) == 1) 
   {	
           
     BI_BI();//哔哔提醒
      ESP8266_Clear();//清除缓存
     STMFLASH_Write(FLASH_SAVE_ADDR, &Out_data.temp_H, 1);

   }
   
   char *tw_ptr = strstr((char *)esp8266_buf, "TL");
   if (tw_ptr != NULL && sscanf(tw_ptr + 2, "=%hu", &Out_data.temp_L) == 1) 
   {	
         
     BI_BI();//哔哔提醒
      ESP8266_Clear();//清除缓存
     STMFLASH_Write(FLASH_SAVE_ADDR+2, &Out_data.temp_L, 1);
   }
   
   // CO阈值设置
   char *co_ptr = strstr((char *)esp8266_buf, "COH");
   if (co_ptr != NULL && sscanf(co_ptr + 3, "=%hu", &Out_data.co_H) == 1) 
   {	
     BI_BI();//哔哔提醒
     ESP8266_Clear();//清除缓存
     STMFLASH_Write(FLASH_SAVE_ADDR+4, &Out_data.co_H, 1);
   }
   
   // 空气质量阈值设置
   char *air_ptr = strstr((char *)esp8266_buf, "AIR");
   if (air_ptr != NULL && sscanf(air_ptr + 3, "=%hu", &Out_data.air_H) == 1) 
   {	
     BI_BI();//哔哔提醒
     ESP8266_Clear();//清除缓存
     STMFLASH_Write(FLASH_SAVE_ADDR+6, &Out_data.air_H, 1);
   }
  
}

// 数据显示界面
void Page_data(void)
{
		// 添加按键2的模式切换功能
    if(key_num==2)//模式切换键
    {
        MODE++;
        if(MODE > manual_mode) MODE = auto_mode; // 循环切换:自动->手动->自动
        
        // 切换到手动模式时关闭报警和设备
        if(MODE == manual_mode)
        {
            beep_flag=false;
            BEEP=OFF;
					  HOT=OFF;
					  COLD=OFF;
						LED=OFF;
      
           if(DOOR){Servo_SetAngle(0); DOOR=OFF;}
					 if(StateCurtain == 1)
          {
              Motor_Ctrl_Angle_F(90, MOTOR_SPEED);
              StateCurtain = 0;
          }
        }
    }
  
		//空气质量
		sprintf(oled_str,"空气质量:%dppm   ",(int)air_value);
    OLED_ShowText(0,0,(u8*)oled_str,0);
	  //一氧化碳浓度
	  sprintf(oled_str,"CO浓度:%dppm   ",(int)co_value);
    OLED_ShowText(0,2,(u8*)oled_str,0);
		
    //温度显示
    sprintf(oled_str,"温度:%3d℃  ",(int)temp_value);
    OLED_ShowText(0,4,(u8*)oled_str,0);
	  //湿度显示
	  sprintf(oled_str,"湿度:%3d%%",(int)humi_value);
    OLED_ShowText(0,6,(u8*)oled_str,0);
		
		
		
	  //模式状态
    sprintf(oled_str,"%s",MODE?"手动":"自动");
    OLED_ShowText(95,6,(u8*)oled_str,0);
    
    
   
}

//控制界面
void Page_control(void)
{
    static u8 Index_flag=1;
    static u8 is_curtain_page=0; // 0为第一页,1为窗帘页

    // 显示界面内容
    if(is_curtain_page == 0) // 第一页:LED、制冷、制热、门锁
    {
        sprintf(oled_str,"LED:%s",LED?"ON ":"OFF");
        OLED_ShowText(16,0,(u8 *)oled_str,0);
        
        sprintf(oled_str,"制冷:%s",COLD?"ON ":"OFF");
        OLED_ShowText(16,2,(u8 *)oled_str,0);
    
        sprintf(oled_str,"制热:%s",HOT?"ON ":"OFF");
        OLED_ShowText(16,4,(u8 *)oled_str,0);
        
        sprintf(oled_str,"门锁:%s",DOOR?"ON ":"OFF");
        OLED_ShowText(16,6,(u8 *)oled_str,0);
        
        // 处理按键2选择逻辑
        if(key_num==2)
        {
            Index_flag++;
            if(Index_flag > 4) // 当选择超过门锁时,进入窗帘页面
            {
                is_curtain_page = 1;
                Index_flag = 1; // 重置为窗帘选择
								OLED_Clear(0);
            }
        }               
        
        // 箭头显示和控制逻辑
        switch(Index_flag)
        {   
            case 1:      
                OLED_ShowString(0,0,(u8 *)">",16) ; 
                OLED_ShowString(0,2,(u8 *)" ",16) ;
                OLED_ShowString(0,4,(u8 *)" ",16) ; 
                OLED_ShowString(0,6,(u8 *)" ",16) ;             
                break;
            case 2:      
                OLED_ShowString(0,0,(u8 *)" ",16) ; 
                OLED_ShowString(0,2,(u8 *)">",16) ;
                OLED_ShowString(0,4,(u8 *)" ",16) ; 
                OLED_ShowString(0,6,(u8 *)" ",16) ;             
                break; 
            case 3:      
                OLED_ShowString(0,0,(u8 *)" ",16) ; 
                OLED_ShowString(0,2,(u8 *)" ",16) ;
                OLED_ShowString(0,4,(u8 *)">",16) ; 
                OLED_ShowString(0,6,(u8 *)" ",16) ;             
                break;
            case 4:      
                OLED_ShowString(0,0,(u8 *)" ",16) ; 
                OLED_ShowString(0,2,(u8 *)" ",16) ;
                OLED_ShowString(0,4,(u8 *)" ",16) ; 
                OLED_ShowString(0,6,(u8 *)">",16) ;             
                break;  
        }    
        
        if(MODE==manual_mode)//手动模式下
        {
            if(Index_flag==1&&key_num==3) LED=ON;
            if(Index_flag==1&&key_num==4) LED=OFF;
            
            if(Index_flag==2&&key_num==3) COLD=ON;
            if(Index_flag==2&&key_num==4) COLD=OFF;
                
            if(Index_flag==3&&key_num==3) HOT=ON;
            if(Index_flag==3&&key_num==4) HOT=OFF;
            
            // 门锁控制
            if(Index_flag==4&&key_num==3) if(!DOOR) {Servo_SetAngle(90); DOOR=ON;}
            if(Index_flag==4&&key_num==4) if(DOOR){Servo_SetAngle(0); DOOR=OFF;}
        }
    }
		
    else // 窗帘控制页面
    {
        sprintf(oled_str,"窗帘:%s",StateCurtain ? "ON ":"OFF");
        OLED_ShowText(16,0,(u8 *)oled_str,0);
        
        // 处理按键2返回第一页
        if(key_num==2)
        {
            is_curtain_page = 0;
            Index_flag = 1; // 返回LED选择
						OLED_Clear(0);
        }
        
        // 箭头显示
        OLED_ShowString(0,0,(u8 *)">",16) ; 
        OLED_ShowString(0,2,(u8 *)" ",16) ;
        OLED_ShowString(0,4,(u8 *)" ",16) ; 
        OLED_ShowString(0,6,(u8 *)" ",16) ;
        
        if(MODE==manual_mode)//手动模式下
        {
            // 窗帘控制
            if(key_num==3 && StateCurtain==0) // 开启窗帘
            {
                Motor_Ctrl_Angle_Z(90, MOTOR_SPEED);
                StateCurtain = 1;
                BI_BI(); // 提示音
            }
            if(key_num==4 && StateCurtain==1) // 关闭窗帘
            {
                Motor_Ctrl_Angle_F(90, MOTOR_SPEED);
                StateCurtain = 0;
                BI_BI(); // 提示音
            }
        }
    }
}

// 设置界面
void Page_setting(void)
{
    static u8 Index_flag=1;
    // 显示设置参数
    sprintf(oled_str,"温度上限:%d  ",Out_data.temp_H);
    OLED_ShowText(16,0,(u8 *)oled_str,0);
    sprintf(oled_str,"温度下限:%d  ",Out_data.temp_L);
    OLED_ShowText(16,2,(u8 *)oled_str,0);
    sprintf(oled_str,"CO阈值:%d  ",Out_data.co_H);
    OLED_ShowText(16,4,(u8 *)oled_str,0);
    sprintf(oled_str,"空气质量:%d  ",Out_data.air_H);
    OLED_ShowText(16,6,(u8 *)oled_str,0);
               
    // 处理参数调节逻辑
    if(key_num==2)
    {
        Index_flag++;
        Index_flag=Index_flag%4; // 修改为4个选项
    }               
    
    // 箭头显示和参数调节逻辑
    switch(Index_flag)
    {
        case 1:      
            OLED_ShowString(0,0,(u8 *)">",16) ; 
            OLED_ShowString(0,2,(u8 *)" ",16) ;
            OLED_ShowString(0,4,(u8 *)" ",16) ; 
            OLED_ShowString(0,6,(u8 *)" ",16) ;             
            break;
        case 2:      
            OLED_ShowString(0,0,(u8 *)" ",16) ; 
            OLED_ShowString(0,2,(u8 *)">",16) ;
            OLED_ShowString(0,4,(u8 *)" ",16) ; 
            OLED_ShowString(0,6,(u8 *)" ",16) ;             
            break;
        case 3:      
            OLED_ShowString(0,0,(u8 *)" ",16) ; 
            OLED_ShowString(0,2,(u8 *)" ",16) ;
            OLED_ShowString(0,4,(u8 *)">",16) ; 
            OLED_ShowString(0,6,(u8 *)" ",16) ;             
            break;
        case 0:      
            OLED_ShowString(0,0,(u8 *)" ",16) ; 
            OLED_ShowString(0,2,(u8 *)" ",16) ;
            OLED_ShowString(0,4,(u8 *)" ",16) ; 
            OLED_ShowString(0,6,(u8 *)">",16) ;             
            break; 						 
    }    

    // 处理参数调节
		
    //温度上限
    if(Index_flag==1&&key_num==3)  
    {
        Out_data.temp_H < 100 ?  Out_data.temp_H++ : 100;//温度上限不能超过100
        STMFLASH_Write(FLASH_SAVE_ADDR, &Out_data.temp_H,1);
    }
    if(Index_flag==1&&key_num==4)  
    {
        Out_data.temp_H > 0 ?  Out_data.temp_H-- : 0; //温度下限不能低于0
        STMFLASH_Write(FLASH_SAVE_ADDR, &Out_data.temp_H,1);
    } 
		
    //温度下限
    if(Index_flag==2&&key_num==3)  
    {
        Out_data.temp_L < 100 ?  Out_data.temp_L++ : 100;//温度下限不能超过100
        STMFLASH_Write(FLASH_SAVE_ADDR+2, &Out_data.temp_L,1);
    } 
    if(Index_flag==2&&key_num==4)  
    {
        Out_data.temp_L > 0 ?  Out_data.temp_L-- : 0; //温度下限不能低于0
        STMFLASH_Write(FLASH_SAVE_ADDR+2, &Out_data.temp_L,1);
    }
    
    //CO阈值
    if(Index_flag==3&&key_num==3)  
    {
        Out_data.co_H < 200 ?  Out_data.co_H++ : 200;//CO阈值不能超过200ppm
        STMFLASH_Write(FLASH_SAVE_ADDR+4, &Out_data.co_H,1);
    }
    if(Index_flag==3&&key_num==4)  
    {
        Out_data.co_H > 0 ?  Out_data.co_H-- : 0; //CO阈值不能低于0
        STMFLASH_Write(FLASH_SAVE_ADDR+4, &Out_data.co_H,1);
    }
    
    //空气质量阈值
    if(Index_flag==0&&key_num==3)  
    {
        Out_data.air_H < 100 ?  Out_data.air_H++ : 100;//空气质量阈值不能超过100ppm
        STMFLASH_Write(FLASH_SAVE_ADDR+6, &Out_data.air_H,1);
    }
    if(Index_flag==0&&key_num==4)  
    {
        Out_data.air_H > 0 ?  Out_data.air_H-- : 0; //空气质量阈值不能低于0
        STMFLASH_Write(FLASH_SAVE_ADDR+6, &Out_data.air_H,1);
    }
}


void BI_BI(void){
 BEEP=ON;
 delay_ms(150);
 BEEP=OFF;

}

六、资料内容

七、资料获取

B站一键三联关注私信博主即可获取

STM32项目分享:智能家居(机智云)系统 (资料分享见文末)基于STM32的智能家居(机智云)系统。采集温湿度:系统通过DHT11模块采集温湿度烟雾监测:通过MQ-2模块采集环境中烟雾浓度煤气监测:通过MQ-7一氧化碳模块采集环境中一氧化碳浓度空气质量监测:通过MQ-7空气质量传感器采集环境空气质量情况大气压强采集:通过BMP280采集环境气压大小窗帘控制:通过步进电机模拟窗帘开关LED灯控制:控制LED灯OLED显示:显示温湿度、烟雾浓度、一氧化碳浓度、空气质量、大气压强等信息。 阅读详情

相关推荐

毕业设计:基于STM32与机智云平台的远程控制智能家居系统

该项目实现一个智能家居系统,采用STM32为主控,并连接云平台-机智云作为远程控制的云服务器,同时用到手机APP作为控制终端,整个系统包括硬件端、云平台、手机APP,是一套完整的物联网智能家居系统。

myQQ_914404940的博客 2804

电子科学与技术毕设题目选题推荐

🥇 近期不少学弟学妹询问学长关于电子科学与技术专业相关的毕设选题,学长特意写下这篇文章以作回应!以下是学长亲手整理的物联网相关的毕业设计选题,都是经过学长精心审核的题目,适合作为毕设,难度不高,工作量达标,对毕设有任何疑问都可以问学长哦!相对容易工作量达标题目新颖,含创新点。

m0_71572576的博客 5124

STM32项目分享:智能家居语音系统

(资料分享见文末)基于STM32的智能家居语音系统温湿度采集:系统通过DHT11模块采集温湿度烟雾监测:通过MQ-2模块采集环境中烟雾浓度光照强度采集:通过BH1750传感器采集环境光照强度窗帘控制:通过步进电机转动模拟窗帘控制风扇控制:通过继电器和指示灯模拟风扇驱动照明控制:通过继电器和指示灯模拟照明驱动蜂鸣器报警:环境烟雾异常情况下蜂鸣器报警OLED显示:显示温湿度、光照强度和烟雾浓度APP功能:使用机智云APP,包括功能有控制照明灯和风扇开关、显示当前温湿度信息。

qq_44016222的博客 4147

单片机毕设分享100例(一)

【单片机毕业设计项目分享系列】🔥 这里是DD学长,单片机毕业设计及享100例系列的第一篇,目的是分享高质量的毕设作品给大家。🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的单片机项目缺少创新和亮点,往往达不到毕业答辩的要求,为此学长准备了相对容易且工作量达标,并包含创新点的项目分享给大家。🧿。

DD学长的博客 1万+

基于STM32设计的智能家居系统(采用ESP8266+OneNet云平台)

一、环境介绍 单片机采用:STM32F103C8T6 上网方式:采用ESP8266,也可以使用其他设备代替,只要支持TCP协议即可。比如:GSM模块、有线网卡等。 云平台: 采用中国移动OneNet. 也可以采用腾讯、阿里云、华为云、百度天工物接入、机智云等等。 前面文章有讲解。 协议: 采用MQTT协议 开发软件:keil5 完整项目源码下载:https://download.youkuaiyun.com/download/xiaolong1126626497/19766925 二、包含的硬件与实...

1万+

22个易上手的STM32项目(适合对STM32有一定了解的伙伴)

包含“基于STM32的二维码识别”、“基于STM32的电子相册”、“基于STM32的数控电源设计”、“基于STM32的数据采集、心率检测”、“基于STM32的路径记录”、“基于STM32的岗哨报警系统”、还有一个一等奖作品。

010、STM32项目分享:智能家居系统

本项目基于STM32F103C8T6单片机设计了一套智能家居系统,通过多种传感器实现环境监测与智能控制。系统包含DHT11温湿度传感器、MQ-2烟雾传感器、BH1750光照传感器等模块,可实时监测环境参数并通过OLED屏幕显示。具备自动照明、智能排烟、远程APP控制等功能,支持阈值设置和报警机制。硬件设计包含PCB原理图,软件采用模块化编程实现传感器数据采集、设备驱动和WiFi通信。项目成果包括完整的硬件设计文件、程序源码及演示视频,实现了家居环境的智能化监测与控制。

qq_40891583的博客 1124

7个STM32项目(内含大赛作品)

(大赛作品)STM32F072RB NUCLEO智能家居控制、STM32数字示波器源码+数字信号处理教程、配套实例、低功耗STM32F411开发板(原理图+PCB源文件+官方例程+驱动等)、基于stm32 nucleo_L476的智能灯(操作说明+源码)、基于STM32 NUCLEO板设计彩色LED照明灯(纯cubeMX开发)、基于STM32 的联合调试侦听设备解决方案(原理图、PCB源文件、调试工具、视频)、基于STM32 人群定位、调速智能风扇设计(程序、设计报告、视频演示)

102、STM32项目分享开源:低功耗智能家居系统

本项目基于STM32F103C8T6单片机设计了一款低功耗智能家居系统,包含DHT11温湿度、MQ-2烟雾、BH1750光照传感器等模块,通过OLED屏幕实时显示环境数据。系统可实现自动照明(光照低于阈值时开启LED)、智能排烟(烟雾超标启动风扇)、电器/窗帘按键控制、阈值设置及温湿度超标报警等功能,具有长时间未操作自动熄屏的低功耗特性。项目提供了完整的硬件设计(原理图、PCB)、程序源码及实验效果视频,所有资料可通过文末链接获取。

qq_40891583的博客 173

AI智能体升级实战:从规则匹配到Function Call,准确率提升86%的技术选型之路

AI智能体升级实战:从规则匹配到Function Call的技术演进 文章记录了AI邮件助手从传统规则匹配升级到Function Call的技术迭代过程。通过案例分析,揭示了规则匹配的三大核心问题:覆盖不全(用户表达千变万化)、组合困难(多条件容易漏掉)、维护噩梦(每个需求都要新增规则)。测试数据显示,规则匹配在复杂查询中的准确率仅51%,严重影响用户体验。 技术团队对比了三种升级方案:1) 继续优化规则匹配(天花板明显);2) 微调专用NLP模型(成本高);3) 采用Function Call(灵活高效)

yweng18的博客 1079

ROS激光雷达动态避障算法优化(C++实战)

本文深入探讨了ROS激光雷达动态避障算法的C++实战优化。针对动态环境的核心挑战,文章系统性地介绍了从激光数据预处理(降噪、瘦身)、动态障碍物检测与跟踪,到基于动态窗口法(DWA)的智能决策与调优的全流程。重点分享了如何将障碍物速度预测融入DWA打分函数,以实现更安全、流畅的避障,并提供了工程架构、性能优化及真机调试的实用建议。

weixin_29192141的博客 947

STM32要学到什么程度才算合格?

不过呢,我觉得要是能把外设原理搞懂,还会用,已经很不错。在开始前刚好我有一些资料,是我根据网友给的问题精心整理了一份「嵌入式的资料从专业入门到高级教程」,2. 学会用 STM32 来做一些小项目,比如说控制个小机器人啦,或者做个智能家居系统啥的。给个小建议,可以去参加一些 STM32 的比赛或者项目,这样可以更快地提高自己的水平。点个关注在评论区回复“888”之后私信回复“888”,全部无偿共享给大家!3. 掌握一些编程技巧,比如说优化代码啦,提高程序的运行效率啦。

linlaoshi2009的博客 1861

解密美团外卖API:mtgsig和waimai_sign参数生成原理与Python实现

本文深入解析了美团外卖API中核心风控参数mtgsig和waimai_sign的生成原理与实现方法。文章详细拆解了waimai_sign作为业务数据签名、mtgsig作为请求环境签名的不同角色与生成逻辑,并通过Python代码示例演示了如何通过逆向工程、Frida动态Hook等技术手段模拟签名生成过程,为开发者理解移动端API安全机制提供了实战参考。

weixin_29325515的博客 554

基于 STM32 的智能家居嵌入式系统开发实战

本文将从CAN通信的原理、通信流程、帧结构、关键代码实现等方面,深入剖析多个CAN设备如何实现互相通信,并通过一个简单示例,帮助你快速上手。设想有两个设备Device A与Device B,它们都接入同一条CAN总线,配置不同的ID进行通信。广播通信:发送帧中不包含目标地址,所有节点接收帧,再根据标识符(ID)过滤决定是否处理。4. 处理数据:B设备对接收到的数据进行逻辑处理,必要时回传数据。3. 接收帧:B设备接收到数据后,根据滤波规则判断是否接收。2. 发送帧:A设备发送带有特定ID和数据的CAN帧。

silenthdd的博客 1808

MT5交易软件系统源码

Manager配置的功能及权限:管理客户、开户,销户、入金、信用额度、修改定单、人工交易报表、设定点差、强制平仓、修改密码,设定持仓交割单或挂单小止盈止损点数;26、修改价格 27、更改K线图历史价格 28、同步历史数据;2、系统设置 3、交易管理 4、交易柜台 5、价格更改 6、多台服。务器联机 7、恢复交易历史 8、数据源调整 9、备份服务调整 10、交易市场设定 11、交易单更改 12、平台时间设定(全世界) 13、可添加商品;15、设置商品利息;独立主机(服务器、VPS、VM)

tutujunjun的博客 904

红外协议 IR NEC 协议深度解析-简单易懂协议详解

1. 协议特征 使用双向编码(又称曼彻斯特编码); 使用38K载波对编码后的波形进行调制; 位时间 1.12ms 或 2.25ms 2. 调制 定义脉冲560µS为脉冲基本宽度T; 根据脉冲时间长短来解码。推荐载波占空比为1/3至1/4: (1) Logic “1” 位宽为2.25ms,脉冲时间560us(T + 3T); (2) Logic “0” 位宽为1.12ms,脉冲时间560us(T + T)。 (3 ) 重复码: 位宽为11.25ms,脉冲时间9ms(16T + 4T)。 3. 协议

代码打工人的博客 1万+

毕业设计| STM32单片机控制的智能家居系统设计

灯由LED发光二极管来实现,窗帘由直流电机模拟实现,风扇由5V小风扇实现,门由sg90舵机模拟实现,插座由继电器模拟实现,安防系统由人体光学传感器模块实现,烟雾报警由MQ-135和无源蜂鸣器来实现。3)系统稳定性问题:运用的协议过多,单片机运算速率有限以上就是这个毕设的相关内容了,总体来看实现的难度不是非常大,把项目按照功能一步步分解来做,就会简单很多。✔ 照明控制,温度和湿度控制,空气质量测量,家用电器定时和自动窗帘等功能的控制。除此之外,由于器件功率因素的影响,还需增加一个5V2A的开关电源进行供电。

Sen_091的博客 1244

【ARXML专题】-2-创建一个Classic CAN(经典CAN2.0)/CANFD的系统描述ARXML文件

目录 1 创建一个AUTOSAR系统描述 2 物理层命名以及创建ECU 3 新建一个Frame 4 新建一个PDU 5 新建一个signal 6 结尾 AUTOSAR System Description Network Explorer是一个文件编辑器,支持可视化和编辑系统描述的AUTOSAR系统描述文件和ECU摘录的通信内容,它支持架构版本4.0.3、4.1.2、4.2.1、4.2.2和4.3.0。AUTOSAR系统描述(ARXML)文件是基于XML的文件格式,描述网络通信的元素...

「汽车电子助手」的博客 1万+

【免费分享】70+ STM32项目源码

咱搞STM32开发的,都知道找好用代码有多难。为啥非得找呢?就是为了避免重复开发轮子,提高开发效率嘛。今天我就把STM32项目源码分享出来,这里面有些是我自己做项目写的,还有些是之前前辈分享给我的。这些代码可都是干货,希望能帮大家在开发的时候少走弯路,一起在STM32开发这条路上越走越顺,开发出更多厉害的东西。

mfSTM32的博客 8584

Transformer模型详解

​本文主要介绍Transformer系列,从基础到理论,对注意力机制进行总结并解释《Attention is all you need》,提出解决sequence to sequence问题的transformer模型,用全attention的结构代替了lstm,抛弃了之前传统的encoder-decoder模型必须结合cnn或者rnn的固有模式,只用attention。文章的主要目的是在减少计算量和提高并行效率的同时不损害最终的实验结果。

专注大数据与人工智能技术分享,欢迎私信加群互相学习! 5311

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

stm32毕业设计项目分享50例(一)

【单片机毕业设计项目分享系列】🔥 这里是DD学长,单片机毕业设计及享100例系列的第一篇,目的是分享高质量的毕设作品给大家,包含全面内容:源码+原理图+PCB+实物演示+论文。🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的单片机项目缺少创新和亮点,往往达不到毕业答辩的要求,为此学长准备了相对容易且工作量达标,并包含创新点的项目分享给大家。🧿。

m0_984093的博客 6205

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

基于STM32与机智云平台的远程控制智能家居系统

NUCLEO-L073RZ 是 ST 公司推出的一款针对 STM32L0 系列设计的 Cortex-M0 开发板,支持 mbed ,兼容 Arduino,同时还提供 ST Morpho 扩展排针,可连接微控制器的所有周边外 设。开发板基于 STM32L073RZT6 设计,开发板还集成了 ST-LINK/V2-1 仿真下载器(但仅 对外提供 SWD 接口),免除您另外采购仿真器或下载器的麻烦。

qq_51533426的博客 2204

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

基于STM32单片机的智能家居毕设

基于STM32单片机的智能家居系统设计,包含本地控制、远程控制(小程序)、语音识别、短信警报、触摸屏控制与显示等功能。

Y_E_J的博客 6万+

stm32毕业设计项目分享50例(三)

【单片机毕业设计项目分享系列】🔥 这里是DD学长,单片机毕业设计及享100例系列的第一篇,目的是分享高质量的毕设作品给大家,包含全面内容:源码+原理图+PCB+实物演示+论文。🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的单片机项目缺少创新和亮点,往往达不到毕业答辩的要求,为此学长准备了相对容易且工作量达标,并包含创新点的项目分享给大家。🧿。

m0_984093的博客 3033

基于STM32的物联网智能家居系统搭建之旅

通过以上代码的实现,我们完成了基于STM32的物联网智能家居系统的核心功能。从环境数据采集、阈值设置与设备控制,到数据的云端上传,每个环节都紧密相扣。当然,这只是一个基础版本,实际应用中还可以进一步优化和扩展,比如增加更多传感器、优化用户交互界面等。希望这篇博文能给对智能家居开发感兴趣的小伙伴们一些启发,大家一起动手打造更智能的家居环境吧!

2504_94281097的博客 868
下一篇: STM32项目分享:植物生长环境监测系统
大海学长的单片机设计
博客等级 码龄6年 74粉丝 3原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值