【STM32开源项目】智能晾衣架
目录
一、项目概述
本项目使用STM32F103C8T6单片机开发,整体设计简洁明了,没有复杂的操作系统和多线程逻辑。主要实现基础的数据采集、数据显示和智能控制功能,上手零压力。
系统搭载了DHT11温湿度传感器采集环境温湿度,光敏传感器检测光照强度,雨滴传感器感应是否下雨,光电红外传感器检测人体靠近。所有数据实时显示在0.96寸OLED屏幕上。当检测到下雨时,系统自动控制步进电机将晾衣架收回;天黑时自动开启LED照明灯;夜晚有人靠近时触发蜂鸣器防盗报警。用户可通过按键手动切换模式、修改参数或直接控制晾衣架伸缩。设备通过ESP8266接入机智云平台,手机App可远程查看环境数据并控制晾衣架展开或收回。
二、实现功能
-
1、功能详解:
-
STM32F103C8T6单片机:整个系统的主控芯片,负责读取传感器数据、处理逻辑、控制执行部件和通信。
-
OLED屏幕:用来显示当前时间和温湿度、光照等环境信息。
-
DHT11温湿度传感器:采集环境温度和湿度数据。
-
光敏传感器:检测光照强度
-
雨滴传感器:感应是否有雨水落在上面。
-
光电红外传感器:检测是否有人体靠近或经过。
-
ESP8266模块:连接WiFi,实现手机APP与设备之间的通信。
-
步进电机:带动晾衣架展开或收回。
-
有源蜂鸣器:防盗触发时发出报警声。
-
LED指示灯:显示灯光开关状态或系统运行状态。
-
按键开关:用于切换模式、进入设置、修改参数和手动控制
-
2、材料清单:
-
主控芯片:STM32F103C8T6
-
屏幕显示:OLED
-
环境检测:DHT11温湿度传感器、光敏传感器、雨滴传感器、光电红外传感器
-
网络通信:ESP8266 WIFI模块
-
驱动部件:步进电机
-
报警提示:有源蜂鸣器
-
状态指示:LED指示灯
-
3、演示视频:
-
哔哩哔哩视频链接:https://www.bilibili.com/video/BV1B17N6ZEiL/?share_source=copy_web&vd_source=f4437c8e4429101e5bf1054c39d5474f
三、PCB硬件设计
-
PCB硬件设计:
-


四、程序设计
#include "delay.h"
#include "sys.h"
#include "bmp.h"
#include "usart.h"
#include "control.h"
#include "key.h"
#include "timer.h"
#include "oled.h"
#include "dht11.h"
#include "uln2003.h"
#include "IoData.h"
#include "adc.h"
/**** 菜单变量 ****/
uint8_t keu_num = 0;
uint8_t page_num = 1;
uint8_t option = 0;
/**** 数据变量 ****/
int humi_door = 60; //湿度阈值
int light_door = 3000; //光照阈值
uint8_t led_status = 0; //照明开关状态
uint8_t open_flag = 0; //晾衣架开关标志位
uint8_t door_flag = 0; //晾衣架状态
uint8_t door_auto = 0; //晾衣架状态
uint8_t mode = 0; //模式
uint8_t safe = 0; //安防
extern uint16_t rays_time;
/**** 功能函数声明 ****/
void get_all_sensor_data(); //传感器数据采集
void Sensor_Data_Handle(); //不同模式下控制效果
void Key_event_handle(void); //按键功能函数
void All_Pin_Init(void); //系统初始化函数
void OLED_Show_FirstPage(); //第一屏显示内容
void OLED_Show_SecondPage(); //第二屏显示内容
void OLED_Show_ThirdPage(); //第三屏显示内容
void All_Pin_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);//改变指定管脚的映射,JTAG-DP 禁用 + SW-DP 使能
delay_init();
OLED_Init();
uart3_init(115200); //串口3初始化,波特率115200
// uart1_init(115200); //串口1初始化,波特率115200
uart2_init(9600); //串口2初始化,波特率9600
DHT11_Init(); //DHT11温湿度初始化
Uln2003_Init(); //步进电机初始化
Adc_Init(); //光照强度初始化
KEY_Init(); //按键初始化
TIME_Config(); //定时器初始化
IoData_Init(); //人体检测初始化
Control_Init(); //补光灯、蜂鸣器初始化
LED=1;
}
int main(void)
{
All_Pin_Init();
while(1)
{
if(Time_Period[1]>=1000)
{
Time_Period[1] = 0;
}
get_all_sensor_data(); //传感器数据采集
Key_event_handle(); //按键监测
if(page_num == 1){ //屏幕更新
OLED_Show_FirstPage();
}else if(page_num == 2){
OLED_Show_SecondPage();
}else if(page_num == 3){
OLED_Show_ThirdPage();
}
Sensor_Data_Handle(); //数据处理
}
}
void Key_event_handle(void)
{
keu_num = KEY_Scan(0); //按键扫描赋值
switch(keu_num)
{
case 1: //按键1按下
if(page_num==1){
option=0;page_num=2;
OLED_Clear();OLED_Show_SecondPage();
}else if(page_num==2){
option=0;page_num=3;
OLED_Clear();OLED_Show_ThirdPage();
}else if(page_num==3){
option=0;page_num=1;
OLED_Clear();OLED_Show_FirstPage();
}
break;
case 2: //按键2按下
if(page_num==1){
// if(option==1)rays_time++;
// else mode = !mode;
}else if(page_num==2){
option++;
if(option>2)option=0;
}else if(page_num==3){
option++;
if(option>2)option=0;
}
break;
case 3: //按键3按下
if(page_num==1){
mode = !mode;
}else if(page_num==2){
if(option==1){
humi_door++;
if(humi_door>100)humi_door=100;
}else if(option==2){
light_door+=25;
if(light_door>4000)light_door=4000;
}
}else if(page_num==3){
if(option==1){
LED=0;
led_status = 1;
}else if(option==2){
open_flag = 1;
door_flag = 1;
door_auto = 1;
}
}
break;
case 4: //按键1按下
if(page_num==1){
safe = !safe;
}else if(page_num==2){
if(option==1){
humi_door--;
if(humi_door<0)humi_door=0;
}else if(option==2){
light_door-=25;
if(light_door<0)light_door=0;
}
}else if(page_num==3){
if(option==1){
LED=1;
led_status = 0;
}else if(option==2){
open_flag = 1;
door_flag = 0;
door_auto = 0;
}
}
break;
}
}
void get_all_sensor_data()
{
DHT11_Read_Data(&DHT_temp,&DHT_hum); //获取温湿度数据
Get_HCSR_Value(&hcsr); //人体检测
Get_Light_Value(&Light_Value); //获取光照强度
Get_Rain_Value(&Rain_Value); //检测降雨
}
void Sensor_Data_Handle()
{
//手动模式控制衣柜开关
if(mode==0){
if(open_flag==1){
open_flag = 0;
if(door_flag==1){
Stepper_RotateByLoop(1,1,1);
}else{
Stepper_RotateByLoop(0,1,1);
}
}
}
//自动模式
if(mode==1){
if(hcsr==1 || Rain_Value==1 || DHT_hum>=humi_door || Light_Value<light_door){
if(door_flag==1){
door_flag=0;
Stepper_RotateByLoop(0,1,1);
}
}else{
if(door_auto==1 && door_flag==0){
door_flag=1;
Stepper_RotateByLoop(1,1,1);
}else{
if(open_flag==1){
open_flag = 0;
if(door_flag==1){
Stepper_RotateByLoop(1,1,1);
}else{
Stepper_RotateByLoop(0,1,1);
}
}
}
}
// /*
// 检测到温湿度超过阈值
// 自动打开风扇通风降温、除湿
// */
// if(DHT_hum>=humi_door||DHT_temp>temp_door){
// Wind = 1;wind_status = Wind;
// }else{
// Wind = 0;wind_status = Wind;
// }
//
// //湿度大于阈值打开加热片除湿
// if(DHT_hum>=humi_door){
// heat = 1;heat_status = heat;
// }else{
// heat = 0;heat_status = heat;
// }
}
if(safe==1){
if(door_flag==1 || door_auto==1){
if(hcsr==1)BEEP=1;
else BEEP=0;
}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)
*/
void OLED_Show_FirstPage()
{
OLED_ShowChinese(16*3+8,0,6,16,1); //模式
OLED_ShowChinese(16*4+8,0,7,16,1);
OLED_ShowChar(16*5+8,0,':',16,1);
if(mode==1){
OLED_ShowChinese(16*6,0,8,16,1); //自动
OLED_ShowChinese(16*7,0,10,16,1);
}else{
OLED_ShowChinese(16*6,0,9,16,1); //手动
OLED_ShowChinese(16*7,0,10,16,1);
}
OLED_ShowChinese(16*4+8,16,40,16,1); //防盗
OLED_ShowChinese(16*5+8,16,41,16,1);
OLED_ShowChar(16*6+8,16,':',16,1);
if(safe==1){
OLED_ShowChinese(16*7,16,17,16,1); //开
}else{
OLED_ShowChinese(16*7,16,18,16,1); //关
}
OLED_ShowString(16*0,0,"T:",16,1);
OLED_ShowNum(16*1,0,DHT_temp,2,16,1);
OLED_ShowChinese(16*2,0,5,16,1);
OLED_ShowString(16*0,16,"H:",16,1);
OLED_ShowNum(16*1,16,DHT_hum,2,16,1);
OLED_ShowString(16*2,16,"%RH",16,1);
OLED_ShowChinese(16*0,32,35,16,1); //天气
OLED_ShowChinese(16*1,32,36,16,1);
OLED_ShowChar(16*2,32,':',16,1);
if(Rain_Value==1){
OLED_ShowChinese(16*2+8,32,37,16,1); //有雨
OLED_ShowChinese(16*3+8,32,39,16,1);
}else{
OLED_ShowChinese(16*2+8,32,38,16,1); //无雨
OLED_ShowChinese(16*3+8,32,39,16,1);
}
OLED_ShowChinese(16*0,48,20,16,1); //光照强度
OLED_ShowChinese(16*1,48,21,16,1);
OLED_ShowChinese(16*2,48,22,16,1);
OLED_ShowChinese(16*3,48,23,16,1);
OLED_ShowChar(16*4,48,':',16,1);
OLED_ShowNum(16*4+8,48,Light_Value,4,16,1);
// OLED_ShowChinese(16*0,32,11,16,1); //消毒间隔
// OLED_ShowChinese(16*1,32,12,16,1);
// OLED_ShowChinese(16*2,32,28,16,1);
// OLED_ShowChinese(16*3,32,29,16,1);
// OLED_ShowChar(16*4,32,':',16,1);
// if(option==1)OLED_ShowNum(16*4+8,32,rays_time,3,16,0);
// else OLED_ShowNum(16*4+8,32,rays_time,3,16,1);
// OLED_ShowString(16*6,32,"min",16,1);
// OLED_ShowChinese(16*0,48,30,16,1); //柜门
// OLED_ShowChinese(16*1,48,19,16,1);
// OLED_ShowChar(16*2,48,':',16,1);
// if(door_flag==1)OLED_ShowChinese(16*2+8,48,17,16,1);
// else OLED_ShowChinese(16*2+8,48,18,16,1);
//
OLED_Refresh();
}
void OLED_Show_SecondPage()
{
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,1,16,1); // “湿”
OLED_ShowChinese(16*1,0,2,16,1); // “度”
OLED_ShowChinese(16*2,0,3,16,1); // “阈”
OLED_ShowChinese(16*3,0,4,16,1); // “值”
OLED_ShowChar(16*4,0,':',16,1); // “:”
OLED_ShowNum(16*4+8,0,humi_door,3,16,a); // hum_door_value
OLED_ShowChinese(16*0,16,20,16,1); // “光”
OLED_ShowChinese(16*1,16,21,16,1); // “照”
OLED_ShowChinese(16*2,16,3,16,1); // “阈”
OLED_ShowChinese(16*3,16,4,16,1); // “值”
OLED_ShowChar(16*4,16,':',16,1); // “:”
OLED_ShowNum(16*4+8,16,light_door,4,16,b); // light_door_value
// OLED_ShowChinese(16*0,32,1,16,1); // “打”
// OLED_ShowChinese(16*1,32,2,16,1); // “开”
// OLED_ShowChinese(16*2,32,3,16,1); // “时”
// OLED_ShowChinese(16*3,32,4,16,1); // “间”
// OLED_ShowChar(16*4,32,':',16,1); // “:”
OLED_Refresh();
}
void OLED_Show_ThirdPage(){
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,21,16,1); //照
OLED_ShowChinese(16*1,0,31,16,1); //明
OLED_ShowChar(16*2,0,':',16,1);
if(led_status==1)OLED_ShowChinese(16*2+8,0,17,16,a); //开
else OLED_ShowChinese(16*2+8,0,18,16,a); //关
OLED_ShowChinese(16*0,16,32,16,1); //晾
OLED_ShowChinese(16*1,16,33,16,1); //衣
OLED_ShowChinese(16*2,16,34,16,1); //架
OLED_ShowChar(16*3,16,':',16,1);
if(door_flag==1 || door_auto==1)OLED_ShowChinese(16*3+8,16,17,16,b); //开
else OLED_ShowChinese(16*3+8,16,18,16,b); //关
OLED_Refresh();
// page_num = 1;
}
五、项目效果图

六、项目总结
本系统各项功能均已实现并稳定运行,具体成果如下:
-
环境感知:温湿度、光照强度、雨滴感应、人体红外探测均采集准确,OLED屏幕实时刷新显示。
-
智能联动:下雨自动收衣架、天黑自动开灯、夜间人体靠近声光报警,三项自动功能响应灵敏。
-
手动控制:按键切换模式、修改参数、手动伸缩晾衣架均操作流畅。
-
远程监控:ESP8266成功接入机智云平台,手机App可远程查看环境数据并控制晾衣架。
项目结构紧凑、代码逻辑清晰、硬件成本可控,达到了预期设计目标,可实际应用于阳台智能晾晒管理场景。
七、包含资料
1)本资料免费分享,获取全套资料请看主页,并将告诉助手需要资料的项目编号,助手收到消息后,会发送百度网盘链接。每人限领两份开源资料。
2)需要实物或者定制的小伙伴可以添加工作室微信,发送项目需求,可以按照需求定制项目。定制包含源码、原理图、全套实物、模块参考资料、更详细的参考资料。
3)重点!!!在本工作室定制的项目,提供一年的技术支持和答疑服务,定制功能范围内的代码和原理图工程师一对一解疑答惑!
资料获取:查看主页介绍“充哥单片机设计”
更多推荐



所有评论(0)