飛思卡爾那些事之離散型光電管路徑識(shí)別
資源:
1、紅外光電發(fā)射接收管
2、電壓比較器
3、HCS12的IO口
4、HCS12的ATD模塊
5、HCS12的ECT模塊
原理:
1、紅外發(fā)射管,將紅外線信號(hào)發(fā)射出去,當(dāng)遇到遮擋物是,會(huì)反射回來(lái)。如果當(dāng)部分為黑色時(shí),則不會(huì)發(fā)射回來(lái)(黑色能吸收光線,紅外線在遇到黑色遮擋物時(shí),被吸收)。接收管在接收到反射的紅外線時(shí),其兩端的電阻發(fā)生變化,從而可以輸出不同的電壓值,最后根據(jù)這些電壓值來(lái)識(shí)別路徑。
2、電壓比較器能將連續(xù)量轉(zhuǎn)變成開(kāi)關(guān)量,在大于設(shè)定的閾值時(shí),輸出高電平,小于設(shè)定的閾值時(shí),則輸出低電平。
3、ADC能將模擬量轉(zhuǎn)換成計(jì)算機(jī)可以識(shí)別的數(shù)字量,可是自己對(duì)這些數(shù)字信號(hào)進(jìn)行處理,對(duì)路徑信息進(jìn)行識(shí)別。
方案:
1、離散型路徑識(shí)別算法。
將紅外接收管輸出的電壓信號(hào)通過(guò)電壓比較器進(jìn)行電壓比較,輸出一個(gè)開(kāi)關(guān)量,HCS12的IO讀取電壓比較器輸出的開(kāi)關(guān)量。安裝若干個(gè)光電管排成一排,并且同時(shí)讀取信息,當(dāng)與發(fā)射管連接的IO口輸入一個(gè)0值時(shí),則判斷黑色軌道在該光電接收管下,通過(guò)一定的算法即可求出黑色軌道和小車(chē)的偏移角度。
優(yōu)點(diǎn):簡(jiǎn)單易行。
缺點(diǎn):
a.存在檢測(cè)盲區(qū),即在接收管之間的區(qū)域。
b.道路信息為離散值,通過(guò)道路信息經(jīng)過(guò)控制算法得到的控制信息為階躍的而非連續(xù)的控制量,這對(duì)小車(chē)的穩(wěn)定影響。
2、連續(xù)型路徑識(shí)別算法。
將紅外接收管輸出的電壓信號(hào)經(jīng)過(guò)AD轉(zhuǎn)換,等到數(shù)字量的的電壓信號(hào)。通過(guò)對(duì)這些數(shù)字亮的處理可以得到近似于連續(xù)的道路信息。
優(yōu)點(diǎn):路徑信息為連續(xù),路徑信息更加精確。
缺點(diǎn):
a.數(shù)據(jù)處理算法實(shí)現(xiàn)較為困難。
b.因?yàn)楣怆娊邮展鼙旧韰?shù)的不同,在同樣條件下,輸出的電壓可能有所不同,這對(duì)數(shù)字信號(hào)的處理帶來(lái)難度。
方案選擇:因?yàn)槭浅醮谓佑|路徑識(shí)別算法,為了小車(chē)能穩(wěn)定的行駛,于是選擇了較為容易實(shí)現(xiàn)的離散路徑識(shí)別算法。
說(shuō)明:
1、光電接收管為16個(gè),在離前輪Hmm的距離排成一排,同時(shí)檢測(cè)道路信息,每個(gè)光電管之間的距離為15mm。
2、16個(gè)光電管分別和HCS12的PORTB口和PORTE口連接。
3、檢測(cè)時(shí)間間隔為10MS。
車(chē)輪和接收管的車(chē)子垂直距離為500mm。
4、變量iRoutPlace存放路徑信息。
5、數(shù)組iPLace存放路徑位置。
6、數(shù)組iplaceAngle存放方向角度。
7、位置信息數(shù)據(jù):
當(dāng)某位紅外接收管檢測(cè)到黑線時(shí),則通過(guò)比較器,該位輸出為0,未檢測(cè)到的則為1。
iPLace[28]={0x7fff,0x3fff,0xbfff,0x9fff,0xdfff,0xcfff,0xefff,
0xf7ff,0xf3ff,0xfbff,0xf9ff,0xfdff,0xfcff,0xfeff,
0xff7f,0xff3f,0xffbf,0xff9f,0xffdf,0xffcf,0xffef,
0xfff7,0xfff3,0xfffb,0xfff9,0xfffd,0xfffc,0xfffe}
8、位置與偏移角的關(guān)系。
通過(guò)C程序計(jì)算出來(lái)。程序如下:
#include
#include
void main()
{
int i;
long double h,n;
n=0.0;
h=500.0;
for(i=0;i<16;i++)
{
printf("%d--%lf--",i,atan((15.0*n)/h));
printf("%lfn",((atan((15.0*n)/h))*180.0)/3.14);
n++;
}
}
運(yùn)行結(jié)果:
位置-弧度角--角度
0--0.000000--0.000000
1--0.029991--1.719230
2--0.059928--3.435372
3--0.089758--5.145373
4--0.119429--6.846244
5--0.148890--8.535093
6--0.178093--10.209149
7--0.206992--11.865795
8--0.235545--13.502579
9--0.263712--15.117239
10--0.291457--16.707714
11--0.318748--18.272153
12--0.345556--19.808919
13--0.371856--21.316590
14--0.397628--22.793961
15--0.422854--24.240034
通過(guò)上表可以近似為,每偏移一個(gè)位置,角度增加1°。
9、角度信息:
iplaceAngle[]={-13,-12,-11,-10,-9,-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,5,5,6,7,8,9,10,11,12,13}
CODE:
#include
#include
#pragma LINK_INFO DERIVATIVE "mc9s12xs128"
//===========================================================//
//光電管離散路徑識(shí)別算法
//PORTB和PORTE接電壓比較器的輸出端
//16位模數(shù)遞減計(jì)數(shù)器進(jìn)行計(jì)數(shù)
//author: Yangtze
//time:2009/4/19/15:15:45
//===========================================================//
#define iSampling 10//路徑采樣時(shí)間設(shè)置
int iRoutPlace; //路徑位置臨時(shí)變量
int Angle; //角度
int iPLace[28]={0x7fff,0x3fff,0xbfff,0x9fff,0xdfff,0xcfff,0xefff, //路徑位置數(shù)組
0xf7ff,0xf3ff,0xfbff,0xf9ff,0xfdff,0xfcff,0xfeff,
0xff7f,0xff3f,0xffbf,0xff9f,0xffdf,0xffcf,0xffef,
0xfff7,0xfff3,0xfffb,0xfff9,0xfffd,0xfffc,0xfffe};
int iplaceAngle[]={-13,-12,-11,-10,-9,-8, //軌道偏移角度
-7,-6,-5,-4,-3,-2,
-1,0,1,2,3,5,5,6,
7,8,9,10,11,12,13};
void Init_MDC(void)
{
MCCTL=0xDF;//設(shè)定模數(shù)計(jì)數(shù)器工作方式,中斷使能,計(jì)數(shù)器使能
//分頻系數(shù)為16
MCCNT=1000;//定時(shí)器賦初值 (1/16M)*16*1000= 1ms
}
void pllclk(void) //16MHz
{
SYNR=0x01; //PLLCLK =2*OSCCLK*(SYNR + 1)/(REFDV + 1)
REFDV=0x01;
CLKSEL=0x80; //選定PLL時(shí)鐘
}
void IO_Init() //PORTB和PORTE設(shè)置為輸入口
{
DDRB=0X00;
DDRE=0X00;
}
void main(void)
{
pllclk();
Init_PT0_ICapture();
IO_Init();
EnableInterrupts;
for(;;) {}
}
#pragma CODE_SEG __NEAR_SEG NON_BANKED
void interrupt 26 MDC_ISR(void)
{
static unsigned int count=0;
count++;
if(count==iSampling) //100MS讀取一次
{
iRoutPlace=PORTB; //將IO口讀取到的信息存入變量iRoutPlace中,B口在高8為,E口在底8位
iRoutPlace=iRoutPlace<<8;
iRoutPlace|=PORTE;
for(i=0;i<28;i++) //通過(guò)循環(huán)比較,取得黑色軌道與中軸的偏移角度
{
if(iPLace ==iRoutPlace)
{
Angle=iplaceAngle ;
}
}
}
MCFLG = 0x80; //清中斷標(biāo)志位
}
后記:
該程序僅僅為黑色軌道的路徑識(shí)別程序,通過(guò)紅外接收管檢測(cè)黑色路徑,然后,輸出位置偏移的角度,并沒(méi)有控制程序。不過(guò)如果得到了偏移角度,控制程序就很好處理了。直接將角度和相應(yīng)的PWM占空比進(jìn)行比較,輸出對(duì)應(yīng)角度的占空比,以控制舵機(jī)。
如果加上舵機(jī)控制程序,就能形成了以個(gè)開(kāi)環(huán)的自控控制系統(tǒng),控制算法為模糊控制算法。很多人都說(shuō)模糊控制算法很難理解,很不好用,可是從這個(gè)程序上看來(lái),模糊控制算法還是挺簡(jiǎn)單的.只要根據(jù)自己的經(jīng)驗(yàn)來(lái)設(shè)計(jì)一些控制量的表格,通過(guò)檢測(cè)到路徑信息然后和控制量的表格進(jìn)行對(duì)比,輸出對(duì)應(yīng)的控制量。這就是模糊控制算法的思路。當(dāng)然這也僅僅只是模糊控制算法的一點(diǎn)思路,有很多不足。
以上程序僅僅只是一個(gè)前期的使用版本,還有很多缺陷有待改進(jìn)。缺陷如下:
1、沒(méi)有發(fā)射管的驅(qū)動(dòng)程序,默認(rèn)為發(fā)射管一直在發(fā)射。這樣的結(jié)果紅外接收管在檢測(cè)信息的時(shí)候,會(huì)受到很大的干擾,而且功耗很大,對(duì)整個(gè)系統(tǒng)的電流供應(yīng)和功率輸出有很大影響。
改進(jìn)方法:在用從一定方向逐個(gè)啟動(dòng)的方式進(jìn)行檢測(cè)。假如有4對(duì)紅外發(fā)射接收管ABCD。先將D管的發(fā)射管開(kāi)啟,ABC發(fā)射管均關(guān)閉,讀取D接收管的信息。然后在開(kāi)去C發(fā)射管,關(guān)閉ABD發(fā)射管,讀取C接收管的信息。依次讀取每一個(gè)接收管的信息。以ns級(jí)的速度讀取,可以近似的認(rèn)為接收管是同時(shí)讀取信息的。
2、沒(méi)有進(jìn)行濾波處理。在讀取道路信息的時(shí)候,可能會(huì)受到多方面的干擾,為了取得更加接近真實(shí)值的信息,有必要進(jìn)行濾波處理,將干擾噪聲剔除。
改進(jìn)方法:在用多次讀取,取平均值的方法可以在一定程度上減小噪聲干擾。
3、位置處理和角度輸出的時(shí)候沒(méi)有按照經(jīng)驗(yàn)進(jìn)行適當(dāng)?shù)奶幚?,比如說(shuō),在偏移角度很小的時(shí)候,可以近似的認(rèn)為是在直線上行駛,直接輸出0°角,讓小車(chē)能快速的行駛。
4、上述程序中的采樣周期是隨意設(shè)定的,沒(méi)有科學(xué)依據(jù),在設(shè)定采樣周期的時(shí)候,一定要通過(guò)計(jì)算出最優(yōu)的周期,這樣才能保證小車(chē)行駛的穩(wěn)定性和前瞻性。
暫時(shí)找到這么多缺陷,更多的缺陷以及改進(jìn)還得在實(shí)際運(yùn)用中去發(fā)現(xiàn),去尋求解決的方法。
完成這個(gè)程序,讓我也學(xué)到了很多?,F(xiàn)總結(jié)如下:
1、重視源代碼的保存。C語(yǔ)言具有很強(qiáng)的移植性,在不同的平臺(tái)上尚且能進(jìn)行移植,在同一個(gè)平臺(tái)上就更容易移植了。我上邊寫(xiě)的這寫(xiě)程序,其實(shí)很大部分都是之前ECT_SPEED程序里邊寫(xiě)過(guò),而我這次在編寫(xiě)程序的時(shí)候,根本不用重新編寫(xiě),直接調(diào)用ECT_SPEED里邊的程序就可以完成任務(wù)。
我這個(gè)程序調(diào)用ECT_SPEED文件里的函數(shù)有:Init_MDC(), pllclk(),如果在大型的軟件開(kāi)發(fā)項(xiàng)目中,這樣將會(huì)大大縮短程序的開(kāi)發(fā)周期,降低程序的開(kāi)發(fā)成本。
2、重視程序說(shuō)明文檔的編寫(xiě)。這幾天的編程練習(xí)中,在編程之前,認(rèn)真思考,將整個(gè)程序的算法,流程都考慮清楚之后,然后將其通過(guò)說(shuō)明文檔的形式寫(xiě)出來(lái)。這樣的好處是,使我在程序的編寫(xiě)的過(guò)程中,能一氣呵成,不再像以前那樣,一個(gè)稍微大一點(diǎn)的程序編寫(xiě)下來(lái),還沒(méi)編寫(xiě)完畢,就已經(jīng)原來(lái)的思路忘記了。他的另一個(gè)好處就是方便以后閱讀程序。
3、編寫(xiě)程序的時(shí)候,一定要多想,而且從不同的角度去尋找解決問(wèn)題的方法。在編寫(xiě)這個(gè)程序之前,在我的意識(shí)當(dāng)中,是知道用一排紅外檢測(cè)管是可以檢測(cè)出黑色軌道的,可是在處理軌道位置的時(shí)候,一直都不知道怎么處理,怎么才能讓單片機(jī)知道黑線在那個(gè)地方。想了好久,才從角度的這個(gè)方向去理解,最終找到了位置處理的方法。
4、一定要重視循環(huán),盡可能多的使用循環(huán)。在上述程序的對(duì)比中,我第一感覺(jué)是用switch語(yǔ)句進(jìn)行比較,當(dāng)輸入和whitch中的某一個(gè)case吻合時(shí),執(zhí)行相應(yīng)的語(yǔ)句??墒窃谶@樣的情況下,得寫(xiě)28個(gè)case語(yǔ)句,并寫(xiě)與之對(duì)應(yīng)輸出語(yǔ)句。這樣會(huì)大大增加程序的體積,這在單片機(jī)內(nèi)存空間很少的情況下,造成的錯(cuò)誤是致命的。
為了節(jié)省存儲(chǔ)空間,就開(kāi)始尋求其他方法來(lái)解決這個(gè)問(wèn)題。這樣我想到了冒泡程序中逐次對(duì)比的方法。我這個(gè)程序的問(wèn)題也可以用多次個(gè)循環(huán)來(lái)實(shí)現(xiàn)次比較啊,如果比較結(jié)果為真,則執(zhí)行相應(yīng)的語(yǔ)句。
于是就得到了這個(gè)比較程序:
for(i=0;i<28;i++) //通過(guò)循環(huán)比較,取得黑色軌道與中軸的偏移角度
{
if(iPLace ==iRoutPlace)
{
Angle=iplaceAngle ;
}
}
1、紅外光電發(fā)射接收管
2、電壓比較器
3、HCS12的IO口
4、HCS12的ATD模塊
5、HCS12的ECT模塊
原理:
1、紅外發(fā)射管,將紅外線信號(hào)發(fā)射出去,當(dāng)遇到遮擋物是,會(huì)反射回來(lái)。如果當(dāng)部分為黑色時(shí),則不會(huì)發(fā)射回來(lái)(黑色能吸收光線,紅外線在遇到黑色遮擋物時(shí),被吸收)。接收管在接收到反射的紅外線時(shí),其兩端的電阻發(fā)生變化,從而可以輸出不同的電壓值,最后根據(jù)這些電壓值來(lái)識(shí)別路徑。
2、電壓比較器能將連續(xù)量轉(zhuǎn)變成開(kāi)關(guān)量,在大于設(shè)定的閾值時(shí),輸出高電平,小于設(shè)定的閾值時(shí),則輸出低電平。
3、ADC能將模擬量轉(zhuǎn)換成計(jì)算機(jī)可以識(shí)別的數(shù)字量,可是自己對(duì)這些數(shù)字信號(hào)進(jìn)行處理,對(duì)路徑信息進(jìn)行識(shí)別。
方案:
1、離散型路徑識(shí)別算法。
將紅外接收管輸出的電壓信號(hào)通過(guò)電壓比較器進(jìn)行電壓比較,輸出一個(gè)開(kāi)關(guān)量,HCS12的IO讀取電壓比較器輸出的開(kāi)關(guān)量。安裝若干個(gè)光電管排成一排,并且同時(shí)讀取信息,當(dāng)與發(fā)射管連接的IO口輸入一個(gè)0值時(shí),則判斷黑色軌道在該光電接收管下,通過(guò)一定的算法即可求出黑色軌道和小車(chē)的偏移角度。
優(yōu)點(diǎn):簡(jiǎn)單易行。
缺點(diǎn):
2、連續(xù)型路徑識(shí)別算法。
將紅外接收管輸出的電壓信號(hào)經(jīng)過(guò)AD轉(zhuǎn)換,等到數(shù)字量的的電壓信號(hào)。通過(guò)對(duì)這些數(shù)字亮的處理可以得到近似于連續(xù)的道路信息。
優(yōu)點(diǎn):路徑信息為連續(xù),路徑信息更加精確。
缺點(diǎn):
方案選擇:因?yàn)槭浅醮谓佑|路徑識(shí)別算法,為了小車(chē)能穩(wěn)定的行駛,于是選擇了較為容易實(shí)現(xiàn)的離散路徑識(shí)別算法。
說(shuō)明:
1、光電接收管為16個(gè),在離前輪Hmm的距離排成一排,同時(shí)檢測(cè)道路信息,每個(gè)光電管之間的距離為15mm。
2、16個(gè)光電管分別和HCS12的PORTB口和PORTE口連接。
3、檢測(cè)時(shí)間間隔為10MS。
4、變量iRoutPlace存放路徑信息。
5、數(shù)組iPLace存放路徑位置。
6、數(shù)組iplaceAngle存放方向角度。
7、位置信息數(shù)據(jù):
8、位置與偏移角的關(guān)系。
通過(guò)C程序計(jì)算出來(lái)。程序如下:
#include
#include
void main()
{
int i;
long double h,n;
n=0.0;
h=500.0;
for(i=0;i<16;i++)
{
}
}
運(yùn)行結(jié)果:
位置-弧度角--角度
0--0.000000--0.000000
1--0.029991--1.719230
2--0.059928--3.435372
3--0.089758--5.145373
4--0.119429--6.846244
5--0.148890--8.535093
6--0.178093--10.209149
7--0.206992--11.865795
8--0.235545--13.502579
9--0.263712--15.117239
10--0.291457--16.707714
11--0.318748--18.272153
12--0.345556--19.808919
13--0.371856--21.316590
14--0.397628--22.793961
15--0.422854--24.240034
通過(guò)上表可以近似為,每偏移一個(gè)位置,角度增加1°。
9、角度信息:
iplaceAngle[]={-13,-12,-11,-10,-9,-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,5,5,6,7,8,9,10,11,12,13}
CODE:
#include
#include
#pragma LINK_INFO DERIVATIVE "mc9s12xs128"
//===========================================================//
//光電管離散路徑識(shí)別算法
//PORTB和PORTE接電壓比較器的輸出端
//16位模數(shù)遞減計(jì)數(shù)器進(jìn)行計(jì)數(shù)
//author: Yangtze
//time:2009/4/19/15:15:45
//===========================================================//
#define iSampling 10//路徑采樣時(shí)間設(shè)置
int iRoutPlace;
int Angle;
int iPLace[28]={0x7fff,0x3fff,0xbfff,0x9fff,0xdfff,0xcfff,0xefff,
int iplaceAngle[]={-13,-12,-11,-10,-9,-8,
void Init_MDC(void)
{
}
void pllclk(void) //16MHz
{
}
void IO_Init()
{
}
void main(void)
{
}
#pragma CODE_SEG __NEAR_SEG NON_BANKED
void interrupt 26 MDC_ISR(void)
{
}
評(píng)論