白线识别模块.docx
- 文档编号:30500491
- 上传时间:2023-08-16
- 格式:DOCX
- 页数:12
- 大小:754.83KB
白线识别模块.docx
《白线识别模块.docx》由会员分享,可在线阅读,更多相关《白线识别模块.docx(12页珍藏版)》请在冰豆网上搜索。
白线识别模块
1.最简单的白线识别模块是采用发光二极管照射地面,由光敏二极管接受,引起光敏二极管反向电阻变化。
通过将与光敏二极管串联的采样电阻上的电压与设定的参考电压比较,来判断不同颜色的地面
原理图如下:
注:
1.这里用运放LM358作为比比较器用,因为以前我做过这个电路,使用比较器339做出来的效果很不好,换成358就好多了。
2.通过电位器设定一个参考电压。
当led照射到白色(反光较强)的地面时,光敏二极管D1(反接)的电阻减小,R3上分压增大,超过电位器R1上的分压时,比较器输出低电平,认为是白线。
反之,地面不是白色,反光较差,R3上分压小,小于R1上分压时比较器输出高电平,认为不是白线
3.led和光敏二极管需要用遮光物围起来,减少外界灯光的干扰。
更换场地后,需要调节电位器重新设定参考电压。
3.上面提到的方法不够可靠,外界光线很容易干扰到结果,同时调试起来很麻烦,需要人工调节电位器,如果有很多对的话,难度很大。
通过思考和向师兄学习,我决定采用如下方法:
上图中R3上的电压输出给ADC,然后将转化过的数字信号交给单片机处理,这样进行标定时只需要改单片机里设定的参考值,并且可一次设定多路。
Led受单片机控制,不再是常亮。
灯灭时采集一个数据,灯亮时采集一次,两次数值做差,不懂颜色地面的反光不同,这个差值也一定不同,从而判断出是否为白线。
单片机同时控制多路探头,判断出各探头的结论后,通过总线输出给决策芯片。
这样就构成了一个可简单增加的白线探测模块。
设计思路
Atmel公司的AVR系列单片机,自带8路10位ADC,同时有SPI,UART,I2C等通讯方式,故非常适合做这个模块。
为了简化电路,采用了IO口较多的Mega16芯片,这样扩展性强,不容易遇到引脚共用的情况。
上图为ATmega16的ADC方框图,可见它有一个10位的逐次比较型ADC,和一个八路选择器。
据官方称10位精度时能做到200/13=15.38KHz的采样率,实际我用到的采样率只有5KHz。
(来自官方datasheet)
1.由于选用了功能强大的AVR单片机,使得白线识别模块的电路大大简化,这样不仅降低了设计难度,还提高了可靠性。
流程为:
1)单片机控制第i路led灭
2)读取对应取样电阻上的电压值
3)单片机控制此一路led亮
4)读取对应取样电阻上的电压值
5)两数值做差,差值与基准值比较,大于认为是白线,反之认为不是。
6)采集每一路的信号,判断每对探头下是不是白线,将所有探头的结果输出给主控板。
2.需求:
mega16单片机及基本外围电路,led(红),光敏二极管。
3.采集时信号较稳定,不需要采样-保持电路。
4.这套系统不需要很高精度,故把单片机采集到的10位数据仅保留前八位,以便于后面的运算(比起比较器的“一位”精度,还是要高很多的)
5.使用按键作为外部中断源,在外部中断函数里进行标定,这样可以快速准确的标,同时还可以把得到的阈值存入到eeprom里,下次不换场地就不用标定了。
原理实现
采用红色发光二极管,因为其耗能小,发射能量适中。
蓝色及白色发光二极管耗能很大,同时能量大,很容易使光敏二极管饱和。
(其实这个要根据场地颜色来定,以前的理解不太对。
如果在红色场地上的白线,用红led就很难分辨,而蓝色的就对比很大。
所以可以用两排不同颜色的led。
另外led可以通过一个IO口加一个三极管来控制,不需要每个led都配一个IO。
当初这么搞也是为了顺便做跑马灯)
电路原理图如下:
(画图用的软件是一款免费软件:
eagle,比较简单,但是绘制这种电路完全够用了。
格式上和protel不兼容,画出的图风格略显不同。
不过库文件比较全,原件大都能找得到)
采集部分的介绍
最上面一组是光敏二极管,下面一组是作为状态显示的led,最下面一组是照明用led(因为mega16的PA和PC端口是在同一侧)
最下面设置了两个按键,用于触发外部中断,进行标定。
程序算法:
(源码见附件)
unsignedcharget_adc(unsignedcharch)//进行ADC转化,并读出转化结果
{;
设置参考电压,转换模式,开始转化,返回结果
}
SIGNAL(SIG_INTERRUPT0)//外部中断0,指定白线,采集在白线上灯亮-灯灭的值white,和gate
{
按键重复检测,防抖动
灯亮,采集每路数据,记作led_on[i]
灯灭,采集每路数据,记作led_off[i]
对每一路数据做差,white[i]=(led_on[i]-led_off[i]
求每一路阈值gate[i]=(white[i]+not_white[i])/2
将阈值存入eeprom中
等待按键释放
}
SIGNAL(SIG_INTERRUPT1)//外部中断1,指定not白线,采集不在白线上灯亮-灯灭的值not_white,和gate
{
按键重复检测,防抖动
灯亮,采集每路数据,记作led_on[i]
灯灭,采集每路数据,记作led_off[i]
对每一路数据做差,not_white[i]=(led_on[i]-led_off[i]
求每一路阈值gate[i]=(white[i]+not_white[i])/2
将阈值存入eeprom中
等待按键释放
}
intmain(void)//主函数,判断每路是否为白线,并将结果通过PB口的8个led输出
{
读取eeprom中存储的阈值信息
设置端口工作模式,允许中断发生
循环判断每路状态
{
灯亮,采集每路数据,记作led_on[i]
灯灭,采集每路数据,记作led_off[i]
对每一路数据做差,dis[i]=(led_on[i]-led_off[i]
与阈值比较,
if(dis[i]>gate[i])
认定为白线,PB口对应led点亮,
else
认定不是白线,PB口对应led熄灭
}
}
程序说明:
写得比较简单,所有照明用led都是同时亮,同时灭,没有做成扫描式。
但实际使用时发现做成扫描式的也不会有改观。
由于从led点亮到采样电阻上点稳定需要大概3ms,故再灯亮和灯灭后都加了延迟函数。
每个用于标定的外部中断函数最后都求了一次阈值,这样只要两个状态都标定过了,阈值一定是对的,对表定的顺序没有要求。
同时每个中断里都有写eeprom,两个面都标定后正确的阈值会覆盖到对应地址。
启动时读取eeprom中存储的阈值,场地不换的话就不用标定了
只是作为演示用,未添加总线通讯部分,只是用PB口作为显示。
实物和测试
背面特写:
全拿万用版焊的,还好焊出来就能用。
上方两个按键是外部中断源,左边一个为外部中断0,用于标定白线(高反光面),右边按键标定弱反光面。
正面特写:
和正在调试的三轮全向机器人。
由于白线不好买,现阶段作寻黑线测试,这一方面也体现了该白线识别模块的灵活性。
图中可以看到,白线识别模块的单片机通过UART串口总线与下面盒子里的的主控芯片通讯。
光敏二极管和PC口控制的led交替排列,并且将光敏二极管的四周用热缩管包住,使进到光敏管的光线主要来自正面。
下面八个绿色led用于显示判断的结果,如果上面对应光敏二极管下面是白线(或寻黑线),则对应绿色led亮。
工作效果
黑线的标定。
这里规定检测到黑线时对应灯亮。
实际效果,右数第四个灯亮,对应右数第四个光敏二极管下面是黑线。
判断到两个黑线的情况。
相邻两个光敏管的间距是<16mm,而黑线宽度是20mm,所以不会出现黑线在两灯之间而丢失信号的情况
测试感受
装在三轮全向小车上走黑线还是比较可靠的,但是等机器人速度提高了之后会怎么样还不知道。
根据示波器测量的结果,当led点亮后,采样电阻上的电压需要约3ms才能稳定,这限制了该板最大采样频率只能达到300Hz。
我准备换成更灵敏的光敏三极管再试一试,或者采购高速的光敏二极管。
将阈值存在eeprom里是十分有必要的,这样在同一个场地上就不必每次开机都标定了。
实用化的电路将主要采用贴片原件以减小尺寸,单片机用mega8足够了,另外根据场地情况不一定把灯做成一排。
注:
其实发现光敏二极管响应慢是led亮度太低。
减小电阻,让led工作在20mA下,就能大大减小采样电阻,提高光敏管的响应。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 识别 模块