【STM32项目】教室智能灯控系统
本设计基于 STM32F103C8T6 单片机,实现教室智能灯控制。结合光控、红外、语音识别等模块,能根据光照、人员情况自动调光开关灯,还支持语音、定时、按键控制,可显示数据状态,通过 Wi-Fi 连云平台供管理。
·

🤞🤞大家好,这里是5132单片机毕设设计项目分享,今天给大家分享的是教室智能灯控系统。
设计的详细功能见网盘中的文章《16、基于STM32的教室智能灯控系统设计》:
链接:https://pan.baidu.com/s/1uWSZX2zbZwy9sYwwnvyktQ?pwd=5132
提取码:5132
目录
一、系统功能
本设计是基于STM32单片机的教室智能灯控制系统设计,主要内容如下:
- 主控芯片,主控芯片采用的STM32F103C8T6,通过此芯片实现室内信息的采集以及智能灯的控制。
- 光控模块。利用光控模块,可以根据日常需求自行设定室内光照度,通过光敏电阻实时监测室外光照度并结合红外模块,单片机接PWM调光电路控制灯的亮度实现室内光照强度的控制。
- 热释电人体红外模块,在教室内安装热释电红外传感器实时监测教室内是否有人并结合光控模块,来自动控制灯的开闭。
- 语音识别模块。通过“开灯”和“关灯”指令以及模式选择“投影模式”、“讲课模式”、“自习模式”等关键语句实现对智能灯的语音控制。
- 时钟模块。利用STM32内部的时钟模块实现灯的定时开光,当下午6点智能灯自动打开(有人情况下),到了晚上10点“温馨提示”注意休息后关闭。
- 按键模块。按键模块用来控制模式选择和控制智能灯的开启与关闭(手动控制)。
- 显示模块。该模块用来实时显示室内外光照度数据及智能灯工作状态以及当前模式
- 蜂鸣器模块。监测到教室没人(10min),智能灯还亮着时,蜂鸣器告警后关闭灯光。和播报晚点
- Wi-Fi模块,用于连接云平台进行数据储存以及移动端可以远程通过云平台接收传感器数据和下发指令,控制智能灯。便于管理员进行数据分析和管理。
二、演示视频和实物


基于STM32的智能教室灯光控制系统(五种控制模式)
三、系统设计框图

四、软件设计流程图
主要包含系统初始化、主循环处理和多个功能模块。整体流程如下:
- 系统初始化:对各种外设和模块进行初始化,包括 NVIC 中断分组、串口、延时函数、外设、PWM、RTC、人体传感器、机智云和串口 2 等。
- 主循环:不断执行数据上传和后台处理,同时根据不同的时间间隔进行传感器数据采集和处理。根据按键状态进入不同的模式,如远程模式、自动模式、手动模式、定时模式和语音模式。
- 功能模块:每个模式都有相应的处理函数,如手动模式下的窗户开关控制、自动模式下根据光照强度控制窗户、定时模式下的定时开关窗户等。

五、原理图



六、主程序
#include "sys.h"
#include "delay.h"
#include "MyRTC.h"
#include "PWM.h"
#include "renti.h"
#include "Serial2.h"
uint8_t KeyNum; //存储按键值
uint32_t bufe[10]; //存储传感器采集的数据
uint16_t AD0, AD1, AD2; //存储5路ADC值
uint32_t GuangYu1 = 10,GuangYu2 = 30,GuangYu3 = 50,GuangYu4 = 70; //光照强度阈值上限
u8 state, state2 , state2_1,state2_2, state3,state4; //按键状态标志
u8 t = 0; //传感器读取时间间隔
u8 flag; //远程控制标志
u8 flag2 = 0, flag1, flag3;
uint16_t RTC_Time[] = {0, 0, 0};
uint16_t RTC_Time1[] = {18, 0, 0}; //定时时间---开
uint16_t RTC_Time2[] = {22, 0, 0}; //定时时间---关
u8 T_state, T_state1, qingping = 1, state_dingshi_yu_guan, state_dingshi_yu_kai, state_dingshi_yu_switch, state3_1;
extern void TimeSet(void);
extern void TimeRead(void);
extern void DingShiMoShi(void);
extern void YuZhiSet(void);
extern void ChuangGan(void);
void MY_Gizwits_Init(void) //机智云初始化函数
{
TIM3_Int_Init(9, 7199); //1MS系统定时
usart3_init(9600);//WIFI初始化
memset((uint8_t *)¤tDataPoint, 0, sizeof(dataPoint_t)); //设备状态结构体初始化
gizwitsInit();//环形缓冲区初始化
gizwitsSetMode(2); //设置模式
userInit();
}
void shoudong() //state2,state2_1,state2_2
{
if (KeyNum == 2) //按键PB0控制窗户开关
{
delay_ms(20);
if (KeyNum == 2)
{
state2++;
if (state2 > 3)
{
state2 = 0;
}
}
}
switch (state2)
{
case 0:
PWM_SetCompare1(0);
OLED_ShowChinese(4, 4, 76);
break;
case 1:
PWM_SetCompare1(33);
OLED_ShowChinese(4, 4, 77);
break;
case 2:
PWM_SetCompare1(66);
OLED_ShowChinese(4, 4, 78);
break;
case 3:
PWM_SetCompare1(100);
OLED_ShowChinese(4, 4, 79);
break;
default:
break;
}
}
void zhidong()
{
switch (state4)
{
case 1:
PWM_SetCompare1(0);
OLED_ShowChinese(4, 4, 76);
break;
case 2:
PWM_SetCompare1(33);
OLED_ShowChinese(4, 4, 77);
break;
case 3:
PWM_SetCompare1(66);
OLED_ShowChinese(4, 4, 78);
break;
case 4:
PWM_SetCompare1(100);
OLED_ShowChinese(4, 4, 79);
break;
default:
break;
}
}
void YuYingMode() //先说小智唤醒,然后说打开窗户和关闭窗户
{
if (Serial2_RxFlag == 1) //串口接收到数据包的标志位,若是收到数据包,会置1
{
if (strcmp(Serial2_RxPacket, "LED_ON") == 0)
{
PWM_SetCompare1(100);
}
else if (strcmp(Serial2_RxPacket, "LED_OFF") == 0)
{
PWM_SetCompare1(0);
}
Serial2_RxFlag = 0; //将标志位清零,不清零就接收不到下一个数据包了
}
}
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
uart_init(9600); //串口初始化为9600
delay_init(); //延时函数初始化
Buzzer_Init(); //下面为外设初始化
OLED_Init();
Key_Init();
AD_Init();
PWM_Init(); //PWM初始化
MyRTC_Init();
RenTiSensor_Init();
MY_Gizwits_Init(); //机智云初始化
Serial2_Init(); //串口2初始化(语音识别模块)
while (1)
{
userHandle(); //数据上传
gizwitsHandle((dataPoint_t *)¤tDataPoint); //后台处理,必须放在while里
if (t % 10 == 0)
{
AD1 = AD_GetValue(ADC_Channel_1); //光敏传感器
if (AD1 > 4000)AD1 = 4000;
bufe[1] = (u8)(100-AD1 / 40);
if(bufe[1]<GuangYu1) state4=4;
else if(bufe[1]<GuangYu2) state4=3;
else if(bufe[1]<GuangYu3) state4=2;
else if(bufe[1]<GuangYu4) state4=1;
}
t++;
if (GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_4) == 1)
{
flag=1;
}
else
{
flag=0;
}
KeyNum = Key_GetNum();
if (KeyNum == 1)
{
qingping = 0;
delay_ms(20);
if (KeyNum == 1)
{
state++;
if (state > 4)
{
state = 0;
}
}
}
if (state == 0) //远程模式
{
if (qingping == 0)
{
OLED_Clear();
qingping = 1;
}
TimeRead();
ChuangGan();
OLED_ShowChinese(1, 7, 49);
OLED_ShowChinese(1, 8, 50);
}
if (state == 1) //自动模式
{
if (qingping == 0)
{
OLED_Clear();
qingping = 1;
}
OLED_ShowChinese(1, 7, 51);
OLED_ShowChinese(1, 8, 52);
TimeRead();
zhidong();
ChuangGan();
}
if (state == 2) //手动模式
{
if (qingping == 0)
{
OLED_Clear();
qingping = 1;
}
OLED_ShowChinese(1, 7, 18);
OLED_ShowChinese(1, 8, 52);
TimeRead();
ChuangGan();
shoudong();
}
if (state == 3) //定时模式
{
if (qingping == 0)
{
OLED_Clear();
qingping = 1;
}
OLED_ShowChinese(1, 7, 84);
OLED_ShowChinese(1, 8, 85);
TimeRead();
DingShiMoShi();
}
if (state == 4) //语言模式
{
if (qingping == 0)
{
OLED_Clear();
qingping = 1;
}
OLED_ShowChinese(1, 7, 57);
OLED_ShowChinese(1, 8, 58);
TimeRead();
ChuangGan();
YuYingMode();
}
}
}
void TimeSet() //设置时间
{
if (KeyNum == 2) //PB10
{
delay_ms(20);
if (KeyNum == 2)
{
T_state++;
if (T_state > 2)
{
T_state = 0;
}
}
}
if (T_state == 0) //时间显示模式
{
MyRTC_ReadTime();
OLED_ShowNum(1, 5, MyRTC_Time[3], 2); //时
OLED_ShowString(1, 7, ":");
OLED_ShowNum(1, 8, MyRTC_Time[4], 2); //分
OLED_ShowString(1, 10, ":");
OLED_ShowNum(1, 11, MyRTC_Time[5], 2); //秒
RTC_Time[0] = MyRTC_Time[3];
RTC_Time[1] = MyRTC_Time[4];
RTC_Time[2] = MyRTC_Time[5];
}
if (T_state == 1) //修改时间
{
if (KeyNum == 5)
{
delay_ms(20);
if (KeyNum == 5)
{
T_state1++;
if (T_state1 > 2)
{
T_state1 = 0;
}
}
}
if (T_state1 == 0) //修改时
{
if (KeyNum == 4)RTC_Time[0]++;
if (KeyNum == 3)RTC_Time[0]--;
if (RTC_Time[0] > 23 & RTC_Time[0] < 100)RTC_Time[0] = 0;
if (RTC_Time[0] > 100)RTC_Time[0] = 23;
OLED_ShowNum(1, 5, RTC_Time[0], 2); //时
}
if (T_state1 == 1) //修改分
{
if (KeyNum == 4)RTC_Time[1]++;
if (KeyNum == 3)RTC_Time[1]--;
if (RTC_Time[1] > 59 & RTC_Time[1] < 100)RTC_Time[1] = 0;
if (RTC_Time[1] > 100)RTC_Time[1] = 59;
OLED_ShowNum(1, 8, RTC_Time[1], 2); //时
}
if (T_state1 == 2) //修改秒
{
if (KeyNum == 4)RTC_Time[2]++;
if (KeyNum == 3)RTC_Time[2]--;
if (RTC_Time[2] > 59)RTC_Time[2] = 0;
if (RTC_Time[2] > 59 & RTC_Time[2] < 100)RTC_Time[2] = 0;
if (RTC_Time[2] > 100)RTC_Time[2] = 59;
OLED_ShowNum(1, 11, RTC_Time[2], 2); //时
}
}
if (T_state == 2)
{
MyRTC_Time[3] = RTC_Time[0];
MyRTC_Time[4] = RTC_Time[1];
MyRTC_Time[5] = RTC_Time[2];
MyRTC_SetTime();
T_state = 0;
}
}
void TimeRead()
{
MyRTC_ReadTime();
OLED_ShowNum(1, 5, MyRTC_Time[3], 2); //时
OLED_ShowString(1, 7, ":");
OLED_ShowNum(1, 8, MyRTC_Time[4], 2); //分
OLED_ShowString(1, 10, ":");
OLED_ShowNum(1, 11, MyRTC_Time[5], 2); //秒
}
void DingShiMoShi()
{
TimeRead();
OLED_ShowChinese(2, 1, 82);
OLED_ShowChinese(2, 2, 83);
OLED_ShowString(2, 5, ":");
if (flag==1)
{
OLED_ShowChinese(2, 4,80); //有人
OLED_ShowChinese(2, 5,82); //有人
//...............................定时模式..................................../
if ((MyRTC_Time[3] == RTC_Time1[0]) && (MyRTC_Time[4] == RTC_Time1[1]) && (MyRTC_Time[5] == RTC_Time1[2]))
{
PWM_SetCompare1(100);//外设操作
}
if ((MyRTC_Time[3] == RTC_Time2[0]) && (MyRTC_Time[4] == RTC_Time2[1]) && (MyRTC_Time[5] == RTC_Time2[2]))
{
PWM_SetCompare1(0);//外设操作
}
}
else
{
OLED_ShowChinese(2, 4, 81);//无人
OLED_ShowChinese(2, 5, 82);
}
//...............................修改定时时间..................................../
OLED_ShowChinese(3, 1, 31);
OLED_ShowString(3, 3, ":");
OLED_ShowNum(3, 5, RTC_Time1[0], 2);
OLED_ShowString(3, 7, ":");
OLED_ShowNum(3, 8, RTC_Time1[1], 2);
OLED_ShowString(3, 10, ":");
OLED_ShowNum(3, 11, RTC_Time1[2], 2);
OLED_ShowChinese(4, 1, 32);
OLED_ShowString(4, 3, ":");
OLED_ShowNum(4, 5, RTC_Time2[0], 2);
OLED_ShowString(4, 7, ":");
OLED_ShowNum(4, 8, RTC_Time2[1], 2);
OLED_ShowString(4, 10, ":");
OLED_ShowNum(4, 11, RTC_Time2[2], 2);
if (KeyNum == 2)
{
delay_ms(20);
if (KeyNum == 2)
{
state_dingshi_yu_kai++;
if (state_dingshi_yu_kai > 5)
{
state_dingshi_yu_kai = 0;
}
}
}
if (state_dingshi_yu_kai == 0) //时
{
if (KeyNum == 3) RTC_Time1[0]++;
if (KeyNum == 4) RTC_Time1[0]--;
}
if (state_dingshi_yu_kai == 1)//分
{
if (KeyNum == 3) RTC_Time1[1]++;
if (KeyNum == 4) RTC_Time1[1]--;
}
if (state_dingshi_yu_kai == 2)//秒
{
if (KeyNum == 3) RTC_Time1[2]++;
if (KeyNum == 4) RTC_Time1[2]--;
}
if (state_dingshi_yu_kai == 3) //时
{
if (KeyNum == 3) RTC_Time2[0]++;
if (KeyNum == 4) RTC_Time2[0]--;
}
if (state_dingshi_yu_kai == 4)//分
{
if (KeyNum == 3) RTC_Time2[1]++;
if (KeyNum == 4) RTC_Time2[1]--;
}
if (state_dingshi_yu_kai == 5)//秒
{
if (KeyNum == 3) RTC_Time2[2]++;
if (KeyNum == 4) RTC_Time2[2]--;
}
}
void ChuangGan()
{
if (qingping == 0)
{
OLED_Clear();
qingping = 1;
}
OLED_ShowChinese(2, 1, 53);
OLED_ShowChinese(2, 2, 54);
OLED_ShowString(2, 5, ":");
OLED_ShowNum(2, 6, bufe[1], 2);
OLED_ShowString(2, 8, "%");
OLED_ShowChinese(4, 1, 74);
OLED_ShowChinese(4, 2, 75);
OLED_ShowString(4, 5, ":");
OLED_ShowChinese(4, 5, 74);
OLED_ShowChinese(3, 1, 82);
OLED_ShowChinese(3, 2, 83);
OLED_ShowString(3, 5, ":");
if (flag==1)
{
OLED_ShowChinese(3, 4,80); //有人
OLED_ShowChinese(3, 5,82); //有人
}
else
{
OLED_ShowChinese(3, 4, 81);//无人
OLED_ShowChinese(3, 5, 82);
}
}
七、总结
本设计基于 STM32F103C8T6 单片机,实现教室智能灯控制。结合光控、红外、语音识别等模块,能根据光照、人员情况自动调光开关灯,还支持语音、定时、按键控制,可显示数据状态,通过 Wi-Fi 连云平台供管理。
八、资料内容

更多推荐



所有评论(0)