基于STM32的智能盲人头盔系统设计与实现

文章目录

  • 0 前言
  • 1 简介
  • 2 主要器件
  • 3 实现效果
  • 4 设计原理
  • 4.1 硬件设计
  • **STM32模块**
  • **HC-SR04超声波避障模块**
  • 导航模块
  • 图象识别模块
  • 光敏传感模块
  • 智能语音合成模块
  • 4.2 软件设计
  • 5 部分核心代码
  • 5 最后

  • 0 前言

    🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。

    为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天要分享的是

    🚩 基于单片机的智能盲人头盔系统

    🥇学长这里给一个题目综合评分(每项满分5分)

  • 难度系数:4分
  • 工作量:4分
  • 创新点:3分
  • 1 简介

    盲人因为缺少了视觉的感知能力而行走不便,如何安全舒适独立出行已经成为目前困扰他们外出的最主要原因.目前最常用的导盲工具有拐杖和导盲犬,但传统的导盲拐杖不能发现较远处的障碍物且对于复杂的路况难以做出正确的判断,不能满足盲人独立出行的基本需求;此外,我国导盲犬的数量很少,需求远远大于供应,而且有些盲人也可能由于各种原因不愿意使用导盲犬.因此,设计出一种智能导盲设备更加方便的帮助盲人出行。

    2 主要器件

  • STM32单片机
  • HC-SRO4超声波模块
  • 导航模块
  • 图像识别模块
  • 光敏传感模块
  • 智能语音合成模块
  • 3 实现效果

    4 设计原理

    4.1 硬件设计

    设计的核心模块采用STM32模块,它负责头盔上各种传感器的相互协调以及信息的存储,保障各个模块正常的工作,电路图如图:

    STM32模块

    STM32单片机的主要硬件设计性能、集成度都比较高,功耗、电压等均都比较低,具有实时性、数字信号逻辑优化和预处理、开发简易的特点[2].能更好的负责头盔上各种传感器的相互协调以及信息的存储,保障各个模块的正常工作.STM32原理见图

    HC-SR04超声波避障模块

    简介

    HC-SR04超声波模块常用于机器人避障、物体测距、液位检测、公共安防、停车场检测等场所。HC-SR04超声波模块主要是由两个通用的压电陶瓷超声传感器,并加外围信号处理电路构成的。如图:

    两个压电陶瓷超声传感器,一个用于发出超声波信号,一个用于接收反射回来的超声波信号。由于发出信号和接收信号都比较微弱,所以需要通过外围信号放大器提高发出信号的功率,和将反射回来信号进行放大,以能更稳定地将信号传输给单片机。模块整体电路如图:

    模块参数

    (1)模块主要电气参数

  • 使用电压:DC—5V
  • 静态电流:小于2mA
  • 电平输出:高5V
  • 电平输出:底0V
  • 感应角度:不大于15度
  • 探测距离:2cm-450cm
  • 高精度 可达0.2cm
  • (2)模块引脚
    超声波模块有4个引脚,分别为Vcc、 Trig(控制端)、 Echo(接收端)、 GND;其中VCC、GND接上5V电源, Trig(控制端)控制发出的超声波信号,Echo(接收端)接收反射回来的超声波信号。模块如图

    导航模块

    导航功能的实现是通过使用百度API,对收到的坐标和目的地坐标发起检索请求,百度 API将显示出到达目的地的最佳路线以及所用时间等信息,通过语音提示引导用户到达目的地[3].该模块是通过STM32的响应串口,获取一个GPS响应端口协议数据,再将一个GPS的串口数据发送给需要STM32的响应串口,由串口数据采用GPS串口协议编译解码,解析编译出来后数据保存在需要响应的串口结构体中.

    图象识别模块

    由于超声波模块只能对前方4 m范围内的障碍物进行检测,所以为了更好地检测和识别盲区内的人和障碍物,以及实现助盲社交的功能,设计采用了图像识别模块.

    基于双目立体图像视觉三维仪的测量

    这种双目立体图像视觉三维仪的测量方法是基于立体视差计算原理[4],主要通过对两幅立体图像进行视差的综合计算,直接对前方两个物体高度进行一定距离上的测量.基线距为两个连线投影点或摄像机的基点基线中心的距离,用字母b表示.摄像机坐标所在投影镜头的内部有一光学坐标中心,光学坐标原点是作为整个投影摄像机所在镜头光学坐标系的一个运动原点,坐标的运动关系如图5所示.设O1和O2为光轴坐标原点距离左右俯视对象摄像机光轴以及光轴坐标交点1 m的距离,设空间中点的坐标为P,左反射图像和右反射图像中对应的两点坐标分别为P1(U1,V1)和P2(U2,V2).若两台摄像机的图像处于同一平面,点P上两个点的坐标与点y的坐标相同,即V1=V2.f表示焦距,b表示基线距,Zc表示P点在Z轴上的坐标.

    由三角几何关系得到位置差d: 及摄像机坐标系中的坐标值.

    人脸图像识别处理

    对于人脸识别以及对于红绿灯、斑马线的图像识别主要基于美国opencv公司发行的一款跨行业平台自动计算机图形视觉和自动机器智能学习软件库[5].对于使用人脸识别采集功能,首先需要利用人脸数据库采集市opencv采集中的人脸数据库采集orl构建人脸识别数据库,在不同人物表情、光照、人脸识别细节的不同情况下可以采集一个熟人的嘴和脸大小作为技能测试集,采集集中包含一个陌生人和一个熟人的嘴与脸大小作为技能训练集;对一个熟人的嘴和脸大小进行分割预处理,检测一个熟人的嘴和脸大小并用新的orl进行分割产生出新的人脸,通过分割改变人脸大小可以使它与熟人orl利用人脸识别数据库检测人物的脸细节大小一致.再利用人脸识别算法检测出熟人的脸.对于斑马线以及红绿灯的判定,是利用摄像头对周围环境进行拍摄并按帧保存图像;通过对图像的预处理将图像采集的过程中采集到的干扰项进行剔除.图像预分析处理之后将直接进入二次目标图像定位分析阶段,确定一个目标后对其图像进行二次数值边缘化与目标边缘化的提取,再与目标样本像素做高度比较,相似度较高若达到超过一个特定的图像值则可以认为其指的是一个目标,记录的是目标在其像素中的坐标.运用图像预处理方法,可计算出每个红绿灯光线位置,通过与红绿灯样本对比,确定每个红绿灯准确的光线位置,并对红绿灯的颜色进行判别并输出,再根据各个灯所在位置像素的R、G、B分量来判断灯的颜色,最后通过智能语音模块告诉盲人.

    光敏传感模块

    光敏信号传感器指的是一种可以利用这些光敏传感元件将光线电信号进行转换成为无线电信号的电子传感器,基本工作原理图如下:

    图中光敏电阻的工作是基于光电磁场效应,其阻值随光强的增大而减小.LM393则是双有源电压比较器,不受限于vcc的两端有源电压设定值的最大限制,它的负载电阻可以连接输出电压设定范围内的任何功率输出电压,还可用亮度电位控制器自动调节显示的亮度系数阈值亮度系数大于系统设定值时显示DO会自动输出亮度低电平,反之则会自动输出亮度高电平.利用这个特性,可以使头盔在夜间发光,以提醒周围行人和车辆,保障盲人夜间出行的安全.

    智能语音合成模块

    智能语音合成模块的功能是将控制模块发送的文本信息转换成语音从而输出,该部分采用XF-S4240中文语音合成模块,其主要应用于嵌入式领域。该模块有如下特点:

  • 可通过GB2312、GBK、Big5、Unicode的快速文本合成;同时,它支持中文文本和英文的合成,能够正确快速地识别英文、数字、时间点、日期和常用的国际度量单位符号;还支持处理各种音节和字母.

  • 拥有UART、SPI、I2C三种数据通信接口.

  • 支持合成、停止、暂停合成、继续合成等多种控制指令.

  • 存储模块用于存储待合成的文本数据文件.存储设备为语音控制系统SD卡(安全数字存储卡),具有便携性、通用性和安全性三大特点。

    4.2 软件设计

    具体软件流程

    5 部分核心代码

    //超声波测距
    //晶振=8M
    //MCU=STC10F04XE
    //P0.0-P0.6共阳数码管引脚
    //Trig  = P1^0
    //Echo  = P3^2
    #include <reg52.h>     //包括一个52标准内核的头文件
    #define uchar unsigned char //定义一下方便使用
    #define uint  unsigned int
    #define ulong unsigned long
    //***********************************************
    sfr  CLK_DIV = 0x97; //为STC单片机定义,系统时钟分频
                         //为STC单片机的IO口设置地址定义
    sfr   P0M1   = 0X93;
    sfr   P0M0   = 0X94;
    sfr   P1M1   = 0X91;
    sfr   P1M0   = 0X92;
    sfr	P2M1   = 0X95;
    sfr	P2M0   = 0X96;
    //***********************************************
    sbit Trig  = P1^0; //产生脉冲引脚
    sbit Echo  = P3^2; //回波引脚
    sbit test  = P1^1; //测试用引脚
    
    uchar code SEG7[10]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};//数码管0-9
    uint distance[4];  //测距接收缓冲区
    uchar ge,shi,bai,temp,flag,outcomeH,outcomeL,i;  //自定义寄存器
    bit succeed_flag;  //测量成功标志
    //********函数声明
    void conversion(uint temp_data);
    void delay_20us();
    //void pai_xu();
    
    void main(void)   // 主程序
    {  uint distance_data,a,b;
       uchar CONT_1;   
       CLK_DIV=0X03; //系统时钟为1/8晶振(pdf-45页) 
         P0M1 = 0;   //将io口设置为推挽输出
         P1M1 = 0;
         P2M1 = 0;
         P0M0 = 0XFF;
         P1M0 = 0XFF;
         P2M0 = 0XFF;
       i=0;
       flag=0;
    	test =0;
    	Trig=0;       //首先拉低脉冲输入引脚
    	TMOD=0x11;    //定时器0,定时器1,16位工作方式
    	TR0=1;	     //启动定时器0
       IT0=0;        //由高电平变低电平,触发外部中断
    	ET0=1;        //打开定时器0中断
     //ET1=1;        //打开定时器1中断
    	EX0=0;        //关闭外部中断
    	EA=1;         //打开总中断0	
      
    	
    while(1)         //程序循环
    	{
      EA=0;
    	     Trig=1;
            delay_20us();
            Trig=0;         //产生一个20us的脉冲,在Trig引脚  
            while(Echo==0); //等待Echo回波引脚变高电平
    	     succeed_flag=0; //清测量成功标志
    	     EX0=1;          //打开外部中断
    	 	  TH1=0;          //定时器1清零
            TL1=0;          //定时器1清零
    	     TF1=0;          //
            TR1=1;          //启动定时器1
       EA=1;
    
          while(TH1 < 30);//等待测量的结果,周期65.535毫秒(可用中断实现)  
    		  TR1=0;          //关闭定时器1
            EX0=0;          //关闭外部中断
    
        if(succeed_flag==1)
    	     { 	
    		   distance_data=outcomeH;                //测量结果的高8位
               distance_data<<=8;                   //放入16位的高8位
    		     distance_data=distance_data|outcomeL;//与低8位合并成为16位结果数据
                distance_data*=12;                  //因为定时器默认为12分频
               distance_data/=58;                   //微秒的单位除以58等于厘米
             }                                      //为什么除以58等于厘米,  Y米=(X秒*344)/2
    			                                       // X秒=( 2*Y米)/344 ==》X秒=0.0058*Y米 ==》厘米=微秒/58 
        if(succeed_flag==0)
    		   {
                distance_data=0;                    //没有回波则清零
    		   	test = !test;                       //测试灯变化
               }
    
         ///       distance[i]=distance_data; //将测量结果的数据放入缓冲区
         ///        i++;
      	  ///	 if(i==3)
    	  ///	     {
    	  ///	       distance_data=(distance[0]+distance[1]+distance[2]+distance[3])/4;
         ///        pai_xu();
         ///        distance_data=distance[1];
    
          
    	   a=distance_data;
           if(b==a) CONT_1=0;
           if(b!=a) CONT_1++;
           if(CONT_1>=3)
    		   { CONT_1=0;
    			  b=a;
    			  conversion(b);
    			}       
    	  ///		 i=0;
     	  ///		}	     
    	 }
    }
    //***************************************************************
    //外部中断0,用做判断回波电平
    INTO_()  interrupt 0   // 外部中断是0号
     {    
         outcomeH =TH1;    //取出定时器的值
         outcomeL =TL1;    //取出定时器的值
         succeed_flag=1;   //至成功测量的标志
         EX0=0;            //关闭外部中断
      }
    //****************************************************************
    //定时器0中断,用做显示
    timer0() interrupt 1  // 定时器0中断是1号
       {
     	 TH0=0xfd; //写入定时器0初始值
    	 TL0=0x77;	 	
    	 switch(flag)   
          {case 0x00:P0=ge; P2=0xfd;flag++;break;
    	    case 0x01:P0=shi;P2=0xfe;flag++;break;
    	    case 0x02:P0=bai;P2=0xfb;flag=0;break;
          }
       }
    //*****************************************************************
    /*
    //定时器1中断,用做超声波测距计时
    timer1() interrupt 3  // 定时器0中断是1号
        {
    TH1=0;
    TL1=0;
         }
    */
    //******************************************************************
    //显示数据转换程序
    void conversion(uint temp_data)  
     {  
        uchar ge_data,shi_data,bai_data ;
        bai_data=temp_data/100 ;
        temp_data=temp_data%100;   //取余运算
        shi_data=temp_data/10 ;
        temp_data=temp_data%10;   //取余运算
        ge_data=temp_data;
    
        bai_data=SEG7[bai_data];
        shi_data=SEG7[shi_data];
        ge_data =SEG7[ge_data];
    
        EA=0;
        bai = bai_data;
        shi = shi_data;
        ge  = ge_data ; 
    	 EA=1;
     }
    //******************************************************************
    void delay_20us()
     {  uchar bt ;
        for(bt=0;bt<100;bt++);
     }
    /*
    void pai_xu()
      {  uint t;
      if (distance[0]>distance[1])
        {t=distance[0];distance[0]=distance[1];distance[1]=t;} /*交换值
      if(distance[0]>distance[2])
        {t=distance[2];distance[2]=distance[0];distance[0]=t;} /*交换值
      if(distance[1]>distance[2])
        {t=distance[1];distance[1]=distance[2];distance[2]=t;} /*交换值	 
        }
    */
    
    

    5 最后

    物联沃分享整理
    物联沃-IOTWORD物联网 » 基于STM32的智能盲人头盔系统设计与实现

    发表评论