“3分硬件,7分软件”,优秀的算法可以使你的作品稳定运行,大家千万避免“隔夜车”。这期主要讲解怎么用STM32解算红外模块输出的模拟量。
我们希望红外模块经过单片机解算后可以根据智能车在黑线左右不同位置输出不同的数值,例如下面这两张图


图一图二
上面两种都可以,输出值的正负只是代表小车在黑线的左边或者右边,绝对值越大表示小车越偏离黑线。
一、硬件改装
我买的红外模块一般是根据环境的不同输出1和0,遇到白色输出1,遇到黑色输出0(有些是反过来的:遇到白色输出0,遇到黑色输出1)。

图三
原理:蓝色的是红外发射管,黑色的是红外接收管,红外接收管在距离黑线不同距离时会输出不同电压,当输出电压大于电压比较器的阈值时,此时模块的输出端为低电平,指示二极管被点亮。
那么“红外接收管在距离黑线不同距离时会输出不同电压”这个是我们想要的,看一下商家给的原理图,红外接收管一端连接地,另一端就是电压输出管脚,

图四寻迹传感器模块电路图
用万用表调到蜂鸣档,测试红外接收管哪一端是接地,另一端自然就是我们要的电压输出管脚,如下图。

图五
怎么改装?可以把杜邦线一端剪掉,漏出铜丝然后和红外接收管的电压输出端焊在一起,另一端接到stm32的ADC采集管脚。

图六
这样我们们根据红外模块在黑线的不同位置采集到不同的电压值,然后通过stm32的模数转换功能,也就是我们常说的ADC功能,输出0-4095。
二、算法原理
首先看看一个红外模块在黑线中间时stm32采集的波形

图七
那么怎么得到下面这种波形呢?

图八
第一步、我们车头左右各安装一个红外模块。

图九
用单片机采集两个红外于是得到下面这个波形,注意:黄色是右边红外的ADC值,红色是左边边红外的ADC值。当车头向右平移时,右边的红外逐渐远离黑线,左边的红外逐渐靠近红外然后再远离黑线,所以左边红外的ADC值会先增大再减小,车头向左平移同理。

图十
第二步,把右边红外ADC采集波形关于x轴翻转,这个用代码很容易做到,然后输出下图波形:

图十一
代码:Deviation= Left_x1 - Right_x1;
Deviation就是左右红外作差输出,Left_x1是左边红外ADC值,Right_x1是右边红外ADC值。此时中间部分蓝色的波形已经没问题了,如下图,剩下两端黄色的部分就是左红外到达峰值时继续向右偏离和右红外到达峰值时继续向左偏离的部分。

图十二
第三步、在车头中间安装一个红外。

图十三
来监控左右红外是否到达峰值,如下图。将小车从黑线中间向右平移,当左红外ADC到达峰值时LEFT_MAX,此时中间红外的ADC值Mid为左阈值LEFT_THERSH,右阈值同理。

图十四
如果中间红外ADC值小于左阈值且此时车头位于黑线右边,那么Deviation=2*左红外ADC最大值-左边当前采集ADC值,那么怎么判断车头位于黑线右边呢?我们可以定义一个标志位PosFlag,然后大概选一个合适的阈值PosFlagValue,当Deviation
代码:
int PosFlagValue = 600;
char PosFlag=0; //定义传感器位置标志位,1认为传感器在黑线偏左位置,0认为传感器在黑线偏右位置
Deviation = Left_x1 - Right_x1;//红外偏移量, 左 -> 右 -4095-> +4095
if(Deviation>PosFlagValue)
PosFlag = 1;
else if(Deviation
PosFlag = 0;
if(Mid_x1
{
Deviation=(2*LEFT_MAX-Left_x1);
}
if(Mid
{
Deviation= Right_x1-2*RIGHT_MAX;
}
匿名上位机显示Deviation波形,小车从左向右移动

图十五
全车图片:

图十六
展示视频:
视频十七
代码参考在:
https://gitee.com/iornx/SEIG-T307
本次对算法不清楚的可加群交流。如教程有错,请指正。

图十八交流群二维码
供稿:T307智能车实验室