Was this page helpful?

CODE

    內容表格
    沒有標頭


     

    #include <IRremote.h>  
    #include <Servo.h>
    //***********************定義馬達腳位*************************
    int MotorRight1=5;
    int MotorRight2=6;
    int MotorLeft1=10;
    int MotorLeft2=11;
    int counter=0;
    const int irReceiverPin = 2; //紅外線接收器 OUTPUT 訊號接在 pin 2
    
    //***********************設定所偵測到的IRcode*************************
    long IRfront= 0x00FFA25D;        //前進碼
    long IRback=0x00FF629D;         //後退
    long IRturnright=0x00FFC23D;    //右轉
    long IRturnleft= 0x00FF02FD;     //左轉
    long IRstop=0x00FFE21D;         //停止
    long IRcny70=0x00FFA857;        //CNY70自走模式
    long IRAutorun=0x00FF906F;      //超音波自走模式
    long IRturnsmallleft= 0x00FF22DD;
    //*************************定義CNY70腳位************************************
    const int SensorLeft = 7;      //左感測器輸入腳
    const int SensorMiddle= 4 ;    //中感測器輸入腳
    const int SensorRight = 3;     //右感測器輸入腳
    int SL;    //左感測器狀態
    int SM;    //中感測器狀態
    int SR;    //右感測器狀態
    IRrecv irrecv(irReceiverPin);  // 定義 IRrecv 物件來接收紅外線訊號
    decode_results results;       // 解碼結果將放在 decode_results 結構的 result 變數裏
    //*************************定義超音波腳位******************************
    int inputPin =13 ; // 定義超音波信號接收腳位rx
    int outputPin =12; // 定義超音波信號發射腳位'tx
    int Fspeedd = 0; // 前方距離
    int Rspeedd = 0; // 右方距離
    int Lspeedd = 0; // 左方距離
    int directionn = 0; // 前=8 後=2 左=4 右=6
    Servo myservo; // 設 myservo
    int delay_time = 250; // 伺服馬達轉向後的穩定時間
    int Fgo = 8; // 前進
    int Rgo = 6; // 右轉
    int Lgo = 4; // 左轉
    int Bgo = 2; // 倒車
    //********************************************************************(SETUP)
    void setup()
    {  
      Serial.begin(9600);
      pinMode(MotorRight1, OUTPUT);  // 腳位 8 (PWM)
      pinMode(MotorRight2, OUTPUT);  // 腳位 9 (PWM)
      pinMode(MotorLeft1,  OUTPUT);  // 腳位 10 (PWM)
      pinMode(MotorLeft2,  OUTPUT);  // 腳位 11 (PWM)
      irrecv.enableIRIn();     // 啟動紅外線解碼
       pinMode(SensorLeft, INPUT); //定義左感測器
      pinMode(SensorMiddle, INPUT);//定義中感測器
      pinMode(SensorRight, INPUT); //定義右感測器
      digitalWrite(2,HIGH);
      pinMode(inputPin, INPUT); // 定義超音波輸入腳位
      pinMode(outputPin, OUTPUT); // 定義超音波輸出腳位
      myservo.attach(9); // 定義伺服馬達輸出第5腳位(PWM)
    
    
     }
    //******************************************************************(Void)
    void advance(int a) // 前進
    {
            digitalWrite(MotorRight1,LOW);
            digitalWrite(MotorRight2,HIGH);
            digitalWrite(MotorLeft1,LOW);
            digitalWrite(MotorLeft2,HIGH);
            delay(a * 100);
    }
    void right(int b) //右轉(單輪)
    {
           digitalWrite(MotorLeft1,LOW);
           digitalWrite(MotorLeft2,HIGH);
           digitalWrite(MotorRight1,LOW);
           digitalWrite(MotorRight2,LOW);
           delay(b * 100);
    }
    void left(int c) //左轉(單輪)
    {
          digitalWrite(MotorRight1,LOW);
          digitalWrite(MotorRight2,HIGH);
          digitalWrite(MotorLeft1,LOW);
          digitalWrite(MotorLeft2,LOW);
          delay(c * 100);
    }
    void turnR(int d) //右轉(雙輪)
    {
          digitalWrite(MotorRight1,HIGH);
          digitalWrite(MotorRight2,LOW);
          digitalWrite(MotorLeft1,LOW);
          digitalWrite(MotorLeft2,HIGH);
          delay(d * 100);
    }
    void turnL(int e) //左轉(雙輪)
    {
          digitalWrite(MotorRight1,LOW);
          digitalWrite(MotorRight2,HIGH);
          digitalWrite(MotorLeft1,HIGH);
          digitalWrite(MotorLeft2,LOW);
          delay(e * 100);
    }
    void stopp(int f) //停止
    {
         digitalWrite(MotorRight1,LOW);
         digitalWrite(MotorRight2,LOW);
         digitalWrite(MotorLeft1,LOW);
         digitalWrite(MotorLeft2,LOW);
         delay(f * 100);
    }
    void back(int g) //後退
    {
            digitalWrite(MotorRight1,HIGH);
            digitalWrite(MotorRight2,LOW);
            digitalWrite(MotorLeft1,HIGH);
            digitalWrite(MotorLeft2,LOW);;
            delay(g * 100);
    }
    void detection() //測量3個角度(前.左.右)
    {
        int delay_time = 250; // 伺服馬達轉向後的穩定時間
        ask_pin_F(); // 讀取前方距離
    
        if(Fspeedd < 10) // 假如前方距離小於10公分
       {
          stopp(1); // 清除輸出資料
          back(2); // 後退 0.2秒
       }
        if(Fspeedd < 25) // 假如前方距離小於25公分
       {
          stopp(1); // 清除輸出資料
          ask_pin_L(); // 讀取左方距離
          delay(delay_time); // 等待伺服馬達穩定
          ask_pin_R(); // 讀取右方距離
          delay(delay_time); // 等待伺服馬達穩定
    
          if(Lspeedd > Rspeedd) //假如 左邊距離大於右邊距離
         {
            directionn = Lgo; //向左走
         }
    
          if(Lspeedd <= Rspeedd) //假如 左邊距離小於或等於右邊距離
          {
            directionn = Rgo; //向右走
          }
    
          if (Lspeedd < 15 && Rspeedd < 15) //假如 左邊距離和右邊距離皆小於10公分
         {
            directionn = Bgo; //向後走
          }
        }
        else //加如前方大於25公分
       {
          directionn = Fgo; //向前走
       }
    }   
    //*********************************************************************************
    void ask_pin_F() // 量出前方距離
    {
    myservo.write(90);
    digitalWrite(outputPin, LOW); // 讓超聲波發射低電壓2μs
    delayMicroseconds(2);
    digitalWrite(outputPin, HIGH); // 讓超聲波發射高電壓10μs,這裡至少是10μs
    delayMicroseconds(10);
    digitalWrite(outputPin, LOW); // 維持超聲波發射低電壓
    float Fdistance = pulseIn(inputPin, HIGH); // 讀差相差時間
    Fdistance= Fdistance/5.8/10; // 將時間轉為距離距离(單位:公分)
    Serial.print("F distance:"); //輸出距離(單位:公分)
    Serial.println(Fdistance); //顯示距離
    Fspeedd = Fdistance; // 將距離 讀入Fspeedd(前速)
    }
    //********************************************************************************
    void ask_pin_L() // 量出左邊距離
    {
    myservo.write(177);
    delay(delay_time);
    digitalWrite(outputPin, LOW); // 讓超聲波發射低電壓2μs
    delayMicroseconds(2);
    digitalWrite(outputPin, HIGH); // 讓超聲波發射高電壓10μs,這裡至少是10μs
    delayMicroseconds(10);
    digitalWrite(outputPin, LOW); // 維持超聲波發射低電壓
    float Ldistance = pulseIn(inputPin, HIGH); // 讀差相差時間
    Ldistance= Ldistance/5.8/10; // 將時間轉為距離距离(單位:公分)
    Serial.print("L distance:"); //輸出距離(單位:公分)
    Serial.println(Ldistance); //顯示距離
    Lspeedd = Ldistance; // 將距離 讀入Lspeedd(左速)
    }
    //******************************************************************************
    void ask_pin_R() // 量出右邊距離
    {
    myservo.write(5);
    delay(delay_time);
    digitalWrite(outputPin, LOW); // 讓超聲波發射低電壓2μs
    delayMicroseconds(2);
    digitalWrite(outputPin, HIGH); // 讓超聲波發射高電壓10μs,這裡至少是10μs
    delayMicroseconds(10);
    digitalWrite(outputPin, LOW); // 維持超聲波發射低電壓
    float Rdistance = pulseIn(inputPin, HIGH); // 讀差相差時間
    Rdistance= Rdistance/5.8/10; // 將時間轉為距離距离(單位:公分)
    Serial.print("R distance:"); //輸出距離(單位:公分)
    Serial.println(Rdistance); //顯示距離
    Rspeedd = Rdistance; // 將距離 讀入Rspeedd(右速)
    }
    //******************************************************************************(LOOP)
    void loop()
    {
          SL = digitalRead(SensorLeft);
          SM = digitalRead(SensorMiddle);
          SR = digitalRead(SensorRight);
    //***************************************************************************正常遙控模式      
      if (irrecv.decode(&results))
        {         // 解碼成功,收到一組紅外線訊號
    /***********************************************************************/
          if (results.value == IRfront)//前進
           {
            advance(10);//前進
           }
    /***********************************************************************/
          if (results.value ==  IRback)//後退
           {
            back(10);//後退
           }
    /***********************************************************************/
          if (results.value == IRturnright)//右轉
          {
            right(6); // 右轉
          }
    /***********************************************************************/
         if (results.value == IRturnleft)//左轉
         {
           left(6); // 左轉);
         }
    /***********************************************************************/    
        if (results.value == IRstop)//停止
       {
         digitalWrite(MotorRight1,LOW);
         digitalWrite(MotorRight2,LOW);
         digitalWrite(MotorLeft1,LOW);
         digitalWrite(MotorLeft2,LOW);
        }
    //***********************************************************************cny70模式自走模式 黑:LOW 白:
        if (results.value == IRcny70)
       {                     
         while(IRcny70)
         {  
           SL = digitalRead(SensorLeft);
           SM = digitalRead(SensorMiddle);
           SR = digitalRead(SensorRight);
                       
           if (SM == HIGH)//中感測器在黑色區域
           {
              if (SL == LOW & SR == HIGH) // 左黑右白, 向左轉彎
              {  
                 digitalWrite(MotorRight1,LOW);
                 digitalWrite(MotorRight2,HIGH);
                 analogWrite(MotorLeft1,0);
                 analogWrite(MotorLeft2,80);
              }
              else if (SR == LOW & SL == HIGH) //左白右黑, 向右轉彎
              {  
                 analogWrite(MotorRight1,0);//右轉
                 analogWrite(MotorRight2,80);
                 digitalWrite(MotorLeft1,LOW);
                 digitalWrite(MotorLeft2,HIGH);
              }
             else  // 兩側均為白色, 直進
              {
                 digitalWrite(MotorRight1,LOW);
                 digitalWrite(MotorRight2,HIGH);
                 digitalWrite(MotorLeft1,LOW);
                 digitalWrite(MotorLeft2,HIGH);
                 analogWrite(MotorLeft1,200);
                 analogWrite(MotorLeft2,200);
                 analogWrite(MotorRight1,200);
                 analogWrite(MotorRight2,200);
             }      
           }
           else // 中感測器在白色區域
          {  
             if (SL == LOW & SR == HIGH)// 左黑右白, 快速左轉
            {  
                digitalWrite(MotorRight1,LOW);
                digitalWrite(MotorRight2,HIGH);
                digitalWrite(MotorLeft1,LOW);
                digitalWrite(MotorLeft2,LOW);
            }
             else if (SR == LOW & SL == HIGH) // 左白右黑, 快速右轉
            {  
               digitalWrite(MotorRight1,LOW);
               digitalWrite(MotorRight2,LOW);
               digitalWrite(MotorLeft1,LOW);
               digitalWrite(MotorLeft2,HIGH);
            }
             else // 都是白色, 停止
            {    
            digitalWrite(MotorRight1,HIGH);
            digitalWrite(MotorRight2,LOW);
            digitalWrite(MotorLeft1,HIGH);
            digitalWrite(MotorLeft2,LOW);;
            }
          }
           if (irrecv.decode(&results))
           {
                 irrecv.resume();
                      Serial.println(results.value,HEX);
                 if(results.value ==IRstop)
                 {
                   digitalWrite(MotorRight1,HIGH);
                   digitalWrite(MotorRight2,HIGH);
                   digitalWrite(MotorLeft1,HIGH);
                   digitalWrite(MotorLeft2,HIGH);
                   break;
                 }
           }
         }
          results.value=0;
       }
    //***********************************************************************超音波自走模式
     if (results.value ==IRAutorun )
          {
               while(IRAutorun)
            {
                myservo.write(90); //讓伺服馬達回歸 預備位置 準備下一次的測量
                detection(); //測量角度 並且判斷要往哪一方向移動
                 if(directionn == 8) //假如directionn(方向) = 8(前進)
                {
                  if (irrecv.decode(&results))
               {
                 irrecv.resume();
                 Serial.println(results.value,HEX);
                 if(results.value ==IRstop)
                 {
                   digitalWrite(MotorRight1,LOW);
                   digitalWrite(MotorRight2,LOW);
                   digitalWrite(MotorLeft1,LOW);
                   digitalWrite(MotorLeft2,LOW);
                   break;
                 }
               }
                    results.value=0;
                    advance(1); // 正常前進
                    Serial.print(" Advance "); //顯示方向(前進)
                    Serial.print(" ");
                }
               if(directionn == 2) //假如directionn(方向) = 2(倒車)
              {
                if (irrecv.decode(&results))
               {
                 irrecv.resume();
                 Serial.println(results.value,HEX);
                 if(results.value ==IRstop)
                 {
                   digitalWrite(MotorRight1,LOW);
                   digitalWrite(MotorRight2,LOW);
                   digitalWrite(MotorLeft1,LOW);
                   digitalWrite(MotorLeft2,LOW);
                   break;
                 }
               }
                  results.value=0;
                  back(8); // 倒退(車)
                  turnL(3); //些微向左方移動(防止卡在死巷裡)
                  Serial.print(" Reverse "); //顯示方向(倒退)
              }
                if(directionn == 6) //假如directionn(方向) = 6(右轉)
              {
               if (irrecv.decode(&results))
               {
                  irrecv.resume();
                  Serial.println(results.value,HEX);
                 if(results.value ==IRstop)
                 {
                   digitalWrite(MotorRight1,LOW);
                   digitalWrite(MotorRight2,LOW);
                   digitalWrite(MotorLeft1,LOW);
                   digitalWrite(MotorLeft2,LOW);
                   break;
                 }
               }
                 results.value=0;
                   back(1);
                   turnR(6); // 右轉
                   Serial.print(" Right "); //顯示方向(左轉)
              }
                if(directionn == 4) //假如directionn(方向) = 4(左轉)
              {
                 if (irrecv.decode(&results))
               {
                 irrecv.resume();
                 Serial.println(results.value,HEX);
                 if(results.value ==IRstop)
                 {
                   digitalWrite(MotorRight1,LOW);
                   digitalWrite(MotorRight2,LOW);
                   digitalWrite(MotorLeft1,LOW);
                   digitalWrite(MotorLeft2,LOW);
                   break;
                 }
               }
                    results.value=0;
                    back(1);
                    turnL(6); // 左轉
                    Serial.print(" Left "); //顯示方向(右轉)
               }
                
                 if (irrecv.decode(&results))
               {
                 irrecv.resume();
                 Serial.println(results.value,HEX);
                 if(results.value ==IRstop)
                 {
                   digitalWrite(MotorRight1,LOW);
                   digitalWrite(MotorRight2,LOW);
                   digitalWrite(MotorLeft1,LOW);
                   digitalWrite(MotorLeft2,LOW);
                   break;
                 }
               }
             }
                   results.value=0;
           }
    /***********************************************************************/    
         else
        {
               digitalWrite(MotorRight1,LOW);
               digitalWrite(MotorRight2,LOW);
               digitalWrite(MotorLeft1,LOW);
               digitalWrite(MotorLeft2,LOW);
         }
          
    
            irrecv.resume();    // 繼續收下一組紅外線訊號        
       }  
    }
    Was this page helpful?
    標籤 (Edit tags)
    • No tags

    文件 1

    文件大小日期附件上傳者 
     car.rar
    無描述
    11.02 MB16:54, 29 Apr 2012thx動作
    您必須 登入 才能發佈評論。
    Powered by MindTouch Core