STM32项目开源:智能插座控制系统(代码 + 原理图 + 仿真)

文章目录


一、前言

实物项目成品:

仿真项目成品:

n/direct/e9f8c5792cfa462e9b89acb77c465491.png)

哔哩哔哩开源视频链接(复制浏览器打开):

https://www.bilibili.com/video/BV1g2eu6YEeg/?vd_source=10da4d04d580bd6b34f7298120737c50

(资料分享见文末)

二、项目功能简介

【开源】STM32单片机智能插座控制系统(代码 + 原理图 + 仿真)

功能介绍:

  1. 使用 OLED 屏幕实时显示采集到的温度数据与插座实时功率;
  2. 通过 DS18B20 温度传感器采集环境温度;
  3. 采用 HLW8032 电能计量模块采集插座输出功率;
  4. 搭载语音识别模块,通过语音指令控制插座通断;
  5. 实时对比采集数据与设定阈值,当温度或功率超过阈值时,插座自动断电,同时蜂鸣器声光报警;
  6. 手机机智云 APP 可同步查看 OLED 上的温度、功率数据,并且远程控制插座的开启与断开。

三、PCB设计

四、原理图设计

五、程序设计

代码如下():

c 复制代码
#include "sys.h"
#include "adc.h"
#include "delay.h"
#include "OLED.h"
#include "ds18b20.h"
#include "esp8266.h"
#include "timer.h"
#include "dht11.h"
#include "PWM.h"
#include "gpio.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>


unsigned int  light=0;
unsigned char temperature=0;
unsigned char  Humi;

unsigned char setTempValue=35;       
unsigned int  setHumiValue=70;	
unsigned int setLightValue=900;       
unsigned int LightValue=0;       

bool usart_send_flag = 0;
bool mode = 0;               
bool shuaxin  = 0;
bool shanshuo = 0;
bool sendFlag = 1;

u8 buff[30];//参数显示缓存数组
u8 count;
uint8_t Ren;		// 人
unsigned char setn=0;
void Red_Init(void)		
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);	
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
}

uint8_t Red_Rdata(void)//获取有人无人的数据
{
	return GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_4);
}
void displayLight(void)
{
		u16 test_adc=0;
		static u16 last_light[5] = {0}; // 保存最近5次的光照值,用于滑动平均滤波
		static u8 filter_index = 0;     // 当前滤波数组索引
		u16 sum = 0;                    // 用于计算平均值的总和
	  
	  // 增加采样次数,从20次增加到30次
	  test_adc = Get_Adc_Average(ADC_Channel_0,30);
		
		// 计算当前光照值
		u16 current_light = test_adc*1000/4096;
		//current_light = 99 - current_light;
		
		// 更新滑动窗口数组
		last_light[filter_index] = current_light;
		filter_index = (filter_index + 1) % 5; // 循环更新索引
		
		// 计算滑动平均值
		for(u8 i = 0; i < 5; i++) {
			sum += last_light[i];
		}
		
		// 如果是初始状态(前几次采样),使用当前值
		if(last_light[4] == 0) {
			light = current_light;
		} else {
			// 使用滑动平均值,但对新值赋予更高权重
			// 新值占20%,历史平均值占80%
			light = (current_light * 2 + (sum / 5) * 8) / 10;
		}
		
		// 确保值在合理范围内
		light = light >= 1000? 1000: (light <= 0? 0: light);
		
	  if(light<=setLightValue && shanshuo)
		{
			//   OLED_ShowString(16*6,32,"   ",16);
		}
		else
		{
			//OLED_ShowNum(3, 13, light, 4);
			sprintf((char*)buff,"%2d Luz",light);
			OLED_ShowString(3,7,(char*)buff);	//显示光照
		}
}
void displayTemp_Humierature(void)
{
		DHT11_Read_Data(&Humi,&temperature);

	  if(temperature>=setTempValue && shanshuo)
		{
			 //OLED_ShowString(16*6,16,"  ",16);
		}
		else
		{
			 if(temperature!=0)
			 {
				 sprintf((char*)buff,"%2d C",temperature);
				OLED_ShowString(1,7,(char*)buff);	
					
			 }
		}
		if(Humi<=setHumiValue && shanshuo)
		{
			// OLED_ShowString(16*6,0,"   ",16);
		}
		else
		{
			sprintf((char*)buff,"%2d %%",Humi);
			OLED_ShowString(2,7,(char*)buff);	//显示温度
			
		}
}

void displaySetValue(void)
{
		if(setn == 1)
		 {
			 
			 if(shanshuo)
			 {
				OLED_ShowString(2,11,"  ");
			 }
			 else
			 {
				 sprintf((char*)buff,"%2dC",setTempValue);
				 
				OLED_ShowString(2,11,(char*)buff);	
				sprintf((char*)buff,"%2d%%",setHumiValue);
				OLED_ShowString(3,11,(char*)buff);	
				sprintf((char*)buff,"%2dLux",setLightValue);
				OLED_ShowString(4,11,(char*)buff);	
				 
				
			 }
			
		 }
		 if(setn == 2)
		 {
				if(shanshuo)
			 {
				OLED_ShowString(3,11,"  ");
			 }
			 else
			 {
				 sprintf((char*)buff,"%2dC",setTempValue);
				 
				OLED_ShowString(2,11,(char*)buff);	
				  sprintf((char*)buff,"%2d%%",setHumiValue);
				OLED_ShowString(3,11,(char*)buff);	
				 sprintf((char*)buff,"%2dLux",setLightValue);
				OLED_ShowString(4,11,(char*)buff);	
				 
				  
			 }
		 }
		 if(setn == 3)
		 {
				if(shanshuo)
			 {
				OLED_ShowString(4,11,"  ");
			 }
			 else
			 {
				sprintf((char*)buff,"%2dC",setTempValue);
				 
				OLED_ShowString(2,11,(char*)buff);	
				sprintf((char*)buff,"%2d%%",setHumiValue);
				OLED_ShowString(3,11,(char*)buff);	
				sprintf((char*)buff,"%2dLux",setLightValue);
				OLED_ShowString(4,11,(char*)buff);	 
			 }
		 }
}

void keyscan(void)
{
	if(KEY1 == 0)
	{
	 	delay_ms(20);
		if(RELAY2==1)delay_ms(50);
		if(KEY1 == 0)
		{
		 	while(KEY1 == 0);
			if(setn == 0)
			 {
				  mode = !mode;
					 if(mode==0)
					  {
						  OLED_ShowChinese(4,4,19);
						  OLED_ShowChinese(4,5,20);
					  }
					  else 
					  {
						  RELAY1=0;  
						  RELAY2=0;  
						  RELAY3=0;  
						  OLED_ShowChinese(4,4,21);
						  OLED_ShowChinese(4,5,22);
					  }
			 }
		}
	}
	if(KEY2 == 0)
	{
	 	delay_ms(20);
		
		if(KEY2 == 0)
		{
			while(KEY2 == 0);
			 BEEP=0;
			if(mode==0)
			{
				setn ++;
				PWM_SetCompare2(0);  
				RELAY2=0; 
				
			}
			if(setn == 0 && mode==1)
			 {
					PWM_SetCompare2(0);  
			 }
			if(setn == 1)
			{
				OLED_Clear();
			}
			if(mode==1)
			{
				RELAY3=~RELAY3;;
			}
			
			 if(setn == 1||setn == 2||setn == 3)
			 {
				OLED_ShowChinese(1,3,16);
				OLED_ShowChinese(1,4,17);
				OLED_ShowChinese(1, 5, 23);
				OLED_ShowChinese(1, 6, 24);	
				 
				//显示"温度阈值:"
				OLED_ShowChinese(2, 1, 2);
				OLED_ShowChinese(2, 2, 3);
				OLED_ShowChinese(2, 3, 23);
				OLED_ShowChinese(2, 4, 24);	
				OLED_ShowChar(2, 9, ':');
				
				//显示"湿度阈值:"
				OLED_ShowChinese(3, 1, 6);
				OLED_ShowChinese(3, 2, 7);
				OLED_ShowChinese(3, 3, 23);
				OLED_ShowChinese(3, 4, 24);	
				OLED_ShowChar(3, 9, ':');

				//显示"光照阈值:"
				OLED_ShowChinese(4, 1, 10);
				OLED_ShowChinese(4, 2, 11);	
				OLED_ShowChinese(4, 3, 23);
				OLED_ShowChinese(4, 4, 24);	
				OLED_ShowChar(4, 9, ':');
			 }
			
			 displaySetValue();
			 if(setn >= 4)
			 {
					OLED_Clear();
					setn = 0;
					//显示"温度:"
					OLED_ShowChinese(1, 1, 2);
					OLED_ShowChinese(1, 2, 3);
					OLED_ShowChar(1, 5, ':');
					
					//显示"湿度:"
					OLED_ShowChinese(2, 1, 6);
					OLED_ShowChinese(2, 2, 7);	
					OLED_ShowChar(2, 5, ':');

					//显示"光照:"
					OLED_ShowChinese(3, 1, 8);
					OLED_ShowChinese(3, 2, 9);	
					OLED_ShowChar(3, 5, ':');
								 
					//显示"工作模式:"
					OLED_ShowChinese(4,1,14);
					OLED_ShowChinese(4,2,15);
					OLED_ShowChar(4, 5, ':');
		
				  if(mode==0)
					  {
						  OLED_ShowChinese(4,4,19);
						  OLED_ShowChinese(4,5,20);
					  }
					  else 
					  {
						  OLED_ShowChinese(4,4,21);
						  OLED_ShowChinese(4,5,22);
					  }
			 }
		}
	}
	if(KEY3 == 0)//加
	{
		delay_ms(20);//
		
		if(KEY3 == 0 )
		{
			while(KEY3 == 0);
			if(setn == 0 && mode==1)
			 {
					if(LightValue==0)
					{
						LightValue=setLightValue;
					}
					LightValue+=100;
					if(LightValue>=1000)
						LightValue=10;
					PWM_SetCompare2(LightValue);
			 }
			if(setn == 2)
			 {
					if(setHumiValue<99)setHumiValue++;
			 }
			 if(setn == 1)
			 {
					if(setTempValue<99)setTempValue++;
			 }
			 if(setn == 3)
			 {
				 if(setLightValue<999)setLightValue+=100;
			 }
			 displaySetValue();
		}
	}
	
	if(KEY4 == 0)//减
	{
		delay_ms(20);//
		if(RELAY2==1)delay_ms(50);
		if(KEY4 == 0 )
		{
			while(KEY4 == 0);
			if(setn == 0 && mode==1)
			 {
					RELAY2=~RELAY2;
			 }
      if(setn == 2)
			 {
					if(setHumiValue>0)setHumiValue--;
			 }
			 if(setn == 1)
			 {
					if(setTempValue>0)setTempValue--;
			 }
			 if(setn == 3)
			 {
				 if(setLightValue>0)setLightValue-=100;
			 }
			 displaySetValue();
		}
	}
}

int main(void)
{	
	delay_init();	   
	NVIC_Configuration();
	delay_ms(500);      
	Adc_Init();          //光照adc初始化
	KEY_GPIO_Init();     //按键初始化
	DHT11_Init();				//DHT11初始化
	Red_Init();         //人体检测
	PWM_Init();         //PWM初始化
	OLED_Init();				//OLED初始化
	OLED_Clear();		
	OLED_ShowString(2,1,"   Loading...   ");
	delay_ms(1000);
	OLED_Clear();
	
	//显示"温度:"
	OLED_ShowChinese(1, 1, 2);
	OLED_ShowChinese(1, 2, 3);
	OLED_ShowChar(1, 5, ':');
	
	//显示"湿度:"
	OLED_ShowChinese(2, 1, 6);
	OLED_ShowChinese(2, 2, 7);	
	OLED_ShowChar(2, 5, ':');

	//显示"光照:"
	OLED_ShowChinese(3, 1, 8);
	OLED_ShowChinese(3, 2, 9);	
	OLED_ShowChar(3, 5, ':');
				 
	//显示"工作模式:"
	OLED_ShowChinese(4,1,14);
	OLED_ShowChinese(4,2,15);
	OLED_ShowChar(4, 5, ':');
			
	TIM3_Init(99,719);  
		
		while(1)
		{  
			 keyscan();
			 if(setn == 0)
			 {
				   if(shuaxin == 1)
					 {
						   shuaxin = 0;
							 displayLight();   
							 displayTemp_Humierature(); 
							 Ren=Red_Rdata();
							 if(Ren==1)   
							 {
								  OLED_ShowChinese(1,7,25);
									OLED_ShowChinese(1,8,27);
							 }
							 else
							 {
									 
								  OLED_ShowChinese(1,7,26);
									OLED_ShowChinese(1,8,27);
							 }
							 if(mode==0)   
							 {
								 if(Ren==1)      //有人
								 {
										if(light<=setLightValue)
											PWM_SetCompare2(1000-light);
										else
											PWM_SetCompare2(0); 
								 }
								 else         //无人自动关灯
								 {
										PWM_SetCompare2(0); 
								 }             
								 if(temperature>=setTempValue||Humi>=setHumiValue)RELAY2=1;else RELAY2=0;                
								 if(temperature>=setTempValue||Humi>=setHumiValue)BEEP=1;else BEEP=0;  
								 OLED_ShowChinese(4,4,19);
								 OLED_ShowChinese(4,5,20);
							 }
							 else
							 {
									BEEP=0;
									OLED_ShowChinese(4,4,21);
									OLED_ShowChinese(4,5,22);
							 }
					 }
			 }
			  if(setn!=0)
				 {  
					displaySetValue();  
				 }
			 delay_ms(10);
		}	
}


void TIM3_IRQHandler(void)   
{
		static u16 timeCount1 = 0;
	
		if(TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)  
		{
				TIM_ClearITPendingBit(TIM3, TIM_IT_Update);  
        timeCount1++;
        if(timeCount1 >= 300)  //300ms
				{
						timeCount1 = 0;
					  shanshuo = !shanshuo;
					  shuaxin = 1;
				}
		}
} 

六、包含内容

七、资料分享

资料获取:请查看主页介绍搜索或观看开源视频获取

相关推荐
OpenTiny社区1 小时前
从开发到运行:OpenTiny NEXT 如何构建 Agent 时代的 Web 应用
前端·开源·ai编程·opentiny
芯岭技术郦1 小时前
MS32C001B32位MO+内核MCU
单片机·嵌入式硬件·个人开发
一直C1 小时前
ARM裸机开发Day03|IMX6ULL汇编点亮LED,寄存器、内存、中断梳理
嵌入式硬件·imx6ull裸机
Zw-awa1 小时前
自己编写 .c 和 .h:把小车代码分开放
stm32
深圳市青牛科技实业有限公司 小芋圆1 小时前
D2025——双通道音频功率放大电路,可替代TEA2025
嵌入式硬件·笔记本电脑开合检测·太阳能逆变器·电动车控制器供电·智能家居位置传感
万物智能信息科技2 小时前
硬件看门狗MAX6369设置—【万物智能之开源鸿蒙OpenHarmony系统实战开发系列教程】
人工智能·华为·开源·harmonyos·鸿蒙
田径他爸来了2 小时前
嵌入式学习第四十天(imx6ull裸机——ADC)
嵌入式硬件
ouynagda2 小时前
DS18B20单总线温度传感器原理与51单片机驱动
51单片机
xx~t12 小时前
嵌入式学习——ARM1
linux·arm开发·嵌入式硬件·arm