一、 綜述: a) 項目名稱:小車自動走迷宮; b) 小組成員: i. 周杰:負(fù)責(zé)總體規(guī)劃,及ARM編程; ii. 宋大成:負(fù)責(zé)車輪驅(qū)動; iii. 陳瀟:負(fù)責(zé)紅外驅(qū)動; c) 小車圖片: MicroMouse615: MicroMouse120: 二、 項目介紹: 電腦鼠走迷宮競賽的目的是制作一個微型機器人,它能在最短的時間內(nèi)穿越迷宮到達(dá)終點。參賽的機機器人稱為“電腦鼠”,將電腦鼠放入迷宮并啟動操作的人稱為“操作員”。 電腦鼠的基本功能是從起點開始走到終點,這個過程稱為一次“運行”,所花費的時間稱為“運行時間”。從終點回到起點所花費的時間不計算在運行時間內(nèi)。從電腦鼠的第一次激活到每次運行開始,這段期間所花費的時間稱為“迷宮時間”。如果電腦鼠在比賽時需要手動輔助,這個動作稱為“碰觸”。競賽使用這三個參數(shù),從速度﹑求解迷宮的效率和電腦鼠的可靠性三個方面來進(jìn)行評分。器人稱為“電腦鼠”,將電腦鼠放入迷宮并啟動操作的人稱為“操作員”。 在G02小組的工作中,基本完成了電腦鼠的驅(qū)動部分和算法部分:電腦鼠可以進(jìn)行直線行走、90度左轉(zhuǎn)、90度右轉(zhuǎn)和180度后轉(zhuǎn);能準(zhǔn)確監(jiān)測左前右三個方向的擋板,能準(zhǔn)確判斷左右間距是否恰當(dāng);能進(jìn)行調(diào)距運動,以保持與左右擋板的距離;能簡單判斷通路,并計算記憶合適通路;并按照通路完成迷宮行走。 但是,由于某些原因,小車的沒有取得完美的效果:由于電機轉(zhuǎn)速控制不當(dāng),小車直線行走效果不佳(參看第條);左轉(zhuǎn)右轉(zhuǎn)不夠準(zhǔn)確,只能依靠調(diào)整函數(shù)補償;算法不夠優(yōu)秀,正在探究更好的算法。這些問題都在努力克服中,我們不會因為檢查完畢就放棄小車的調(diào)試。 三、 項目整體結(jié)構(gòu): MicroMouse102 電腦老鼠,采用美國LuminaryMicro 公司生產(chǎn)的32 位ARM CortexM3處理器LM3S102,控制和檢測紅外傳感器;主CPU 根據(jù)檢測到的傳感信號,控制電機驅(qū)動電路調(diào)整行走路徑,直到到達(dá)終點。 四、 硬件部分介紹: LED 電路 電腦鼠有5 個獨立的LED,通過LM3S 系統(tǒng)單片機的GPIO 口直接控制,如圖 1.6 所示。電路采用了I/O 口灌電流的驅(qū)動方式來驅(qū)動LED,LM3S 系統(tǒng)單片機的灌電流為2~8mA(可配置),所以不需要驅(qū)動就可以點亮LED。GPIO 引腳輸出高電平時LED 熄滅,低電平時LED 點亮。 電機驅(qū)動電路 電機采用直流減速電機,最高輸出轉(zhuǎn)速為800 轉(zhuǎn)/分鐘,工作電壓為DC3V。電機驅(qū)動 電路采用專用的單相直流電動機橋式驅(qū)動芯片。 車速檢測電路 車速檢測用于檢測并記錄車體運行的路徑,通過車速檢測記錄車體做迷宮的坐標(biāo),同 時也起到控制車速和保持左右雙輪的速度一致。 檢測原理:在左輪和右輪的內(nèi)則都貼有的光電碼盤,碼盤由兩種顏色組成白色和黑色。 紅外發(fā)射管安裝在車輪光電檢測碼盤的檢測區(qū)域,當(dāng)紅外發(fā)射與接收管正對著黑色邊時, 紅外線沒有被反射,接收管的電阻很大;當(dāng)紅外發(fā)射與接收管正對著白色邊時,紅外線被 反射,接收管的電阻很小。 紅外檢測電路 紅外檢測電路是用于迷宮擋板的檢測,分為左側(cè)、右側(cè)、前方三個方向,三個方向的 檢測原理相同,某一個方向的檢測電路。 CPU 及晶振電路 電腦鼠的單片機、晶體振蕩器和LDO輸出原理如圖所示。該單片機選用LM3S102 微處理器。 五、 軟件部分介紹: 一體化紅外接收頭工作原理 一體式紅外線接收傳感器IRM8601S,它內(nèi)部集成自動增益控制電路、帶通濾波電路、 解碼電路及輸出驅(qū)動電路。當(dāng)連續(xù)收到38KHz 的紅外線信號時,將產(chǎn)生脈寬10ms 左右的 低電平。如果沒有收到信號,便立即輸出高電平。Send 為發(fā)射控制端,高 電平時發(fā)射38KHz 的紅外信號。Out 為接收輸出端,低電平表示收到信號。 檢測障礙物的軟件設(shè)計 根據(jù)接收頭是否檢測到經(jīng)過反射的紅外線信號,就可以判斷是否存在障礙物。由于接 收頭檢測到信號時只產(chǎn)生一個負(fù)脈沖,所以只需要在檢測時使能紅外線發(fā)射,一次檢測結(jié) 束后使能無效,程序設(shè)計參考流程圖如圖2.5 所示。 接收頭有一定的 響應(yīng)時間 開始發(fā)送38KHz 的紅外線 迷宮擋板檢測 調(diào)制信號產(chǎn)生 本設(shè)計中采用定時器1 產(chǎn)生38KHz 的調(diào)制信號,由PB5 輸出,該端口連接到圖2.3 中 的Pulse 端口。在中斷中翻轉(zhuǎn)PB5 輸出信號,所以要產(chǎn)生頻率為f 的脈沖,定時器的頻率 要為2f。在本設(shè)計中要產(chǎn)生38KHz 的頻率,定時器中斷頻率為76KHz。 程序清單 3.1 為定時器1 的初始化函數(shù),程序清單 3.2 為中斷服務(wù)函數(shù),在這里翻轉(zhuǎn) PB5 口輸出狀態(tài)。 程序清單 3.1 定時器1 初始化 void PULSEIni(void) { GPIODirModeSet(GPIO_PORTB_BASE, SEND | PULSE, GPIO_DIR_MODE_OUT); // 設(shè)置為輸 出 GPIOPinWrite( GPIO_PORTB_BASE,SEND | PULSE,0); // 紅外線初始時停止發(fā)射 SysCtlPeripheralEnable( SYSCTL_PERIPH_TIMER1 ); // 使能定時器1 外設(shè) TimerConfigure(TIMER1_BASE, TIMER_CFG_32_BIT_PER); // 設(shè)置定時器1 為周期觸發(fā) TimerLoadSet(TIMER1_BASE, TIMER_A, SysCtlClockGet()/76000); // 設(shè)置定時器裝載值 TimerIntEnable(TIMER1_BASE, TIMER_TIMA_TIMEOUT); TimerEnable(TIMER1_BASE, TIMER_A); IntEnable(INT_TIMER1A); } 程序清單 3.2 定時器1 服務(wù)函數(shù) void Timer1A_ISR(void) { TimerIntClear(TIMER1_BASE, TIMER_TIMA_TIMEOUT); // 清除定時器1 中斷 GPIOPinWrite(GPIO_PORTB_BASE, PULSE,GPIOPinRead(GPIO_PORTB_BASE, PULSE) ^ PULSE); // 翻轉(zhuǎn)GPIO B5 端口 } 抗干擾處理 紅外線在空氣中傳播和反射受外界的干擾,如果測量距離剛好處在能夠檢測到信號的 臨界狀態(tài),保持距離不變,傳感器輸出信號也可能不確定。這樣就需要在軟件中進(jìn)行抗干 擾處理。參考程序如程序清單3.3 所示。 程序清單3.3 抗干擾處理程序 GPIOPinWrite( GPIO_PORTB_BASE,SEND , SEND); // 發(fā)送脈沖 Delay(150); // 延時 for(i=0,j=0;i<10;i++) // 檢測接收信號 { if(GPIOPinRead(GPIO_PORTA_BASE, OUT_L)==0) j++; } GPIOPinWrite( GPIO_PORTB_BASE,SEND , ~SEND); // 停止發(fā)送 if(j>5) // 左邊存在擋板 { } else // 左邊存在支路 { } 圖3.1 為抗干擾程序在Micromouse 中運行后用邏輯分析儀抓到的波形圖,Pulse 為 38KHz 的輸出信號,Send 高電平有效,有效時發(fā)送紅外線脈沖,OUT 為一體化接收頭輸 …… …… 出端,該圖所示為接收頭探測到障礙物,軟件在Send 信號無效(下降沿)前完成檢測OUT 輸出信號,從圖中可以看出,此時正處于OUT 有效信號的中間,所以軟件里延時參數(shù)能 保證正確檢測到信號。 圖3.1 傳感器檢測波形圖 軟件設(shè)計參考 為用一組紅外實現(xiàn)兩組參數(shù)(是否存在擋板和是否太接近擋板)的檢測流程圖。在Micromouse 中,用到了三組(左、前、右)反射式紅外檢測傳感器,左邊和右邊的傳感器各自都需要檢測兩組參數(shù),而前方的傳感器只需要探測有無擋板,存在擋板就必須根據(jù)策略轉(zhuǎn)換行進(jìn)方向,若不存在就可以繼續(xù)前進(jìn)。如圖3.3 所示為Micromouse 紅外檢測的程序設(shè)計流程圖。紅外檢測參考程序見程序清單 3.4 所示,該程序中使用了五個LED 用來指示傳感器檢測的狀態(tài),由于這幾個LED 硬件上連接到JTAG,關(guān)于如何切換GPIO和JTAG功能參見6 使用JTAG 引腳作GPIO。 此頻率僅作為參考,要根據(jù)實際檢測距離來確定。結(jié)合可調(diào)電阻R1 變可以實現(xiàn)擋板和防碰撞的檢測。 程序清單 3.4 Micromouse 紅外檢測函數(shù)(見附錄) 電機的調(diào)速 電機的調(diào)速 直流電機的轉(zhuǎn)速控制在本設(shè)計中通過PWM來控制,LM3S102 單片機則剛有兩路PWM 輸出,非常適合用于控制兩個電機的轉(zhuǎn)速。 兩路PWM 是LM3S102 通用定時器0(Timer0)的三種工作模式之一,16 位PWM 模 式。該模式是將一個32 位的定時器,折分成兩個16 位的定時器TimerA 和TimerB。這些 定時器為計數(shù)寄存器(GPTMTnR)遞減計數(shù),遞減到0 時自動加載預(yù)裝載值(GPTMTnILR)。 當(dāng)然預(yù)裝載值也是由用戶設(shè)定,該直也就決定了定時周期,也即PWM 的輸出周期。 當(dāng)計數(shù)器的值與預(yù)裝載值相等時,輸出PWM 信號有效,當(dāng)計數(shù)器的值與匹配寄存器 (GPTMnMATCHR)的值相等時,輸出PWM 信號失效。通過軟件可以設(shè)定PWM 輸?shù)男?/font> 號有效和信號無效的電平狀態(tài)。當(dāng)GPTMCTL 寄存器的TnPWML 位值為0 時,信號有效 為高電平,信號無效為低電平;TnPWML 位值為1 時,則反之。如圖 4.1 所示。 輸出信號 計數(shù) 0x411A 0xC350 TnPWML=0 TnPWML=1 TnEN置位 GPTMTnR=GPTMnMR GPTMTnR=GPTMnMR 時間 圖 4.1 16 位PWM 模式輸出 占空比的約定:占空比為在一個周期內(nèi),輸出有信號有效電平占整個周期時間的比率。 在這里為以統(tǒng)一軟件控制的約定,用戶API 函數(shù)輸入的占空比值越大,電機轉(zhuǎn)速越快,正 向運行和反向運行都一樣。 為了簡化占空比輸出的計算,將計數(shù)寄存器與匹配寄存器值相等時,輸出的電平信號 為驅(qū)動電機的有效信號。例如將PWM 周期時間設(shè)定為60000 個時鐘節(jié)拍,需要輸出驅(qū)動 電機的占空比為75%,則設(shè)置匹配寄存器值為75*6000。 由于電機的轉(zhuǎn)向不一樣,所以電機驅(qū)動的有效電平也需要調(diào)整,通過控制TnPWML 實現(xiàn)。 2 程序設(shè)計 Timer0 的兩路16 定時器TimerA 和TimerB 的PWM 輸出引腳分別為PB0 和PB6,PB0 和PB6 分別控制左輪和右輪驅(qū)動器TA7291S 的IN1 引腳,而它們的IN2 引腳分別由GPIO 輸出的PA4 和PA5 控制。 左輪的控制函數(shù)如程序清單 4.1 所示。 該函數(shù)的第1 個參數(shù)sel 為選擇輪子的控制方式:0 為停止,1 為輪子向前,2 為輪子 向后;percen 參數(shù)為占空比,其最大值為99,最小值為1,對于輪子的停止控制該參數(shù)無 效。 程序清單 4.1 左輪控制函數(shù) void LeftWheelRun(int sel,unsigned char percen) { switch(sel) { /*輪子停止轉(zhuǎn)動*/ case 0: TimerDisable(TIMER0_BASE,TIMER_A); // 禁止定時器 GPIOPinWrite(GPIO_PORTA_BASE,LWC2,0xff); // 控制引腳輸出高電平 GPIODirModeSet(GPIO_PORTB_BASE, LWC1, GPIO_DIR_MODE_OUT); // GPIO 輸出 GPIOPinWrite(GPIO_PORTB_BASE,LWC1, 0xff); // GPIO 輸出高電平 break; /*左輪向前*/ case 1: GPIOPinWrite(GPIO_PORTA_BASE,LWC2, 0xff); // PA4 輸出高電平 TimerControlLevel(TIMER0_BASE,TIMER_A,true); // PWM 有效電平方向 GPIODirModeSet(GPIO_PORTB_BASE, LWC1, GPIO_DIR_MODE_HW); // PWM 輸出 TimerMatchSet(TIMER0_BASE,TIMER_A,percen*600); // 設(shè)置占空比 TimerEnable(TIMER0_BASE,TIMER_A); // 使能定時器 break; /*左輪向后*/ case 2: GPIOPinWrite(GPIO_PORTA_BASE,LWC2, 0); // PA4 輸出低電平 TimerControlLevel(TIMER0_BASE,TIMER_A,false); // PWM 有效電平方向 GPIODirModeSet(GPIO_PORTB_BASE, LWC1, GPIO_DIR_MODE_HW); // PWM 輸出 TimerMatchSet(TIMER0_BASE,TIMER_A,percen*600); // 設(shè)置占空比 TimerEnable(TIMER0_BASE,TIMER_A); // 使能定時器 break; } } 右輪的控制函數(shù)如程序清單 4.2 所示。 該函數(shù)的第1 個參數(shù)sel 為選擇輪子的控制方式:0 為停止,1 為輪子向前,2 為輪子 向后;percen 參數(shù)為占空比,其最大值為99,最小值為1,對于輪子的停止控制該參數(shù)無 效。 程序清單 4.2 右輪控制函數(shù) void RightWheelRun(int sel,unsigned char percen) { switch(sel) { /*輪子停止轉(zhuǎn)動*/ case 0: TimerDisable(TIMER0_BASE,TIMER_B); // 禁止定時器 GPIOPinWrite(GPIO_PORTA_BASE,RWC2,0xff); // 控制引腳輸出高電平 GPIODirModeSet(GPIO_PORTB_BASE, RWC1, GPIO_DIR_MODE_OUT); // GPIO 輸出 GPIOPinWrite(GPIO_PORTB_BASE,RWC1,0xff); // GPIO 輸出高電平 break; /*右輪向后*/ case 2: GPIOPinWrite(GPIO_PORTA_BASE,RWC2, 0xff); // PA4 輸出高電平 TimerControlLevel(TIMER0_BASE,TIMER_B,true); // PWM 有效電平方向 GPIODirModeSet(GPIO_PORTB_BASE, RWC1, GPIO_DIR_MODE_HW); // PWM 輸出 TimerMatchSet(TIMER0_BASE,TIMER_B,percen*600); // 設(shè)置占空比 TimerEnable(TIMER0_BASE,TIMER_B); // 使能定時器 break; /*右輪向前*/ case 1: GPIOPinWrite(GPIO_PORTA_BASE,RWC2, 0); // PA4 輸出低電平 TimerControlLevel(TIMER0_BASE,TIMER_B,false); // PWM 有效電平方向 GPIODirModeSet(GPIO_PORTB_BASE, RWC1, GPIO_DIR_MODE_HW); // PWM 輸出 TimerMatchSet(TIMER0_BASE,TIMER_B,percen*600); // 設(shè)置占空比 TimerEnable(TIMER0_BASE,TIMER_B); // 使能定時器 break; } } 需要注意的是,當(dāng)PWM 信號禁止后,其輸出引腳的電平狀態(tài)是保持靜止時的狀態(tài)(可 能為低電平也可能為高電平),導(dǎo)致電機可能不能停止,所以在制停電機時,需要將PWM 引腳改為GPIO 輸出,并且出高電平,使電機剎車停止。 定時器PWM 初始化函數(shù)如程序清單 4.3 所示。 程序清單 4.3 定時器PWM 初始化 void PWMTimer0AIni(void) { SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0); // 使能定時器0 模 塊 GPIODirModeSet(GPIO_PORTB_BASE, LWC1|RWC1 , GPIO_DIR_MODE_OUT); /* 控制引腳輸出*/ GPIOPinWrite(GPIO_PORTB_BASE, LWC1|RWC1 , 0xff); // GPIO 輸出高電 平 GPIODirModeSet(GPIO_PORTA_BASE, LWC2|RWC2 , GPIO_DIR_MODE_OUT); // 控制引腳輸出 GPIOPinWrite(GPIO_PORTA_BASE, LWC2|RWC2 , 0xff); // GPIO 輸出高電 平 /* 定時器配置*/ TimerConfigure(TIMER0_BASE,TIMER_CFG_16_BIT_PAIR |TIMER_CFG_A_PWM|TIMER_CFG_B_PWM); // 16 位PWM 輸出 TimerControlLevel(TIMER0_BASE,TIMER_A,false); //有效信號為低電 平 TimerControlLevel(TIMER0_BASE,TIMER_B,false); TimerLoadSet(TIMER0_BASE,TIMER_A,60000); // 設(shè)定PWM 頻率 TimerLoadSet(TIMER0_BASE,TIMER_B,60000); } Micromouse 車速檢測 車速檢測程序設(shè)計 本設(shè)計中選用了LM3S102 的PA0 和PB1 分別檢測左輪和右輪的下降沿的脈沖個數(shù), 為了快速向應(yīng)檢測信號,使用了下降沿觸發(fā)中斷。LM3S102 單片機的特點,任何一個GPIO 引腳都可以配置為中斷輸入,并且可以作任意設(shè)定為高電平觸發(fā)、低電平觸發(fā)、下降沿觸 發(fā)、上升沿觸發(fā)和上升或下降沿觸發(fā)5 種模式。本應(yīng)用中使用下降沿觸發(fā),其初始化如程 序清單 5.1 所示。 程序清單 5.1 輪子脈沖檢測初始化 void WheelPulseIni(void) { // 配置引腳為輸入 GPIODirModeSet(GPIO_PORTA_BASE, PULSE_R, GPIO_DIR_MODE_IN); GPIODirModeSet(GPIO_PORTB_BASE, PULSE_L, GPIO_DIR_MODE_IN); // 配置引腳下降沿觸發(fā)中斷 GPIOIntTypeSet(GPIO_PORTA_BASE,PULSE_R,GPIO_FALLING_EDGE); GPIOIntTypeSet(GPIO_PORTB_BASE,PULSE_L,GPIO_FALLING_EDGE); // 使能引腳輸入中斷 GPIOPinIntEnable(GPIO_PORTA_BASE,PULSE_R); GPIOPinIntEnable(GPIO_PORTB_BASE,PULSE_L); // 使能GPIO PA 口和GPIO PB 口中斷 IntEnable(INT_GPIOA); IntEnable(INT_GPIOB); } 左右輪檢測脈沖中斷處函數(shù)如程序清單 5.2 所示。 程序清單 5.2 左右輪檢測脈沖中斷處函數(shù) //------------------------------------------------------------------------------------ // 函數(shù)名稱: GPIO_Port_A_ISR // 函數(shù)功能: 右輪檢測脈沖中斷處函數(shù) //------------------------------------------------------------------------------------ void GPIO_Port_A_ISR (void) { unsigned char IntStatus; IntStatus = GPIOPinIntStatus(GPIO_PORTA_BASE,true); // 讀PA 口中斷狀態(tài) if(IntStatus&PULSE_R) // 是否為左輪脈沖中斷 { PulCount_R++; if(PulCount_R >= RightPulse) { RightWheelRun(0, 1); WheelStop_R= 1; } GPIOPinIntClear(GPIO_PORTA_BASE,PULSE_R); // 清中斷 } } //------------------------------------------------------------------------------------ // 函數(shù)名稱: GPIO_Port_B_ISR // 函數(shù)功能: 左輪檢測脈沖中斷處函數(shù) //------------------------------------------------------------------------------------ void GPIO_Port_B_ISR (void) { unsigned char IntStatus; IntStatus = GPIOPinIntStatus(GPIO_PORTB_BASE,true); // 讀PA 口中斷狀態(tài) if(IntStatus&PULSE_L) // 是否為右輪脈沖中斷 { PulCount_L++; if(PulCount_L>= LeftPulse) { WheelStop_L= 1; LeftWheelRun(0, 1); } GPIOPinIntClear(GPIO_PORTB_BASE,PULSE_L); // 清中斷 } } 六、 系統(tǒng)DV:參看附件: a) 直線行走3格+右轉(zhuǎn): 該運動中,小車首先直線行走3格(50CM),然后右轉(zhuǎn),并在碰到障礙物后右轉(zhuǎn),直線行走一格,再右轉(zhuǎn)一次; b) 圍繞小桌運動: 該運動中,小車圍繞方形小桌繞圈,判斷安全距離、檢測是否存在通路,并自動修正方向。 七、 測試情況: 經(jīng)檢測,小車能較好的完成給定的運行任務(wù),較為準(zhǔn)確地直走、左右轉(zhuǎn),及180度轉(zhuǎn)。小車完全可以完成探究迷宮、自動尋路等任務(wù),并以較短的時間完成迷宮行走。 但是,小車依舊存在些問題:直走中有擺動現(xiàn)象,左右轉(zhuǎn)也做不到90度(大概85度到95度之間),180度更不好;算法不夠優(yōu)秀,時間依舊較長。雖然這些問題更為瑣碎更為難處理,但我們有信心,暑假間會完全克服。 八、 曾遇到的問題:
1.車輪行進(jìn)速度不一:
同一函數(shù)中,小車的左右轉(zhuǎn)速相差比較大,我們嘗試采取了以下幾種方式解決
1)。調(diào)占空比:無效,原因不明。在與別的小組交流之后,我們嘗試改寫了原先的驅(qū)動函數(shù),使速度函數(shù)與正反轉(zhuǎn)函數(shù)區(qū)分開:
(原函數(shù) & 改進(jìn)后的函數(shù) 請見附錄)
還不太明白是為什么,把兩個函數(shù)分開寫了之后,發(fā)現(xiàn)有一定效果。
2)。脈沖補償:
這也是演示程序的方法,在執(zhí)行完一次運行任務(wù)之后,把相差的脈沖補償?shù)较乱淮稳蝿?wù)的設(shè)定中:
PWMTimer0AIni(); // PWM初始化
PULSEIni(); // 調(diào)制信號初始化
WheelPulseIni(); // 測速初始化
while(1)
{
LeftPulse = 10; // 設(shè)定電機運行任務(wù)
RightPulse = 10;
WheelStop_L = 0; // 清零電機停止標(biāo)志位
WheelStop_R = 0;
LeftWheelRun(1, 99); // 啟動左右電機
RightWheelRun(1, 99);
while(!(WheelStop_L && WheelStop_R))// 等待運行結(jié)束,狀態(tài)在中斷中改變
Check_Infrared(0); // 等待過程中進(jìn)行紅外檢測
PulCount_L -= LeftPulse; // 誤差補償?shù)较乱淮芜\動中
PulCount_R -= RightPulse;
}
想法很好,實際行不通。
以最低誤差來算,假設(shè)左輪10個脈沖,右輪9個,小車明顯走出一條弧線;而當(dāng)下次補償?shù)较麓沃袝r,小車還是先走同樣的路程,然后左輪停轉(zhuǎn),右輪轉(zhuǎn)2個脈沖(上次誤差+ 這次誤差),表現(xiàn)出了明顯的“一瘸一拐”的情況;而且,在我們的調(diào)試過程中,出現(xiàn)了不穩(wěn)定的左右擺動,這是由于“半個脈沖”的問題,小車不能有效識別比較小的距離差,在最好的狀態(tài)下,小車也存在計數(shù)的問題,比如,左輪剛轉(zhuǎn)就開始向下的觸發(fā),右輪快轉(zhuǎn)一圈才有第一次的向下觸發(fā)。而且,這種誤差是隨機的,與小車車輪的起始位置有關(guān),不好避免。
3).從硬件下手:
在左右電機同加固定電壓時,清楚地看到轉(zhuǎn)速不一樣,因此,最好的辦法還是從硬件上下手,通過串聯(lián)電阻來解決問題。這是我們的一個想法,還沒開始實施,準(zhǔn)備在暑假時再想想軟件解決辦法,不行就改電路。(電機內(nèi)阻,運行時電流)
2。檢測信號的波形:
受燈光的影響,可以看到,紅外接受得到的波形不時很好。檢測初速的還好,因為幅度比較大,所以沒有誤判的問題;檢測擋板的波形振動比較大。按照電路圖,嘗試著變換的電阻,取得不錯的效果,以下函數(shù)足夠完成判斷:
( 源程序詳見附錄)
3。編譯器的問題:
大量鐵的事實證明,crosswork不好用,推薦使用Keil for ARM。前期使用的是crosswork,很多不明就里的問題,換到Keil for ARM就解決了,說明crosswork對小車的支持不夠好。很多函數(shù),在crosswork上,完全起不到效果,跑出來都知道是怎么回事。我們不是在責(zé)怪crosswork不好,但至少說明,不易于上手。
總結(jié)了一些發(fā)現(xiàn)的問題:
1)。不能出現(xiàn)漢字:還好,無非就是存盤載入時麻煩點。
2)。只能裝C盤:剛開始裝在D盤,整天藍(lán)屏。
3)。頭文件載入:很多頭文件需要手動一一載入,還是查百度知道的,說明文件上沒有。
4)。編譯顯示錯誤,不顯示為什么錯:開始時,發(fā)現(xiàn)錯誤就在Keil上找錯。。。。。。
5)。脫機運行問題:想脫機運行?需要改很多。。。。。。
因此,不推薦用crosswork。
|