【单片机毕业设计】【mcuclub-dz-1056】家用视力检测仪

在这里插入代码片
最近设计了一个项目家用视力检测仪,与大家分享一下:

一、基本介绍

项目名:家用视力检测仪
项目编号:mcuclub-dz-1056
单片机类型:STM32F103C8T6
具体功能:
1.超声波传感器测距离(检测人的距离、距离阈值动态调整:根据用户身高和检测场景,通过按键或APP设置个性化距离阈值)
2.光敏传感器测光线以及补光(太暗了就调亮 太亮了就调暗 正常就提示:光线正常 可以正常测试)
3.语音播报模块(开始检测的提示、站的太远或太近的提示、光线的提示、测量结果播报等)
4.语音识别(用户说上、下、左、右)
5.温湿度传感器(监测检测环境温湿度,补偿因环境变化导致的测量误差如镜片雾化影响成像等、监测环境干扰(当环境光变化>10%时暂停测试并播报环境异常,避免因镜片雾化导致误判)、空气质量预警(VOC>2000ppb触发通风建议(语音播报提醒)))
6.显示屏也显示测试结果
7.数据云端同步:通过Wi-Fi模块上传检测数据至云端,生成长期视力健康报告。

二、32实物图

单片机型号:STM32F103C8T6

板子为绿色PCB板,两层板,厚度1.2,上下覆铜接地。元器件基本上为插针式,个别降压芯片会使用贴片式。

供电接口:TYPE-C
请添加图片描述

三、原理图

软件版本:AD2013

电路连线方式:网络标号连线方式

注意:原理图只是画出了模块的引脚图,而并不是模块的内部结构原理图
本设计以STM32F103C8T6单片机为核心控制器,结合多种模块构建家用视力检测系统,系统包括中控部分、输入部分和输出部分。中控部分采用STM32F103C8T6单片机,其主要功能是采集输入数据并进行处理,进而控制输出部分。输入部分由以下模块组成:第一部分是超声波测距模块,用于检测用户距离并支持动态阈值调整;第二部分是光照检测模块,用于环境光线检测;第三部分是语音识别模块,用于接收用户方向指令;第四部分是温湿度检测模块,用于环境监测;第五部分是空气质量检测模块,用于空气质量检测;第六部分是按键模块,用于参数设置;第七部分是供电模块,为系统提供电源支持。输出部分由以下模块组成:第一部分是LED灯模块,用于自动调节检测环境亮度;第二部分是语音播报模块,用于提供操作引导和结果播报;第三部分是显示模块,用于显示检测结果和环境参数;除此之外还有WiFi模块,用于将检测数据同步至云端。系统框图如图3.1所示。
在这里插入图片描述

四、PCB图

由原理图导出,封装很大一部分都是作者自己绘制,不提供封装库,只提供连接好的源文件。中间有一个项目编号,隐藏在单片机底座下,插入单片机后不会看到。

两层板,上下覆铜接地。
请添加图片描述

五、系统框图

本设计以STM32F103C8T6单片机为核心控制器,结合多种模块构建家用视力检测系统,系统包括中控部分、输入部分和输出部分。中控部分采用STM32F103C8T6单片机,其主要功能是采集输入数据并进行处理,进而控制输出部分。输入部分由以下模块组成:第一部分是超声波测距模块,用于检测用户距离并支持动态阈值调整;第二部分是光照检测模块,用于环境光线检测;第三部分是语音识别模块,用于接收用户方向指令;第四部分是温湿度检测模块,用于环境监测;第五部分是空气质量检测模块,用于空气质量检测;第六部分是按键模块,用于参数设置;第七部分是供电模块,为系统提供电源支持。输出部分由以下模块组成:第一部分是LED灯模块,用于自动调节检测环境亮度;第二部分是语音播报模块,用于提供操作引导和结果播报;第三部分是显示模块,用于显示检测结果和环境参数;除此之外还有WiFi模块,用于将检测数据同步至云端。系统框图如图3.1所示。

请添加图片描述

六、软件设计流程

请添加图片描述

七、部分程序展示

软件版本:keil5

逻辑程序和驱动程序分开,分布于main.c和其他.c文件

/**********************************
函数名:处理函数
传参值:无
返回值:无
**********************************/
void Manage_Function(void)
{
	if(display_num == 0)								  										//测量界面
	{
		if(flag_zb == 1)
		{
			if(light_value > light_max)														//光照大于设置最大值,关闭灯光
			{
				if(time_num % 10 == 0)
				{
					if(flag_gear > 0)
						flag_gear --;
				}
			}
			else if(light_value < light_min)											//光照小于设置最小值,灯光最亮
			{
				if(time_num % 10 == 0)
				{
					if(flag_gear < 10)
						flag_gear++;
				}
			}
			else																									//光照处于设置的上下限值之间,根据光照值调节灯光亮度
			{
				Huart2_Send_Str("  光线正常 可以正常测试");
				Delay_ms(3000);		
				flag_zb = 2;
			}
		}
		else if(flag_zb == 2)
		{
			if(distance_value < distance_min)
			{
				if(time_num % 100 == 0)
				{
					Huart2_Send_Str("  距离过近");
				}
			}
			else if(distance_value > distance_max)
			{
				if(time_num % 100 == 0)
				{
					Huart2_Send_Str("  距离过远");
				}
			}
			else
			{
				if(temp_value > temp_max*10 || temp_value < temp_min*10)
				{
					Huart2_Send_Str("  温度异常 停止测试");
					
					flag_zb = 0;	
				}
				else if(humi_value > humi_max*10 || humi_value < humi_min*10)
				{
					Huart2_Send_Str("  湿度异常 停止测试");

					flag_zb = 0;	
				}
				else
				{
					Huart2_Send_Str("  距离正常,温湿度正常 开始测试");
					Delay_ms(3000);	
					light_jl = light_value;
					flag_zb = 3;	
					huart3_data = 0x00;
				}
			}
		}
		else if(flag_zb == 3)                            //开始测试
		{
			if(flag_answer == 1)																	//开始回答
			{
				flag_timer_begin = 1;

				if(huart3_data != 0x00)																		//有按键按下时计时清零
				{
					time_5s = 0;
					
					if(flag_buf == 0)																  //显示灯指示数组0
					{
						if(dir_buf0[flag_index] == huart3_data)						//如果按到正确的按键,且没有错位,继续往下测试,反之记错
						{
							if(flag_error == 0)
								flag_index++;
						}
						else
							flag_error++;
					}
					else if(flag_buf == 1)													  //显示灯指示数组1
					{
						if(dir_buf1[flag_index] == huart3_data)
						{
							if(flag_error == 0)
								flag_index++;
						}
						else
							flag_error++;
					}
					else if(flag_buf == 2)													  //显示灯指示数组2
					{
						if(dir_buf2[flag_index] == huart3_data)
						{
							if(flag_error == 0)
								flag_index++;
						}
						else
							flag_error++;
					}
					else													  									//显示灯指示数组3
					{
						if(dir_buf3[flag_index] == huart3_data)
						{
							if(flag_error == 0)
								flag_index++;
						}
						else
							flag_error++;
					}
					
					flag_broadcast = 1;
					huart3_data = 0x00;
				}
				else																							 //计时五秒钟,超时算错一次
				{
					if(flag_1s == 1)
					{
						flag_1s = 0;
						time_5s++;
					}
					
					if(time_5s >= 10)
					{
						time_5s = 0;
						flag_error++;
						flag_broadcast = 1;
					}
				}
		
				if(flag_broadcast == 1)
				{
					flag_broadcast = 0;
					
					switch(flag_error)															//判断错了几次
					{
						case 0:																				//错误次数为0,则一直测试,直到测到最后一个后播报相应的视力值,停止答题
							if(flag_index >= 13)
							{
								Huart2_Send_Str("本次测试结束,您的视力值为:%d点%d",sco_buf[flag_index/2] / 10,sco_buf[flag_index/2] % 10);
								flag_sl = sco_buf[flag_index/2];
								Aliyun_Send_Data_sl();
								flag_index = 12;
								flag_answer = 0;
							}
							else
								Huart2_Send_Str("回答正确");
						break;
							
						case 1:																				//错误次数为1,则判断是不是第一个灯,是则直接播报视力
							if(flag_index == 0)
							{
								Huart2_Send_Str("本次测试结束,您的视力值为:%d点%d",sco_buf[flag_index/2] / 10,sco_buf[flag_index/2] % 10);
								flag_sl = sco_buf[flag_index/2];
								Aliyun_Send_Data_sl();
								flag_answer = 0;
							}
							else																				//错误次数为1,且不为第一个灯,判断是那一行的第一个还是第二个灯,错的是第一个则播报回答错误后再判断一次视力
							{
								if(flag_index % 2 == 1)							
								{
									Huart2_Send_Str("回答错误");
									flag_index++;
								}
								else																			//错的是第二个灯则播报视力值
								{
									Huart2_Send_Str("本次测试结束,您的视力值为:%d点%d",sco_buf[flag_index/2] / 10,sco_buf[flag_index/2] % 10);
									flag_sl = sco_buf[flag_index/2];
									Aliyun_Send_Data_sl();
									flag_answer = 0;
								}
							}
						break;
						
						case 2:																			 //错两个则播报上一行的视力值
							Huart2_Send_Str("本次测试结束,您的视力值为:%d点%d",sco_buf[flag_index/2 - 1] / 10,sco_buf[flag_index/2 - 1] % 10);
							flag_sl = sco_buf[flag_index/2];
							Aliyun_Send_Data_sl();
							flag_answer = 0;
						break;
						
						default:
						break;
					}
				}

				if(((light_value - light_jl) > light_jl / 10.0) || ((light_jl - light_value) > light_jl / 10.0) || humi_value > humi_max*10 || humi_value < humi_min*10 || temp_value > temp_max*10 || temp_value < temp_min*10)
				{
					flag_answer = 0;
					Huart2_Send_Str("  环境异常,本次测试结束,测试结果无效");
					flag_zb = 0;
					HC595_Function(0xFFFFFFFF);
					flag_timer_begin = 0;	
				}
			}
			else																								//停止回答
			{
				flag_timer_begin = 0;															//停止计时
				flag_zb = 0;
			}
		}
		if(TVOC_value > TVOC_max)        //空气质量预警(VOC>2000ppb触发通风建议(语音播报提醒)))
		{
			if(time_num % 100 == 0)
			{
				Huart2_Send_Str("  空气质量过高,请打开通风");
			}
		}
	}
	else																											//设置界面,关闭加热、制冷及声光报警
	{
		flag_timer_begin = 0;	
	}
	
	if(flag_finish_5s == 1)																		//5秒上传一次数据
  {
    flag_begin_5s = 0;
    Aliyun_Send_Data();
    flag_begin_5s = 1;
  }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

单片机俱乐部--官方

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值