单片机教程网

电脑版
提示:原网页已由神马搜索转码, 内容由www.51hei.com提供.
查看:3235|回复:2

Arduino高级自走车完整程序资料

[复制链接]
ID:574921发表于 2019-7-11 20:44|显示全部楼层
0.png

单片机源程序如下:
  1. #include< IRremote.h>  
  2. #include< Servo.h>
  3. //***********************定義馬達腳位*************************
  4. int MotorRight1=5;
  5. int MotorRight2=6;
  6. int MotorLeft1=10;
  7. int MotorLeft2=11;
  8. int counter=0;
  9. const int irReceiverPin = 2; //紅外線接收器 OUTPUT 訊號接在 pin 2

  10. //***********************設定所偵測到的IRcode*************************
  11. long IRfront= 0x00FFA25D;       //前進碼
  12. long IRback=0x00FF629D;       //後退
  13. long IRturnright=0x00FFC23D;   //右轉
  14. long IRturnleft= 0x00FF02FD;     //左轉
  15. long IRstop=0x00FFE21D;       //停止
  16. long IRcny70=0x00FFA857;       //CNY70自走模式
  17. long IRAutorun=0x00FF906F;     //超音波自走模式
  18. long IRturnsmallleft= 0x00FF22DD;
  19. //*************************定義CNY70腳位************************************
  20. const int SensorLeft = 7;     //左感測器輸入腳
  21. const int SensorMiddle= 4 ;   //中感測器輸入腳
  22. const int SensorRight = 3;     //右感測器輸入腳
  23. int SL;   //左感測器狀態
  24. int SM;   //中感測器狀態
  25. int SR;   //右感測器狀態
  26. IRrecv irrecv(irReceiverPin);  // 定義 IRrecv 物件來接收紅外線訊號
  27. decode_results results;     // 解碼結果將放在 decode_results 結構的 result 變數裏
  28. //*************************定義超音波腳位******************************
  29. int inputPin =13 ; // 定義超音波信號接收腳位rx
  30. int outputPin =12; // 定義超音波信號發射腳位'tx
  31. int Fspeedd = 0; // 前方距離
  32. int Rspeedd = 0; // 右方距離
  33. int Lspeedd = 0; // 左方距離
  34. int directionn = 0; // 前=8 後=2 左=4 右=6
  35. Servo myservo; // 設 myservo
  36. int delay_time = 250; // 伺服馬達轉向後的穩定時間
  37. int Fgo = 8; // 前進
  38. int Rgo = 6; // 右轉
  39. int Lgo = 4; // 左轉
  40. int Bgo = 2; // 倒車
  41. //********************************************************************(SETUP)
  42. void setup()
  43. {  
  44.   Serial.begin(9600);
  45.   pinMode(MotorRight1, OUTPUT);  // 腳位 8 (PWM)
  46.   pinMode(MotorRight2, OUTPUT);  // 腳位 9 (PWM)
  47.   pinMode(MotorLeft1,  OUTPUT);  // 腳位 10 (PWM)
  48.   pinMode(MotorLeft2,  OUTPUT);  // 腳位 11 (PWM)
  49.   irrecv.enableIRIn();     // 啟動紅外線解碼
  50.    pinMode(SensorLeft, INPUT); //定義左感測器
  51.   pinMode(SensorMiddle, INPUT);//定義中感測器
  52.   pinMode(SensorRight, INPUT); //定義右感測器
  53.   digitalWrite(2,HIGH);
  54.   pinMode(inputPin, INPUT); // 定義超音波輸入腳位
  55.   pinMode(outputPin, OUTPUT); // 定義超音波輸出腳位
  56.   myservo.attach(9); // 定義伺服馬達輸出第5腳位(PWM)


  57. }
  58. //******************************************************************(Void)
  59. void advance(int a) // 前進
  60. {
  61.        digitalWrite(MotorRight1,LOW);
  62.        digitalWrite(MotorRight2,HIGH);
  63.        digitalWrite(MotorLeft1,LOW);
  64.        digitalWrite(MotorLeft2,HIGH);
  65.        delay(a * 100);
  66. }
  67. void right(int b) //右轉(單輪)
  68. {
  69.      digitalWrite(MotorLeft1,LOW);
  70.      digitalWrite(MotorLeft2,HIGH);
  71.      digitalWrite(MotorRight1,LOW);
  72.      digitalWrite(MotorRight2,LOW);
  73.      delay(b * 100);
  74. }
  75. void left(int c) //左轉(單輪)
  76. {
  77.      digitalWrite(MotorRight1,LOW);
  78.      digitalWrite(MotorRight2,HIGH);
  79.      digitalWrite(MotorLeft1,LOW);
  80.      digitalWrite(MotorLeft2,LOW);
  81.      delay(c * 100);
  82. }
  83. void turnR(int d) //右轉(雙輪)
  84. {
  85.      digitalWrite(MotorRight1,HIGH);
  86.      digitalWrite(MotorRight2,LOW);
  87.      digitalWrite(MotorLeft1,LOW);
  88.      digitalWrite(MotorLeft2,HIGH);
  89.      delay(d * 100);
  90. }
  91. void turnL(int e) //左轉(雙輪)
  92. {
  93.      digitalWrite(MotorRight1,LOW);
  94.      digitalWrite(MotorRight2,HIGH);
  95.      digitalWrite(MotorLeft1,HIGH);
  96.      digitalWrite(MotorLeft2,LOW);
  97.      delay(e * 100);
  98. }
  99. void stopp(int f) //停止
  100. {
  101.      digitalWrite(MotorRight1,LOW);
  102.      digitalWrite(MotorRight2,LOW);
  103.      digitalWrite(MotorLeft1,LOW);
  104.      digitalWrite(MotorLeft2,LOW);
  105.      delay(f * 100);
  106. }
  107. void back(int g) //後退
  108. {
  109.        digitalWrite(MotorRight1,HIGH);
  110.        digitalWrite(MotorRight2,LOW);
  111.        digitalWrite(MotorLeft1,HIGH);
  112.        digitalWrite(MotorLeft2,LOW);;
  113.        delay(g * 100);
  114. }
  115. void detection() //測量3個角度(前.左.右)
  116. {
  117.    int delay_time = 250; // 伺服馬達轉向後的穩定時間
  118.    ask_pin_F(); // 讀取前方距離

  119.    if(Fspeedd< 10) // 假如前方距離小於10公分
  120.    {
  121.      stopp(1); // 清除輸出資料
  122.      back(2); // 後退 0.2秒
  123.    }
  124.    if(Fspeedd< 25) // 假如前方距離小於25公分
  125.    {
  126.      stopp(1); // 清除輸出資料
  127.      ask_pin_L(); // 讀取左方距離
  128.      delay(delay_time); // 等待伺服馬達穩定
  129.      ask_pin_R(); // 讀取右方距離
  130.      delay(delay_time); // 等待伺服馬達穩定

  131.      if(Lspeedd > Rspeedd) //假如 左邊距離大於右邊距離
  132.      {
  133.        directionn = Lgo; //向左走
  134.      }

  135.      if(Lspeedd< = Rspeedd) //假如 左邊距離小於或等於右邊距離
  136.      {
  137.        directionn = Rgo; //向右走
  138.      }

  139.      if (Lspeedd< 15&& Rspeedd< 15) //假如 左邊距離和右邊距離皆小於10公分
  140.      {
  141.        directionn = Bgo; //向後走
  142.      }
  143.    }
  144.    else //加如前方大於25公分
  145.    {
  146.      directionn = Fgo; //向前走
  147.    }
  148. }  
  149. //*********************************************************************************
  150. void ask_pin_F() // 量出前方距離
  151. {
  152. myservo.write(90);
  153. digitalWrite(outputPin, LOW); // 讓超聲波發射低電壓2μs
  154. delayMicroseconds(2);
  155. digitalWrite(outputPin, HIGH); // 讓超聲波發射高電壓10μs,這裡至少是10μs
  156. delayMicroseconds(10);
  157. digitalWrite(outputPin, LOW); // 維持超聲波發射低電壓
  158. float Fdistance = pulseIn(inputPin, HIGH); // 讀差相差時間
  159. Fdistance= Fdistance/5.8/10; // 將時間轉為距離距离(單位:公分)
  160. Serial.print("F distance:"); //輸出距離(單位:公分)
  161. Serial.println(Fdistance); //顯示距離
  162. Fspeedd = Fdistance; // 將距離 讀入Fspeedd(前速)
  163. }
  164. //********************************************************************************
  165. void ask_pin_L() // 量出左邊距離
  166. {
  167. myservo.write(177);
  168. delay(delay_time);
  169. digitalWrite(outputPin, LOW); // 讓超聲波發射低電壓2μs
  170. delayMicroseconds(2);
  171. digitalWrite(outputPin, HIGH); // 讓超聲波發射高電壓10μs,這裡至少是10μs
  172. delayMicroseconds(10);
  173. digitalWrite(outputPin, LOW); // 維持超聲波發射低電壓
  174. float Ldistance = pulseIn(inputPin, HIGH); // 讀差相差時間
  175. Ldistance= Ldistance/5.8/10; // 將時間轉為距離距离(單位:公分)
  176. Serial.print("L distance:"); //輸出距離(單位:公分)
  177. Serial.println(Ldistance); //顯示距離
  178. Lspeedd = Ldistance; // 將距離 讀入Lspeedd(左速)
  179. }
  180. //******************************************************************************
  181. void ask_pin_R() // 量出右邊距離
  182. {
  183. myservo.write(5);
  184. delay(delay_time);
  185. digitalWrite(outputPin, LOW); // 讓超聲波發射低電壓2μs
  186. delayMicroseconds(2);
  187. digitalWrite(outputPin, HIGH); // 讓超聲波發射高電壓10μs,這裡至少是10μs
  188. delayMicroseconds(10);
  189. digitalWrite(outputPin, LOW); // 維持超聲波發射低電壓
  190. float Rdistance = pulseIn(inputPin, HIGH); // 讀差相差時間
  191. Rdistance= Rdistance/5.8/10; // 將時間轉為距離距离(單位:公分)
  192. Serial.print("R distance:"); //輸出距離(單位:公分)
  193. Serial.println(Rdistance); //顯示距離
  194. Rspeedd = Rdistance; // 將距離 讀入Rspeedd(右速)
  195. }
  196. //******************************************************************************(LOOP)
  197. void loop()
  198. {
  199.      SL = digitalRead(SensorLeft);
  200.      SM = digitalRead(SensorMiddle);
  201.      SR = digitalRead(SensorRight);
  202. //***************************************************************************正常遙控模式    
  203.   if (irrecv.decode(&results))
  204.    {       // 解碼成功,收到一組紅外線訊號
  205. /***********************************************************************/
  206.      if (results.value == IRfront)//前進
  207.      {
  208.        advance(10);//前進
  209.      }
  210. /***********************************************************************/
  211.      if (results.value ==  IRback)//後退
  212.      {
  213.        back(10);//後退
  214.      }
  215. /***********************************************************************/
  216.      if (results.value == IRturnright)//右轉
  217.      {
  218.        right(6); // 右轉
  219.      }
  220. /***********************************************************************/
  221.      if (results.value == IRturnleft)//左轉
  222.      {
  223.      left(6); // 左轉);
  224.      }
  225. /***********************************************************************/  
  226.    if (results.value == IRstop)//停止
  227.    {
  228.      digitalWrite(MotorRight1,LOW);
  229.      digitalWrite(MotorRight2,LOW);
  230.      digitalWrite(MotorLeft1,LOW);
  231.      digitalWrite(MotorLeft2,LOW);
  232.    }
  233. //***********************************************************************cny70模式自走模式 黑:LOW 白:
  234.    if (results.value == IRcny70)
  235.    {              
  236.      while(IRcny70)
  237.      {  
  238.      SL = digitalRead(SensorLeft);
  239.      SM = digitalRead(SensorMiddle);
  240.      SR = digitalRead(SensorRight);
  241.             
  242.      if (SM == HIGH)//中感測器在黑色區域
  243.      {
  244.        if (SL == LOW& SR == HIGH) // 左黑右白, 向左轉彎
  245.        {  
  246.          digitalWrite(MotorRight1,LOW);
  247.          digitalWrite(MotorRight2,HIGH);
  248.          analogWrite(MotorLeft1,0);
  249.          analogWrite(MotorLeft2,80);
  250.        }
  251.        else if (SR == LOW& SL == HIGH) //左白右黑, 向右轉彎
  252.        {  
  253.          analogWrite(MotorRight1,0);//右轉
  254.          analogWrite(MotorRight2,80);
  255.          digitalWrite(MotorLeft1,LOW);
  256.          digitalWrite(MotorLeft2,HIGH);
  257.        }
  258.        else  // 兩側均為白色, 直進
  259.        {
  260.          digitalWrite(MotorRight1,LOW);
  261.          digitalWrite(MotorRight2,HIGH);
  262.          digitalWrite(MotorLeft1,LOW);
  263.          digitalWrite(MotorLeft2,HIGH);
  264.          analogWrite(MotorLeft1,200);
  265.          analogWrite(MotorLeft2,200);
  266.          analogWrite(MotorRight1,200);
  267.          analogWrite(MotorRight2,200);
  268.        }    
  269.      }
  270.      else // 中感測器在白色區域
  271.      {  
  272.        if (SL == LOW& SR == HIGH)// 左黑右白, 快速左轉
  273.        {  
  274.          digitalWrite(MotorRight1,LOW);
  275.          digitalWrite(MotorRight2,HIGH);
  276.          digitalWrite(MotorLeft1,LOW);
  277.          digitalWrite(MotorLeft2,LOW);
  278.        }
  279.        else if (SR == LOW& SL == HIGH) // 左白右黑, 快速右轉
  280.        {  
  281.          digitalWrite(MotorRight1,LOW);
  282.          digitalWrite(MotorRight2,LOW);
  283.          digitalWrite(MotorLeft1,LOW);
  284.          digitalWrite(MotorLeft2,HIGH);
  285.        }
  286.        else // 都是白色, 停止
  287.        {  
  288.        digitalWrite(MotorRight1,HIGH);
  289.        digitalWrite(MotorRight2,LOW);
  290.        digitalWrite(MotorLeft1,HIGH);
  291.        digitalWrite(MotorLeft2,LOW);;
  292.        }
  293.      }
  294.      if (irrecv.decode(&results))
  295.      {
  296.          irrecv.resume();
  297.              Serial.println(results.value,HEX);
  298.          if(results.value ==IRstop)
  299.          {
  300.            digitalWrite(MotorRight1,HIGH);
  301.            digitalWrite(MotorRight2,HIGH);
  302.            digitalWrite(MotorLeft1,HIGH);
  303.            digitalWrite(MotorLeft2,HIGH);
  304.            break;
  305.          }
  306.      }
  307.      }
  308.      results.value=0;
  309.    }
  310. //***********************************************************************超音波自走模式
  311. if (results.value ==IRAutorun )
  312.      {
  313.          while(IRAutorun)
  314.        {
  315.          myservo.write(90); //讓伺服馬達回歸 預備位置 準備下一次的測量
  316.          detection(); //測量角度 並且判斷要往哪一方向移動
  317.          if(directionn == 8) //假如directionn(方向) = 8(前進)
  318.          {
  319.            if (irrecv.decode(&results))
  320.          {
  321.          irrecv.resume();
  322.          Serial.println(results.value,HEX);
  323.          if(results.value ==IRstop)
  324.          {
  325.            digitalWrite(MotorRight1,LOW);
  326.            digitalWrite(MotorRight2,LOW);
  327.            digitalWrite(MotorLeft1,LOW);
  328.            digitalWrite(MotorLeft2,LOW);
  329.            break;
  330.          }
  331.          }
  332.            results.value=0;
  333.            advance(1); // 正常前進
  334.            Serial.print(" Advance "); //顯示方向(前進)
  335.            Serial.print(" ");
  336.          }
  337.          if(directionn == 2) //假如directionn(方向) = 2(倒車)
  338.        {
  339.          if (irrecv.decode(&results))
  340.          {
  341.          irrecv.resume();
  342.          Serial.println(results.value,HEX);
  343.          if(results.value ==IRstop)
  344.          {
  345.            digitalWrite(MotorRight1,LOW);
  346.            digitalWrite(MotorRight2,LOW);
  347.            digitalWrite(MotorLeft1,LOW);
  348.            digitalWrite(MotorLeft2,LOW);
  349.            break;
  350.          }
  351.          }
  352.            results.value=0;
  353.            back(8); // 倒退(車)
  354.            turnL(3); //些微向左方移動(防止卡在死巷裡)
  355.            Serial.print(" Reverse "); //顯示方向(倒退)
  356.        }
  357.          if(directionn == 6) //假如directionn(方向) = 6(右轉)
  358.        {
  359.          if (irrecv.decode(&results))
  360.          {
  361.            irrecv.resume();
  362.            Serial.println(results.value,HEX);
  363.          if(results.value ==IRstop)
  364.          {
  365.            digitalWrite(MotorRight1,LOW);
  366.            digitalWrite(MotorRight2,LOW);
  367.            digitalWrite(MotorLeft1,LOW);
  368.            digitalWrite(MotorLeft2,LOW);
  369.            break;
  370.          }
  371.          }
  372.          results.value=0;
  373.            back(1);
  374.            turnR(6); // 右轉
  375.            Serial.print(" Right "); //顯示方向(左轉)
  376.        }
  377.          if(directionn == 4) //假如directionn(方向) = 4(左轉)
  378.        {
  379.          if (irrecv.decode(&results))
  380.          {
  381.          irrecv.resume();
  382.          Serial.println(results.value,HEX);
  383.          if(results.value ==IRstop)
  384.          {
  385.            digitalWrite(MotorRight1,LOW);
  386.            digitalWrite(MotorRight2,LOW);
  387.            digitalWrite(MotorLeft1,LOW);
  388.            digitalWrite(MotorLeft2,LOW);
  389.            break;
  390.          }
  391.          }
  392.            results.value=0;
  393.            back(1);
  394.            turnL(6); // 左轉
  395.            Serial.print(" Left "); //顯示方向(右轉)
  396.          }
  397.         
  398.          if (irrecv.decode(&results))
  399.          {
  400.          irrecv.resume();
  401.          Serial.println(results.value,HEX);
  402.          if(results.value ==IRstop)
  403.          {
  404.            digitalWrite(MotorRight1,LOW);
  405.            digitalWrite(MotorRight2,LOW);
  406.            digitalWrite(MotorLeft1,LOW);
  407.            digitalWrite(MotorLeft2,LOW);
  408.            break;
  409.          }
  410.          }
  411.        }
  412.            results.value=0;
  413.      }
  414. /***********************************************************************/  
  415.      else
  416.    {
  417.          digitalWrite(MotorRight1,LOW);
  418.          digitalWrite(MotorRight2,LOW);
  419.          digitalWrite(MotorLeft1,LOW);
  420.          digitalWrite(MotorLeft2,LOW);
  421.      }
  422.     

  423.        irrecv.resume();   // 繼續收下一組紅外線訊號      
  424.    }  
  425. }
复制代码

所有资料51hei提供下载:
高级自走车完整资料.7z(11.55 MB, 下载次数: 72)
ID:563758发表于 2019-8-24 20:31|显示全部楼层
收藏了,学习中
ID:606788发表于 2019-9-3 12:02|显示全部楼层
感谢分享

手机版|小黑屋|51黑电子论坛|51黑电子论坛6群QQ管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网