【STM32开源项目】智能语音台灯

目录

一、项目概述

二、实现功能

1、功能详解:

2、项目清单:

3、演示视频:

三、硬件介绍

PCB硬件设计:

四、程序设计

五、项目成品效果图

六、项目总结

七、包含资料



一、项目概述

本项目基于STM32F103C8T6单片机,设计并实现了一款集语音控制、环境监测与蓝牙互联于一体的智能语音台灯。系统通过光敏电阻传感器实时采集环境光照强度,利用超声波传感器检测坐姿距离,并配合光电红外传感器判断人体存在情况。采集到的数据通过OLED屏幕实时显示,包括光照值、坐姿距离、计时时间及有人/无人状态。系统支持按键调节光照与距离阈值,并可在自动与手动模式间切换。自动模式下,当检测到有人且光照低于阈值时自动开灯,并根据环境明暗程度智能调节亮度;当坐姿距离小于设定阈值时,有源蜂鸣器触发报警提醒。手动模式下,用户可通过按键自由调节灯光亮度并控制计时开关。此外,系统搭载SNR8016语音识别模块,支持语音切换模式、调节亮度及控制计时;通过BT04A蓝牙模块与手机APP互联,用户可在APP端查看环境信息、切换模式并下发控制指令,实现远程交互与智能化管理。

二、实现功能

1、功能详解:

主控:STM32F103C8T6系统板。

环境采集:光敏测光照,超声波测坐姿距离,光电红外检测有无人。

显示:OLED显示光照、坐姿距离、计时时间及有无人信息。

阈值调节:按键调节光照阈值与超声波距离阈值。

模式切换:按键切换自动/手动模式。

自动模式:有人且光照低于阈值时开灯,越暗越亮,反之越暗。

手动模式:按键调节灯光亮度,可开关计时功能。

坐姿检测:自动模式下距离小于阈值时蜂鸣器报警。

语音功能:语音控制模式切换、灯光亮度及计时开关。

手机APP:蓝牙连接APP,显示环境信息,切换模式并下发控制。

2、项目清单:

STM32F103C8T6单片机

OLED 屏幕

光敏电阻传感器

光电红外传感器

超声波传感器

SNR8016语音识别模块

大功率LED模块

有源蜂鸣器

BT04A蓝牙模块

3、演示视频:

哔哩哔哩视频链接点击观看:https://www.bilibili.com/video/BV1DRNe6wEvM/?share_source=copy_web&vd_source=f4437c8e4429101e5bf1054c39d5474f

三、硬件介绍

PCB硬件设计:

四、程序设计

复制代码
#include "delay.h"
#include "sys.h"
#include "usart.h"
#include "pwm.h"
#include "control.h"
#include "adc.h"
#include "key.h"
#include "timer.h"
#include "oled.h"
#include <stdio.h>
#include "hc-sr04.h"
#include "timer2.h"  
#include "IoData.h"

unsigned char setn=0;

uint8_t keu_num = 0;
uint8_t page_num = 1;
uint8_t option = 0;
uint8_t send = 0;



/****  数据变量  ****/
int close_flag = 0;
int time_delay = 10;		//延时关灯时长
int mask_delay = 0;


int led_time = 0;			//使用时长
int power = 0;				//档位
int	Timing_status = 0;				//计时开关
int	Beep_status=0;



int light_door = 3000;	//光照阈值
int distance_door = 30;//距离阈值
int time_door = 300;		//提醒时长

int auto_mode = 0;  //auto_mode = 0;表示为手动模式



void get_all_sensor_data();
void Sensor_Data_Handle();
void Key_event_handle(void);

void OLED_Show_OnePage(void);		//第一屏显示内容
void OLED_Show_TwoPage(void);		//第二屏显示内容
void OLED_Show_ThreePage(void);		//第三屏显示内容
void time_limit(void);
void Value_limit(void);
void SysDate_To_mask(void);
void mask_To_Updata(void);
void Blue_tooth_order_handle();


int main(void)
{
	SystemInit();//配置系统时钟为72M
	delay_init();
	uart3_init(9600);
	uart1_init(115200);
	uart2_init(115200);
	
	OLED_Init();

	KEY_Init();
	PWM_Init();
	PWM_SetCompare2(0);
	IoData_Init();
	Control_Init();

	Adc_Init();

	HC_SR04_Init();
	Timer2_Init(9,14398);

	while(1)
	{
		Key_event_handle();
		if(page_num == 1){
			OLED_Show_OnePage();
		}else if(page_num == 2){
			OLED_Show_TwoPage();
		}
		get_all_sensor_data();
		Sensor_Data_Handle();
		if(Time_Period[0]>=500){		//一秒钟
			if(Led_Level>0){
				if(Timing_status==1){
					led_time++;
				}

			}else led_time = 0;
					
			if(Timing_status==1){
				if(led_time>time_door){
					Beep=1;delay_ms(100);Beep=0;
				}
			}

			Time_Period[0] = 0;
		}
	}
}

void Key_event_handle(void)
{
	keu_num = KEY_Scan(0);
	switch(keu_num)
	{
		case 1: 
			if(page_num == 1){
				option=0;page_num = 2;
				OLED_Clear();OLED_Show_TwoPage();
			}else if(page_num==2){ 
				option=0;page_num = 1;
				OLED_Clear();OLED_Show_OnePage();
			}
			break;
		case 2:
			if(page_num==1){
				option++;
				if(option>2){
					option=0;
				}
			}else if(page_num==2){
				option++;
				if(option>3){
					option=0;
				}
			}
			break;
		case 3:
			if(page_num==1&&option==0){
				auto_mode =1;
                Led_Level=0;
                PWM_SetCompare2(2*Led_Level);
			}else if(page_num==1&&option==1){
				if(Led_Level<100)Led_Level+=10;
				PWM_SetCompare2(2*Led_Level);
			}else if(page_num==1&&option==2){
				Timing_status=1;
			}else if(page_num==2&& option == 1){
				light_door+=10;
			}else if(page_num==2&& option == 2){
				distance_door+=1;
			}else if(page_num==2&& option == 3){
				time_door+=60;
			}

			break;
		case 4:
			if(page_num==1&&option==0){
				auto_mode =0;
                Led_Level=0;
                PWM_SetCompare2(2*Led_Level);
			}
			if(page_num==1&&option==1){

				if(Led_Level>0)Led_Level-=10;
				PWM_SetCompare2(2*Led_Level);
			}else if(page_num==1&&option==2){

				Timing_status=0;
			}
			else if(page_num==2&& option == 1){
				light_door-=10;
			}
			else if(page_num==2&& option == 2){
				distance_door-=1;
			}
			else if(page_num==2&& option == 3){
				time_door-=60;
			}
			
			
			

			break;
	}
}

void get_all_sensor_data()
{
	Get_Light_Value(&Light_Value);//获取光照数据
	HC_SR04_Deboanle(&distance);
	Get_Body_Value(&body_status);
}

void Sensor_Data_Handle()
{
	if(auto_mode == 1)  //如果开启了自动模式则可以实现根据数据的自动控制
	{
		if(body_status==1){
			if(Light_Value<light_door){
				Led_Level=100-Light_Value*100/4095;
				mask_delay = 0;
			}else{
				Led_Level=0;
			}
			if(distance<distance_door)Beep = 1;
			else Beep = 0;
		}else{
			Beep = 0;
			Led_Level=0;
		}
		
		PWM_SetCompare2(2*Led_Level);

	}else if(auto_mode == 0){
		if(body_status==1){
			if(distance<distance_door && Led_Level>0)Beep = 1;
			else Beep = 0;
		}else{
			Beep = 0;
		}
	}
	


	
}

/*
 白(0) 黄(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)
*/

void OLED_Show_OnePage(void)
{
	uint8_t a,b,c,d;
	if(option==1){a=0;b=1;c=1;d=1;}
	else if(option==2){a=1;b=0;c=1;d=1;}
	else if(option==3){a=1;b=1;c=0;d=1;}
	else if(option==4){a=1;b=1;c=1;d=0;}
	else{a=1;b=1;c=1;d=1;}

	if(auto_mode == 1){
		OLED_ShowChinese(16*6,16*0,19,16,1);//智能
		OLED_ShowChinese(16*7,16*0,21,16,1);
	}else if(auto_mode == 0){
		OLED_ShowChinese(16*6,16*0,20,16,1);//手动
		OLED_ShowChinese(16*7,16*0,21,16,1);
	}
	


	OLED_ShowChinese(16*0,0,9,16,1);//光照
	OLED_ShowChinese(16*1,0,10,16,1);
	OLED_ShowChar(16*2,0,':',16,1);
	OLED_ShowNum(16*2+8,0,Light_Value,4,16,1);
	
	OLED_ShowChinese(16*0,16,7,16,1);//人体
	OLED_ShowChinese(16*1,16,8,16,1);
	OLED_ShowChar(16*2,16,':',16,1);
	if(body_status == 1){
		OLED_ShowChinese(16*2+8,16,15,16,1);	//有
	}else if(body_status == 0){
		OLED_ShowChinese(16*2+8,16,16,16,1);	//无
	}
	
	OLED_ShowChinese(16*4,16,26,16,1);	//距离
	OLED_ShowChinese(16*5,16,27,16,1);
	OLED_ShowChar(16*6,16,':',16,1);
	OLED_ShowNum(16*6+8,16,distance,3,16,1);
	
	OLED_ShowChinese(16*0,16*2,33,16,1);	//亮
	OLED_ShowChinese(16*1,16*2,12,16,1);	//度
	OLED_ShowChar(16*2,16*2,':',16,1);
	OLED_ShowNum(16*2+8,16*2,Led_Level,3,16,a);
	
	OLED_ShowChinese(16*4+8,16*2,5,16,1);	//亮
	OLED_ShowChinese(16*5+8,16*2,6,16,1);	//度
	OLED_ShowChar(16*6+8,16*2,':',16,1);
	if(Timing_status==1){
		OLED_ShowChinese(16*7,16*2,17,16,b);
	}else {
		OLED_ShowChinese(16*7,16*2,18,16,b);
	}
	
	OLED_ShowChinese(16*0,16*3,29,16,1);		//使
	OLED_ShowChinese(16*1,16*3,30,16,1);		//用
	OLED_ShowChinese(16*2,16*3,31,16,1);		//时
	OLED_ShowChinese(16*3,16*3,32,16,1);		//长
	OLED_ShowChar(16*4,16*3,':',16,1);
	OLED_ShowNum(16*4+8,16*3,led_time/60,3,16,1);
	OLED_ShowChar(16*6,16*3,':',16,1);
	OLED_ShowNum(16*6+8,16*3,led_time%60,2,16,1);
	

	
	

	OLED_Refresh();
}

void OLED_Show_TwoPage(void)
{
	uint8_t a,b,c,d;
	if(option==1){a=0;b=1;c=1;d=1;}
	else if(option==2){a=1;b=0;c=1;d=1;}
	else if(option==3){a=1;b=1;c=0;d=1;}
	else if(option==4){a=1;b=1;c=1;d=0;}
	else{a=1;b=1;c=1;d=1;}
	
	OLED_ShowChinese(16*0,0,9,16,1);	//光
	OLED_ShowChinese(16*1,0,10,16,1);	//照
	OLED_ShowChinese(16*2,0,24,16,1);	//阈
	OLED_ShowChinese(16*3,0,25,16,1);	//值
	OLED_ShowChar(16*4,0,':',16,1);
	OLED_ShowNum(16*4+8,0,light_door,4,16,a);
	
	OLED_ShowChinese(16*0,16,26,16,1);	//距
	OLED_ShowChinese(16*1,16,27,16,1);	//离
	OLED_ShowChinese(16*2,16,24,16,1);	//阈
	OLED_ShowChinese(16*3,16,25,16,1);	//值
	OLED_ShowChar(16*4,16,':',16,1);
	OLED_ShowNum(16*4+8,16,distance_door,3,16,b);
	
	OLED_ShowChinese(16*0,32,37,16,1);	//提
	OLED_ShowChinese(16*1,32,38,16,1);	//醒
	OLED_ShowChinese(16*2,32,31,16,1);	//时
	OLED_ShowChinese(16*3,32,32,16,1);	//长
	OLED_ShowChar(16*4,32,':',16,1);
	OLED_ShowNum(16*4+8,32,time_door/60,3,16,c);	

	

	OLED_Refresh();
}

void light_door_limit(void)
{
   if(Led_Level > 100)Led_Level = 100;
   else if(Led_Level<0)Led_Level = 0;
}

void Value_limit(void)
{
   if(Led_Level >= 100)Led_Level = 100;
   else if(Led_Level<=0)Led_Level = 0;
}

五、项目成品效果图

六、项目总结

本项目成功整合了STM32主控、多传感器融合、语音识别与蓝牙通信技术,构建了一套功能完善、交互方式多样的智能台灯系统。硬件方面,各模块(OLED、光敏电阻、光电红外、超声波、SNR8016、LED、蜂鸣器、BT04A)协同工作稳定,实现了环境感知、坐姿监测、语音控制与APP远程交互的完整闭环。软件方面,自动与手动双模式设计兼顾了智能化与个性化需求,阈值可调与蜂鸣器报警提升了实用性与护眼效果。项目验证了STM32在智能家居终端设备中的可行性,也为后续功能扩展(如WiFi联网、数据云端存储)提供了良好基础。整体而言,该系统达到了预期设计目标,具有较高的实用价值和推广意义。

七、包含资料

本资料免费分享,获取全套资料请看主页,并将告诉助手需要资料的项目编号,助手收到消息后,会发送资料给你。

资料获取:查看主页介绍"充哥单片机设计"

文章若对你有所帮助,期待点赞收藏,后续会持续分享各类单片机实战案例。
内容仅作为学习参考,有任何不妥之处,欢迎大家一起探讨!

相关推荐
EatFan1 小时前
全栈自造 Status Deck(四):硬件终于到了,从点亮屏幕到跑通第一个 Demo
单片机·物联网·esp32
sunoo-2292 小时前
【嵌入式裸机开发Day04】i.MX6ULL 蜂鸣器驱动详解:从引脚地址查找到代码实现全流程
arm开发·单片机·嵌入式硬件·学习·串口·裸机
Brilliantwxx3 小时前
【STM32】 SPI阻塞式通信与HAL源码 (源码分析)
stm32·单片机·嵌入式硬件
Doraemomo3 小时前
IMX6ULL裸机开发——PWM
arm开发·嵌入式硬件·imx6ull
老当益壮梁奶奶4 小时前
ARM汇编学习笔记(五):从按键轮询到 GIC 中断控制器(ARM Cortex-A7 )
arm开发·笔记·单片机·嵌入式硬件
WWJA王文举4 小时前
Bootloader、App 和升级分区之间是什么关系?
stm32·freertos·嵌入式开发·在线升级
西城微科方案开发5 小时前
基于SIC8F0535芯片的红外额温枪开发方案
单片机·嵌入式硬件
LCG元5 小时前
STM32F103 NTC 热敏电阻测温实战:分压网络设计、Steinhart-Hart 标定与 ADC 采样优化实测
stm32·单片机·嵌入式硬件
M78佐菲5 小时前
ARM学习笔记(五)
linux·arm开发·笔记·嵌入式硬件·学习