
這是一臺能沿著預設黑色軌跡自主巡游的機器人它在“深圳”地圖上依次經過12個“景點”并在每個景點自動掉頭最終回到起點。項目核心是一塊搭載51單片機的BoeBot小車配合4路QTI灰度傳感器通過狀態機決策實現路徑跟蹤、路口識別和轉向控制。傳感器4路QTI紅外反射式傳感器連接至P1.4~P1.7高四位輸出數字電平0黑線1白底#includeuart.h #includeBoeBot.h void Follow_Line(void); int Get_4QTI_State(void); void MoveAStep(int LeftP,int RightP); void RightTurn(int steps); void LeftTurn(int steps); void Rotate(int steps); void Forward(int steps); int right90Steps42;//向右轉90度所需的循環次數 int left90Steps33;//向左轉90度所需的循環次數 int UTurnSteps45;//旋轉180度所需的循環次數 int whereamI0;//經過的景點數 int crossSteps8,j1,k1; void main(void) { uart_Init(); delay_nms(2000);//延時2s,消除打開開關對小車的影響 while(1) { Follow_Line(); } } void Follow_Line(void) { int QTIState; int LeftPulse,RightPulse; QTIStateGet_4QTI_State();//獲取小車的狀態 switch(QTIState) { case 0x10 : LeftPulse1700;RightPulse1700;break;//右轉 0001 case 0x30 : LeftPulse1700;RightPulse1500;break;//小幅右轉 0011 case 0x20 : LeftPulse1550;RightPulse1450;break;//前進 0010 case 0x40 : LeftPulse1550;RightPulse1450;break;//前進 0100 case 0x60 : LeftPulse1550;RightPulse1450;break;//前進 0110 case 0x80 : LeftPulse1300;RightPulse1300;break;//左轉 1000 case 0xc0 : LeftPulse1500;RightPulse1300;break;//小幅左轉 1100 case 0xe0 : // 1110 if(whereamI8k1) { RightTurn(right90Steps); LeftPulse1500;RightPulse1500;k;break; } //經過景點8后到達十字路口非理想狀態下未檢測到“1111”而是檢測到“1110”為保證準確也讓其右轉 else if(whereamI2||whereamI4||whereamI10) { RightTurn(right90Steps); LeftPulse1500;RightPulse1500;break; }//經過景點2、4、10后到達丁十字路口非理想狀態下未檢測到“1111”而是檢測到“1110”為保證準確也讓其右轉 else if(whereamI5) { Forward(crossSteps);LeftPulse1500;RightPulse1500;break; }//經過景點5后到達十字路口時, 非理想狀態下未檢測到“1111”而是檢測到“1110”為保證準確也讓其直行 else { LeftTurn(left90Steps); LeftPulse1500;RightPulse1500;break; } case 0x70: if(whereamI8k1) // 0111 { RightTurn(right90Steps); LeftPulse1500;RightPulse1500;k;break; }//經過景點8后到達十字路口時, 非理想狀態下未檢測到“1111”而 是檢測到“0111”為保證準確也讓其右轉 else if(whereamI8k2) { LeftTurn(left90Steps);LeftPulse1500;RightPulse1500;break; }//經過景點8后再經過一個十字路口到達第二個十字路口時非理想狀態下未檢測到“1111”而是“0111”為保證準確也讓其左轉 else if(whereamI10||whereamI5) { Forward(crossSteps);LeftPulse1500;RightPulse1500;break; }//經過景點10后到達第二個丁字路口時使其直行經過景點5后非理想狀態下檢測到“0111”為保證準確也讓其直行 else { RightTurn(right90Steps);LeftPulse1500;RightPulse1500;break; } case 0xf0 : switch(whereamI) //1111 { case 5:Forward(crossSteps);LeftPulse1500;RightPulse1500;break; //經過景點5后到達十字路口時使其直行 case 6: if(j1) { LeftTurn(left90Steps); LeftPulse1500;RightPulse1500;j;break; }//經過第6個景點到達第1個十字路口時使其左轉 else { RightTurn(right90Steps); LeftPulse1500;RightPulse1500;break; }//經過第6個景點到達第2個十字路口時使其右轉 case 8: if(k1) { RightTurn(right90Steps); LeftPulse1500;RightPulse1500;k;break; }//經過第8個景點到達第1個十字路口時使其右轉 else { LeftTurn(left90Steps); LeftPulse1500;RightPulse1500;break; }//經過第8個景點到達第2個十字路口時使其左轉 case 9: case 12 : LeftTurn(left90Steps); LeftPulse1500;RightPulse1500;break; //經過第9個或第12個景點后到達十字路口時使其左轉 default :RightTurn(right90Steps); LeftPulse1500;RightPulse1500;break; }break; case 0x00: switch(whereamI) // 0000 { case 12 :Forward(12);Rotate(40);delay_nms(20000); LeftPulse1500;RightPulse1500;break; //游完所有景點后到達起始點時先直行一段距離然后旋轉180度回到初始位置延時20s,方便關閉電源結束巡游 default :Rotate(UTurnSteps);whereamI; LeftPulse1500;RightPulse1500;break; //每到達一個景點就旋轉180度實現掉頭whereamI加1即經過了一個景點 }break; default : LeftPulse1500;RightPulse1500;break; } MoveAStep(LeftPulse,RightPulse);//給形參傳遞不同的值使小車實現不同的運動 } int Get_4QTI_State(void) { return P10xf0;//返回一個十六進制的整形數據以得到小車的狀態 } void Forward(int steps)//前進 { int i; for(i0;isteps;i) MoveAStep(1700,1300); } void MoveAStep(int LeftP,int RightP) //給形參傳遞不同的值使小車實現不同的運動 { P1_11; delay_nus(LeftP); P1_10; P1_01; delay_nus(RightP); P1_00; delay_nms(20); } void RightTurn(int steps) //右轉 { int i; for(i0;isteps;i) MoveAStep(1700,1500); } void LeftTurn(int steps)//左轉 { int i; for(i0;isteps;i) MoveAStep(1500,1300); } void Rotate(int steps) //掉頭 { int i; for(i0;isteps;i) MoveAStep(1700,1700); }