全地形小车(C语言编程代码)

Servo_Move_Control.ino

//===================舵机========================舵机=======================舵机=======================舵机===========================舵机==========================舵机==============================舵机==============================舵机
//====舵机===========================舵机======================舵机=======================舵机=========================舵机==========================舵机============================舵机==================================舵机=============
//===================舵机========================舵机=======================舵机=======================舵机===========================舵机==========================舵机==============================舵机==============================舵机
void Servo_Init()
{
  for(int i=0;i<servo_num;i++)
  {
    myServo[i].attach(servo_port[i]);
    myServo[i].write(map(value_init[i],0,180,500,2500));
    delay(20);
  }
}

void ServoStop(int which){//释放舵机
  myServo[which].detach();
  digitalWrite(servo_port[which],LOW);
}

void ServoGo(int which , float where){//打开并给舵机写入相关角度
  if(where!=200){
    if(where==201) ServoStop(which);
    else{
      myServo[which].write(map(where,0,180,500,2500));
    }
  }
}

void Servo_Move_Single(int which,int Start_angle,int End_angle,unsigned long Servo_move_time)
{
  int servo_flags = 0;
  int delta_servo_angle = abs(Start_angle-End_angle);
  if( (Start_angle - End_angle)<0 )
  {
    servo_flags = 1;
  }
  else{ servo_flags = -1; }
  for(int i=0;i<delta_servo_angle;i++)
  {
    myServo[which].write(map( Start_angle+(servo_flags*i) ,0,180,500,2500));
    delay(Servo_move_time);
  }
}

void servo_move(float value0, float value1, float value2,int delaytimes){ //舵机动作函数
  float value_arguments[] = {value0, value1, value2};
  float value_delta[servo_num];  
  for(int i=0;i<servo_num;i++){
    value_delta[i] = (value_arguments[i] - value_init[i]) / f;
  }  
  for(int i=0;i<f;i++){
    for(int k=0;k<servo_num;k++){
      value_init[k] = value_delta[k] == 0 ? value_arguments[k] : value_init[k] + value_delta[k];
    }
    for(int j=0;j<servo_num;j++){
      ServoGo(j,value_init[j]);
    }
    delay(delaytimes/f);
  }
}

Color_detection.ino


/*
 * 黄--------S3
 * 橙--------S2
 * 红--------GND
 * 棕--------VCC
 * 黑--------OUT
 * 白--------LED
 * 灰--------S1
 * 紫--------S0
 */
//TCS230连接设置 
const int s0 = 2; 
const int s1 = 4; 
const int s2 = 7; 
const int s3 = 11; 
const int out = 14; 
const int led = 15;

// Variables 
int red = 0; 
int green = 0; 
int blue = 0; 

void Color_Init()
{
 pinMode(s0, OUTPUT); 
 pinMode(s1, OUTPUT); 
 pinMode(s2, OUTPUT); 
 pinMode(s3, OUTPUT); 
 pinMode(out, INPUT); 
 pinMode(led, OUTPUT);
 digitalWrite(s0, HIGH); 
 digitalWrite(s1, HIGH);   
}


/*
 * color_judge[0]   red green
 * color_judge[0]   green red
 */
void return_color_ballon()
{
  digitalWrite(led, HIGH);
  int numbers_count = 0;
  int color_judge[12]={0,0,0,0,0,0,0,0,0,0,0,0};
  int red_summer,green_summer,blue_summer;
  Serial.println("---------------Start---------------");
  unsigned long time_now = millis();
  while( (millis() - time_now ) < 2000)
  {
     numbers_count ++;
     digitalWrite(s2, LOW); 
     digitalWrite(s3, LOW); 
     //count OUT, pRed, RED 
     red = pulseIn(out, digitalRead(out) == HIGH ? LOW : HIGH); //blue
     digitalWrite(s3, HIGH); 
     //count OUT, pBLUE, BLUE 
     blue = pulseIn(out, digitalRead(out) == HIGH ? LOW : HIGH); //red
     digitalWrite(s2, HIGH); 
     //count OUT, pGreen, GREEN 
     green = pulseIn(out, digitalRead(out) == HIGH ? LOW : HIGH); //green
     if(red<blue){color_judge[0] = color_judge[0] +1;}  else{color_judge[1] = color_judge[1] +1;}
     if(red<green){color_judge[2] = color_judge[2] +1;} else{color_judge[3] = color_judge[3] +1;}

     if(blue<red){color_judge[4] = color_judge[4] +1;}  else{color_judge[5] = color_judge[5] +1;}
     if(blue<green){color_judge[6] = color_judge[6] +1;} else{color_judge[7] = color_judge[7] +1;}

     if(green<red){color_judge[8] = color_judge[8] +1;}  else{color_judge[9] = color_judge[9] +1;}
     if(green<blue){color_judge[10] = color_judge[10] +1;} else{color_judge[11] = color_judge[11] +1;}     

//输出检测红色色卡的信息
//     Serial.print("color[0]=");Serial.print(color_judge[0]);Serial.print(" | ");
//     Serial.print("color[1]=");Serial.print(color_judge[1]);Serial.print(" | ");
//     Serial.print("color[2]=");Serial.print(color_judge[2]);Serial.print(" | ");
//     Serial.print("color[3]=");Serial.print(color_judge[3]);Serial.print(" | ");     

//输出检测蓝色色卡的信息
//     Serial.print("color[4]=");Serial.print(color_judge[4]);Serial.print(" | ");
//     Serial.print("color[5]=");Serial.print(color_judge[5]);Serial.print(" | ");
//     Serial.print("color[6]=");Serial.print(color_judge[6]);Serial.print(" | ");
//     Serial.print("color[7]=");Serial.print(color_judge[7]);Serial.print(" | ");   
//     Serial.print("color[12]=");Serial.print(color_judge[12]);Serial.print(" | ");
//     Serial.print("color[13]=");Serial.print(color_judge[13]);Serial.print(" | ");  
     
//输出绿色色卡的信息
//     Serial.print("color[8]=");Serial.print(color_judge[8]);Serial.print(" | ");
//     Serial.print("color[9]=");Serial.print(color_judge[9]);Serial.print(" | ");
//     Serial.print("color[10]=");Serial.print(color_judge[10]);Serial.print(" | ");
//     Serial.print("color[11]=");Serial.print(color_judge[11]);Serial.print(" | "); 

//输出red,green,blue色域值范围
//     Serial.print(numbers_count);Serial.print(": ");Serial.print("red:");Serial.print(red);Serial.print(" | ");
//     Serial.print("blue:");Serial.print(blue);Serial.print(" | ");
//     Serial.print("green:");Serial.println(green);
     
  }
  Serial.println();
  if( (color_judge[0] > color_judge[1])  && ((color_judge[2] > color_judge[3])) )
//  if( (color_judge[0] > (numbers_count/2))  && (color_judge[2] > (numbers_count/2)) )
  {
//    Serial.println("The color is red");
    color_detection_ballon = 1;
  }

  else if( (color_judge[4] > color_judge[5])  && ((color_judge[6] > color_judge[7]))  )
  {
//    Serial.println("The color is blue");
    color_detection_ballon = 2;
  }

  else if( (color_judge[8] > color_judge[9])  && ((color_judge[10] > color_judge[11])) )
  {
//    Serial.println("The color is green");
    color_detection_ballon = 3;
  }
  
//  Serial.println("---------------End---------------");
//  Serial.println();
  digitalWrite(led, LOW);delay(500);
}


void return_color_card()
{
  digitalWrite(led, HIGH);
  int numbers_count = 0;
  int color_judge[12]={0,0,0,0,0,0,0,0,0,0,0,0};
  int red_summer,green_summer,blue_summer;
  Serial.println("---------------Start---------------");
  unsigned long time_now = millis();
  while( (millis() - time_now ) < 2000)
  {
     numbers_count ++;
     digitalWrite(s2, LOW); 
     digitalWrite(s3, LOW); 
     //count OUT, pRed, RED 
     red = pulseIn(out, digitalRead(out) == HIGH ? LOW : HIGH); //blue
     digitalWrite(s3, HIGH); 
     //count OUT, pBLUE, BLUE 
     blue = pulseIn(out, digitalRead(out) == HIGH ? LOW : HIGH); //red
     digitalWrite(s2, HIGH); 
     //count OUT, pGreen, GREEN 
     green = pulseIn(out, digitalRead(out) == HIGH ? LOW : HIGH); //green
     if(red<blue){color_judge[0] = color_judge[0] +1;}  else{color_judge[1] = color_judge[1] +1;}
     if(red<green){color_judge[2] = color_judge[2] +1;} else{color_judge[3] = color_judge[3] +1;}

     if(blue<red){color_judge[4] = color_judge[4] +1;}  else{color_judge[5] = color_judge[5] +1;}
     if(blue<green){color_judge[6] = color_judge[6] +1;} else{color_judge[7] = color_judge[7] +1;}

     if(green<red){color_judge[8] = color_judge[8] +1;}  else{color_judge[9] = color_judge[9] +1;}
     if(green<blue){color_judge[10] = color_judge[10] +1;} else{color_judge[11] = color_judge[11] +1;}     

//输出检测红色色卡的信息
//     Serial.print("color[0]=");Serial.print(color_judge[0]);Serial.print(" | ");
//     Serial.print("color[1]=");Serial.print(color_judge[1]);Serial.print(" | ");
//     Serial.print("color[2]=");Serial.print(color_judge[2]);Serial.print(" | ");
//     Serial.print("color[3]=");Serial.print(color_judge[3]);Serial.print(" | ");     

//输出检测蓝色色卡的信息
//     Serial.print("color[4]=");Serial.print(color_judge[4]);Serial.print(" | ");
//     Serial.print("color[5]=");Serial.print(color_judge[5]);Serial.print(" | ");
//     Serial.print("color[6]=");Serial.print(color_judge[6]);Serial.print(" | ");
//     Serial.print("color[7]=");Serial.print(color_judge[7]);Serial.print(" | ");   
//     Serial.print("color[12]=");Serial.print(color_judge[12]);Serial.print(" | ");
//     Serial.print("color[13]=");Serial.print(color_judge[13]);Serial.print(" | ");  
     
//输出绿色色卡的信息
//     Serial.print("color[8]=");Serial.print(color_judge[8]);Serial.print(" | ");
//     Serial.print("color[9]=");Serial.print(color_judge[9]);Serial.print(" | ");
//     Serial.print("color[10]=");Serial.print(color_judge[10]);Serial.print(" | ");
//     Serial.print("color[11]=");Serial.print(color_judge[11]);Serial.print(" | "); 

//输出red,green,blue色域值范围
//     Serial.print(numbers_count);Serial.print(": ");Serial.print("red:");Serial.print(red);Serial.print(" | ");
//     Serial.print("blue:");Serial.print(blue);Serial.print(" | ");
//     Serial.print("green:");Serial.println(green);
     
  }
  Serial.println();
  if( (color_judge[0] > color_judge[1])  && ((color_judge[2] > color_judge[3])) )
//  if( (color_judge[0] > (numbers_count/2))  && (color_judge[2] > (numbers_count/2)) )
  {
//    Serial.println("The color is red");
    color_detection_card = 1;
  }

  else if( (color_judge[4] > color_judge[5])  && ((color_judge[6] > color_judge[7]))  )
  {
//    Serial.println("The color is blue");
    color_detection_card = 2;
  }
  else if( (color_judge[8] > color_judge[9])  && ((color_judge[10] > color_judge[11])) )
  {
//    Serial.println("The color is green");
    color_detection_card = 3;
  }  
//  Serial.println("---------------End---------------");
//  Serial.println();
  digitalWrite(led, LOW);delay(500);
}

void color() 
{ 
 digitalWrite(s2, LOW); 
 digitalWrite(s3, LOW); 
 //count OUT, pRed, RED 
 red = pulseIn(out, digitalRead(out) == HIGH ? LOW : HIGH); //blue
 digitalWrite(s3, HIGH); 
 //count OUT, pBLUE, BLUE 
 blue = pulseIn(out, digitalRead(out) == HIGH ? LOW : HIGH); //red
 digitalWrite(s2, HIGH); 
 //count OUT, pGreen, GREEN 
 green = pulseIn(out, digitalRead(out) == HIGH ? LOW : HIGH); //green
 Serial.print("red:");Serial.print(red);Serial.print(" | ");
 Serial.print("blue:");Serial.print(blue);Serial.print(" | ");
 Serial.print("green:");Serial.println(green);
}

Motor_Gray_Control.ino

//灰度传感器初始化函数
void Motor_Sensor_Init()
{
  for(int i=0;i<Car_Head_Gray_SensorPin_Num;i++) {//初始化灰度传感器
     pinMode(Gray_SensorPin[i],INPUT);
     delay(20);
  }
  for(int i=0;i<motor_num;i++) {//初始化 电机
     pinMode(Car_DC_Motor_Pin[i],OUTPUT);
     delay(20);
  } 
}

void Serialprint_gray_sensor_data_analogRead()
{
   int data_sensor[3]={0,0,0};
   for(int i=0;i<3;i++)
   {
     Serial.print(Gray_SensorPin[i]);Serial.print(": ");
     Serial.print(analogRead(Gray_SensorPin[i]));
     Serial.print(" | ");
   }
   Serial.println();  
}

void Serialprint_gray_sensor_data()
{
   int data_sensor[3]={0,0,0};
   for(int i=0;i<3;i++)
   {
     Serial.print(Gray_SensorPin[i]);Serial.print(": ");
     Serial.print(digitalRead(Gray_SensorPin[i]));
     Serial.print(" | ");
   }
   Serial.println();  
}

/*-----------------------------------------------------------------------
  A2         A3         A4
  ----------------------------------
  0          0          0      0x00  表示三个传感器都没有触发
  0          0          1      0x01  表示小车右边一个传感器触发
  0          1          0      0x02  表示小车中间传感器触发
  0          1          1      0x03  表示小车右边两个传感器都触发
  1          0          0      0x04  表示小车左边一个传感器触发
  1          0          1      0x05  
  1          1          0      0x06  表示小车左边两个传感器都触发
  1          1          1      0x07  表示小车三个传感器都触发  
------------------------------------------------------------------------*/
int Detection_tracking() //灰度传感器A4,A3,A2,用来小车巡线时,返回传感器数值;
{
  int num = 0;
  for(int i=0;i<Car_Head_Gray_SensorPin_Num;i++)
  {
    num |= ( (!digitalRead(Gray_SensorPin[i]) ) << i); 
  }
  Serial.println(num);
  return num;
}

void Tracking_Automatic_Tracking(unsigned long delay_tracking_time)
{
  unsigned long now_times = millis();
  while(millis()-now_times<delay_tracking_time)
  {
    Automatic_Tracking();
  }
}

void Automatic_Tracking() //小车前方两个灰度传感器用来寻迹(即小车巡线)。
{
  int Get_Data = 0;
  Get_Data = Detection_tracking();
  switch(Get_Data)
  {    
    case 0x00: Car_Move(Forward,Forward_Left_Speed,Forward_Right_Speed);break;//forward
    case 0x01: Car_Move(Right,  Right_Left_Speed,  Right_Right_Speed  );break;//RIGHT    
    case 0x02: Car_Move(Forward,Forward_Left_Speed,Forward_Right_Speed);break;//forward
    case 0x03: Car_Move(Right,  Right_Left_Speed,  Right_Right_Speed  );break;//right
    case 0x04: Car_Move(Left,   Left_Left_Speed,   Left_Right_Speed   );break;//left
    case 0x06: Car_Move(Left,   Left_Left_Speed,   Left_Right_Speed   );break;//LEFT
    case 0x07: Gray_Three ++; Car_Move(Forward,Forward_Left_Speed,Forward_Right_Speed);break;//forward
    default: break;     
  }
}

int Detection_tracking_analogRead() //灰度传感器A4,A3,A2,用来小车巡线时,返回传感器数值;
{
  int num = 0;
  int analogRead_data[3] = {0,0,0};
  for(int i=0;i<Car_Head_Gray_SensorPin_Num;i++)
  {
    analogRead_data[i] = analogRead(Gray_SensorPin[i]);
    if( analogRead_data[i] <=600 ){analogRead_data[i] = 1;} else{analogRead_data[i] = 0;}
    num |= ( (analogRead_data[i]) << i); 
  }
  Serial.println(num);
  return num;
}


void Automatic_Tracking_analogRead() //小车前方两个灰度传感器用来寻迹(即小车巡线)。
{
  int Get_Data = 0;
  Get_Data = Detection_tracking_analogRead();
  switch(Get_Data)
  {    
    case 0x00: Car_Move(Forward,Forward_Left_Speed,Forward_Right_Speed);break;//forward
    case 0x01: Car_Move(Right,  Right_Left_Speed,  Right_Right_Speed  );break;//RIGHT    
    case 0x02: Car_Move(Forward,Forward_Left_Speed,Forward_Right_Speed);break;//forward
    case 0x03: Car_Move(Right,  Right_Left_Speed,  Right_Right_Speed  );break;//right
    case 0x04: Car_Move(Left,   Left_Left_Speed,   Left_Right_Speed   );break;//left
    case 0x06: Car_Move(Left,   Left_Left_Speed,   Left_Right_Speed   );break;//LEFT
    case 0x07: Gray_Three ++; Car_Move(Forward,Forward_Left_Speed,Forward_Right_Speed);break;//forward
    default: break;     
  }
}


void Car_Move(int Mode,int LeftSpeed,int RightSpeed)                                                                           
{
  switch(Mode)
  {
    case Forward:
                analogWrite(Car_DC_Motor_Pin[0],LeftSpeed);
                analogWrite(Car_DC_Motor_Pin[1],0);
                analogWrite(Car_DC_Motor_Pin[2],RightSpeed);
                analogWrite(Car_DC_Motor_Pin[3],0);
                break;
    case Back:
                analogWrite(Car_DC_Motor_Pin[0],0);
                analogWrite(Car_DC_Motor_Pin[1],LeftSpeed);
                analogWrite(Car_DC_Motor_Pin[2],0);
                analogWrite(Car_DC_Motor_Pin[3],RightSpeed);
                break;  
    case Left:
                analogWrite(Car_DC_Motor_Pin[0],0);
                analogWrite(Car_DC_Motor_Pin[1],LeftSpeed);
                analogWrite(Car_DC_Motor_Pin[2],RightSpeed);
                analogWrite(Car_DC_Motor_Pin[3],0);
                break; 
    case Right:
                analogWrite(Car_DC_Motor_Pin[0],LeftSpeed);
                analogWrite(Car_DC_Motor_Pin[1],0);
                analogWrite(Car_DC_Motor_Pin[2],0);
                analogWrite(Car_DC_Motor_Pin[3],RightSpeed);
                break;  
    case Stop:
                analogWrite(Car_DC_Motor_Pin[0],LeftSpeed);
                analogWrite(Car_DC_Motor_Pin[1],LeftSpeed);
                analogWrite(Car_DC_Motor_Pin[2],RightSpeed);
                analogWrite(Car_DC_Motor_Pin[3],RightSpeed);
                break;                                             
  }
}

void Car_Move_Test()
{
  Car_Move(Forward,Forward_Left_Speed,Forward_Right_Speed);delay(1500);Car_Move(Stop,Car_speed_stop,Car_speed_stop);delay(1500);
  Car_Move(Back,Forward_Left_Speed,Forward_Right_Speed);delay(1500);Car_Move(Stop,Car_speed_stop,Car_speed_stop);delay(1500);
  Car_Move(Left,Left_Left_Speed,   Left_Right_Speed);delay(1500);Car_Move(Stop,Car_speed_stop,Car_speed_stop);delay(1500);
  Car_Move(Right,Right_Left_Speed,  Right_Right_Speed);delay(1500);Car_Move(Stop,Car_speed_stop,Car_speed_stop);delay(1500);
}

Hit_Ballon_Car.ino

 /*
 *=====================================================================================================*
 *实验接线:                                                                                            |
 *=====================================================================================================*
 *                       车头
 *   灰度传感器:     A2   A3   A4
 *                *----------------*
 *                |                |
 *                |                |
 *                |                | 
 *                |                | 右侧
 *         motor  |                | 车轮
 *          9,10  |                | 5,6
 *                |                |
 *                |                |
 *                |                | 
 *                |                | 
 *                |                | 
 *                *----------------*
 *                       车尾
 * 舵机接线:
 *         车头舵机:3
 *         气球舵机:4
 *         车尾舵机:8
 *
*/

#include<ServoTimer2.h>    //调用舵机库函数
ServoTimer2 myServo[3];    //声明舵机数组
#define TrackingSensorNum 3 //小车寻迹时使用的灰度传感器数量

#define Forward_Left_Speed 100  //小车前进时左轮速度
#define Forward_Right_Speed 90 //小车前进时右轮速度
#define Back_Left_Speed 110     //小车后退时左轮速度
#define Back_Right_Speed 90    //小车后退时右轮速度
#define Left_Left_Speed 235     //小车左转时左轮速度
#define Left_Right_Speed 240    //小车左转时右轮速度
#define Right_Left_Speed 235    //小车右转时左轮速度
#define Right_Right_Speed 240   //小车右转时右轮速度
#define Car_speed_stop 255
#define CAR_STOP_DELAY 500

int Gray_Three = 0;
int tracking_die = 0;
int color_detection_card = 10;
int color_detection_ballon = 0;
bool finish=true;
bool finish_all = true;

int Gray_SensorPin[3]={A4,A3,A2};//寻迹、检测路口传感器
int Car_Head_Gray_SensorPin_Num = sizeof(Gray_SensorPin)/sizeof(Gray_SensorPin[0]);//定义gray数量
int Car_DC_Motor_Pin[4] = {9,10,5,6};//直流电机引脚
int motor_num = sizeof(Car_DC_Motor_Pin) / sizeof(Car_DC_Motor_Pin[0]);//定义电机数量
int servo_port[3] = {3,8,12};//定义舵机引脚
int servo_num = sizeof(servo_port) / sizeof(servo_port[0]);//定义舵机数量
float value_init[3] = {30,5,165};//定义舵机初始角度

int f = 30; //定义舵机每个状态间转动的次数,以此来确定每个舵机每次转动的角度
enum{Forward=1,Back,Left,Right,Stop,ForwardSpeedDown,BackSpeedDown,ForwardRoad};//小车各种模式状态

void setup() {
  // put your setup code here, to run once:
  delay(1500);
  Serial.begin(9600);
  Motor_Sensor_Init();
  Servo_Init();
  Color_Init();
//  while(1){
//    Serialprint_gray_sensor_data_analogRead();
//  }
}

void loop() {
  // put your main code here, to run repeatedly: 
  Automatic_Tracking_analogRead();
  if(Gray_Three == 1)
  {
    Tracking_Automatic_Tracking(1300);
    Car_Move(Stop,Car_speed_stop,Car_speed_stop);delay(3000);
    return_color_card(); //小车走到色卡开始识别色卡

    Tracking_Automatic_Tracking(3300);Car_Move(Stop,Car_speed_stop,Car_speed_stop);delay(500);
    return_color_ballon();
    if(color_detection_card == color_detection_ballon){
      Zha_Qi_Qiu(3);
      finish = false;
      finish_all = false;
    }//小车走到第一个气球区域,并判断气球颜色。

    if(finish_all){
        Tracking_Automatic_Tracking(2800);Car_Move(Stop,Car_speed_stop,Car_speed_stop);delay(500);
        return_color_ballon();
        if( (color_detection_card == color_detection_ballon) && finish ){
          Zha_Qi_Qiu(3);
          finish = false;
          finish_all = false;
      }//小车走到第二个气球区域,并判断气球颜色。
    }

    if(finish_all){
        Tracking_Automatic_Tracking(3800);Car_Move(Stop,Car_speed_stop,Car_speed_stop);delay(500);
        return_color_ballon();
        if( (color_detection_card == color_detection_ballon) && finish ){
          Zha_Qi_Qiu(3);
          finish = false;
          finish_all = false;
      }//小车走到第三个气球区域,并判断气球颜色。
    }
    Car_Move(Stop,Car_speed_stop,Car_speed_stop);delay(3000); 
  }
}


void Zha_Qi_Qiu(int Numbers)
{
  for(int i=0;i<Numbers;i++)
  {
    Servo_Move_Single(1,10,145,2);  
    Servo_Move_Single(1,145,10,3);
  } 
}

posted @ 2021-12-02 09:22  卿源  阅读(1010)  评论(0)    收藏  举报