系列目录

模块介绍

TCRT5000光电传感器模块是基于TCRT5000红外光电传感器设计的一款红外反射式光电开关。传感器采用高发射功率红外光电二极管和高灵敏度光电晶体管组成,输出信号经施密特电路整形,稳定可靠。
传感器的红外发射二极管不断发射红外线,当发射出的红外线没有被反射回来或被反射回来但强度不够大时,光敏三极管一直处于关断状态,此时模块输出端(引脚1)为低电平,指示二极管一直处于熄灭状态;被检测物体出现在检测范围内时,红外线被反射回来且强度足够大,光敏三极管饱和,此时模块的输出端为高电平,指示二极管被点亮
————————————————
版权声明:本文为CSDN博主「小刘和C/C++」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/wlswls1711/article/details/103113626

当检测到黑线时,D1 D2输出高电平,否则输出低电平。通过读取电平值,即可知道当前状态。

接线

通过PH2.0接口接到SA4,SD4接口上。

D1对应了PB1,D2对应了PA3。

CubeMX配置

复制上一节工程。添加PA3,PB1为GPIO_Input,浮空,标签设置为D2,D1。

编写代码

打开sensor.h
添加循迹状态定义和GPIO读取值定义,循迹任务声明

#define D1() HAL_GPIO_ReadPin(D1_GPIO_Port,D1_Pin)
#define D2() HAL_GPIO_ReadPin(D2_GPIO_Port,D2_Pin)
#define XJ_ON 0
#define XJ_OFF 1
int xunji_task(void);

然后打开sensor.c,编写循迹代码
对于简单的巡线,当机器人在线上时,两路红外返回值都为0,机器人直线前进;
当需要左拐时,右边红外会越界,也就是检测不到黑线,所以返回值为1,此时调整机器人转向直至右边红外入界,继续直线前进。
当需要右拐时,左边红外会越界,也就是检测不到黑线,所以返回值为1,此时调整机器人转向直至右边红外入界,继续直线前进。
当两边都检测不到黑线时,要么巡线结束,要么机器人完全出界。对于第一种情况,应该使机器人完全停下。对于第二种情况,不允许出现。解决这种情况可以有多种调节方法:

  1. 提高检测时间分辨率,即减少检测间隔,在检测到越界后立马转向
  2. 提高转向速度,避免转向太慢导致的出界
  3. 原地旋转替换差速前进,转到黑线上后在继续前进
  4. 出界后,编写算法,根据前后状态,自动尝试返回黑线上

有了基本逻辑,我们很容易就能编写出代码。
代码如下

int xunji_task(void) {
	static uint32_t systick_ms_bak = 0;
	int speed = 500;
	int millis=HAL_GetTick();//获取系统时间
	if(millis - systick_ms_bak < 50) return 1; //检测间隔,在这里修改分辨率
	systick_ms_bak = HAL_GetTick();
	
	if((D2() == XJ_OFF) && (D1() == XJ_ON)) { //D2出界,需要左转
		motor_set(-speed-300, speed+300); //原地左转,在这里修改转向速度
	} else if((D2() == XJ_ON) && (D1() == XJ_ON)) {//直线行驶
		motor_set(speed, speed);
	} else if((D2() == XJ_ON) && (D1() == XJ_OFF)) {//D1出界,需要右转		
		motor_set(speed+300,-speed-300); //原地右转,在这里修改转向速度
	} else if((D2() == XJ_OFF) && (D1() == XJ_OFF)){//出界或者结束
		motor_set(0,0);//这里只写了结束的代码,如果误判出界,修改时间和速度基本能解决
		return 0;
	}
	return 1;
}

然后再main中添加对应任务

case 'J':while(xunji_task());break;

烧录后如果出现初始原地打转的情况,则可能是DJ1和DJ2对应关系反了,
修改下

#define D1() HAL_GPIO_ReadPin(D1_GPIO_Port,D1_Pin)
#define D2() HAL_GPIO_ReadPin(D2_GPIO_Port,D2_Pin)

#define D2() HAL_GPIO_ReadPin(D1_GPIO_Port,D1_Pin)
#define D1() HAL_GPIO_ReadPin(D2_GPIO_Port,D2_Pin)

或者反装循迹模块
或者修改控制逻辑

工程源码

国内用户请使用gitee克隆或是使用代理访问Github
https://github.com/USTHzhanglu/stm32-hal/tree/main/trct5000