51智能循迹小车

前面介绍了小车的避障逻辑和代码实现过程,这次我们来看看小车的自当巡线功能是如何实现的

一、巡线功能架构

巡线功能整体架构如下所示:

关于驱动层中GPIO和计数器、定时器的相关配置在前面都有提到,感兴趣的同学可以翻看以前的文章。我们着重介绍接口层的定义和实现功能。

二、接口层

光电传感器模块XD393

设计思路:光电传感器模块以弧形排列在车头,从而侦测出小车行进方向和轨道的偏离程度,从而进行纠正。当传XD393数据手册感器正下方有黑线时,传感器返回信号1;否则返回信号0。XD393数据手册icon-default.png?t=O83Ahttps://item.szlcsc.com/586596.html

其封装如下所示:

每个XD393提供两组比较器,1IN+、1IN-和1OUT为一组,2IN+、2IN-和2OUT为一组,Vcc接电源,GND接地。当1IN+电势高于1IN-时,1OUT输出高电平,否则输出低电平。当2IN+电势高于2IN-时,2OUT输出高电平,否则输出低电平。1OUT和2OUT的电平只有两个取值,高电平(VCC)或低电平(0V,GND)。 

电路原理图分析

 

  1. DY-ITR9909是光电传感器,左半部分为红外发射器,引脚2接高电平,引脚1接低电平。右半部分可以理解为一个光敏电阻,引脚4接高电平,引脚3接地。
  2. 当接收不到红外光时,光敏电阻阻值无穷大VB途径光敏电阻至VE为断路,VA和VB电势均与电源保持一致,为5V。
  3. 当接收到红外光时,光敏电阻阻值减小,VB至VE导通,光敏电阻阻值与R11串联,二者根据阻值大小分压,从而改变VB的电势。
  4. R12为滑动变阻器(电位器),通过移动滑片可以改变U11.1引脚2的电势,在上图中,滑片位置越靠上,U11.1引脚2电势越高。
  5. U11.1为XD393的其中一组比较器,假设R12的滑片位置已固定。当VB电势为5V时,引脚3电势为5V,大于引脚2的电势,此时引脚1输出高电平5V,VF电势为5V,R9和LED6串联,此时二者两侧电势均为5V,LED6不会亮起。
  6. 光敏电阻接收到的红外光越强,R11分压越高,VB电势越低,U11.1引脚3电势越低,当其电势小于引脚2电势时,引脚1输出低电平,即0V,VF电势为0V,LED6亮起。

这就是光电传感器的工作原理,大家可以自行理解一下,如果实在搞不清楚也没关系,只要记住:光电传感器的发射端向物体表面发射红外光,物体将部分红外光反射回去被光电传感器的接收端接收,后者接收的红外光未达到一定值时,LED6不亮。反之,当接收端接收的红外光足够多时,LED6亮起,就可以了。

三、代码实现

​​​​​​​Int_Sensor.h

#ifndef __SENSOR_H__
#define __SENSOR_H__
#include "Dri_GPIO.h"
#include "Util.h"

/**
 * @brief 获取当前误差,正数偏左,负数偏右
 * 
 * @return 误差
 */
char Int_Sensor_GetError();

#endif

 ​​​​​​​Int_Sensor.c

 

​​​​#include "Int_Sensor.h"

#define LL_VALUE -4
#define LM_VALUE -2
#define MM_VALUE 0
#define RM_VALUE 2
#define RR_VALUE 4

// 最近一次测量的误差
static char s_error;

char Int_Sensor_GetError()
{
    // 侦测到黑线的传感器个数
    u8 count;
    if (LL || LM || MM || RM || RR)
    {
        count   = 0;
        s_error = 0;
        if (MM)
        {
            s_error += MM_VALUE;
            count++;
        }
        if (LM)
        {
            s_error += LM_VALUE;
            count++;
        }
        if (LL)
        {
            s_error += LL_VALUE;
            count++;
        }
        if (RM)
        {
            s_error += RM_VALUE;
            count++;
        }
        if (RR)
        {
            s_error += RR_VALUE;
            count++;
        }
        s_error /= count;
    }

    return s_error;
}

四、测试

在main.c文件中写入以下代码

#include "Int_Sensor.h"
#include "Int_LCD1602.h"

void main() 
{
    // 初始化LCD1602
    Int_LCD1602_Init();

    while(1) 
    {
            // 当计数变量减为0时,接收传感器结果,并将i重置为1000
            Int_Sensor_GetError();
    }
}

 将小车放置在白色平面,可以看到车头前方的五个指示灯全部亮起,液晶屏显示“Digression!”。

依次遮挡其余各个光电传感器,来根据指示灯的亮灭状态和显示屏状态来验证系统功能。

至此,我们就完成了小车中循迹传感器部分的设计。 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值