STM32 HAL库快速实战【十一】《红外传感器的使用及巡线循迹》--基于黑龙江科技大学机电工业机器人实训
系列目录
点击查看
- STM32 HAL库快速实战【一】《32点灯》--基于黑龙江科技大学机电工业机器人实训 - USTHzhanglu - 博客园 (cnblogs.com)
- STM32 HAL库快速实战【三】《pwm控制舵机》--基于黑龙江科技大学机电工业机器人实训 - USTHzhanglu - 博客园 (cnblogs.com)
- STM32 HAL库快速实战【四】《串口简单使用》--基于黑龙江科技大学机电工业机器人实训 - USTHzhanglu - 博客园 (cnblogs.com)
- STM32 HAL库快速实战【五】《控制串口电机》--基于黑龙江科技大学机电工业机器人实训 - USTHzhanglu - 博客园 (cnblogs.com)
- STM32 HAL库快速实战【六】《蓝牙控制》--基于黑龙江科技大学机电工业机器人实训 - USTHzhanglu - 博客园 (cnblogs.com)
- STM32 HAL库快速实战【七】《机械臂控制》--基于黑龙江科技大学机电工业机器人实训 - USTHzhanglu - 博客园 (cnblogs.com)
- STM32 HAL库快速实战【八】《声音传感器的使用》--基于黑龙江科技大学机电工业机器人实训 - USTHzhanglu - 博客园 (cnblogs.com)
- STM32 HAL库快速实战【九】《超声波传感器的使用以及自由避障》--基于黑龙江科技大学机电工业机器人实训 - USTHzhanglu - 博客园 (cnblogs.com)
- STM32 HAL库快速实战【十】《颜色传感器的使用》--基于黑龙江科技大学机电工业机器人实训 - USTHzhanglu - 博客园 (cnblogs.com)
- STM32 HAL库快速实战【十一】《红外传感器的使用及巡线循迹》--基于黑龙江科技大学机电工业机器人实训 - USTHzhanglu - 博客园 (cnblogs.com)
模块介绍
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,此时调整机器人转向直至右边红外入界,继续直线前进。
当两边都检测不到黑线时,要么巡线结束,要么机器人完全出界。对于第一种情况,应该使机器人完全停下。对于第二种情况,不允许出现。解决这种情况可以有多种调节方法:
- 提高检测时间分辨率,即减少检测间隔,在检测到越界后立马转向
- 提高转向速度,避免转向太慢导致的出界
- 原地旋转替换差速前进,转到黑线上后在继续前进
- 出界后,编写算法,根据前后状态,自动尝试返回黑线上
有了基本逻辑,我们很容易就能编写出代码。
代码如下
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