ardunio uno智能小车


#include <Arduino.h>


float geta00,geta01;
float geta0,geta1;
float geta02,geta12;
int geti=0;
int chei,ultrasonic_x_i;
float ultrasonic_x_old;
int pinultrasonic=12;

// 定义霍尔传感器输入引脚
int Pina0 = A0; 
int Pina1 = A1; 
int Pina2 = A4; 
int Pina2i = 0; 
int geta2=700;

int encoderPin1A = 2;
int encoderPin1B = 8;
int encoderPin2A = 3;
int encoderPin2B = 11;
long encoderCount1 = 0;
long encoderCount2 = 0;
float encoderspeed1 = 0;
float encoderspeed2 = 0;
float millisold=0;
// 定义pwm电磁铁输出引脚 
int pwm0 = 9;
int pwm1 = 10; 

struct _pid{
    float SetSpeed;            //定义设定期望值,目标值
    float ActualSpeed;        //定义实际值
    float err;                //定义偏差值
    float err_last;            //定义上一个偏差值
    float Kp,Ki,Kd;            //定义比例、积分、微分系数
    float voltage;            //定义电压值(控制执行器的变量)
    float integral;            //定义积分值
    float derivative;          //计算微分项
    float umax;
    float umin;

}pid0,pid1;
//电机298N
void motorModule(int pinDir1,int pinDir2, int pinPwm, int gspeed)
{
    pinMode(pinDir1, OUTPUT);
    pinMode(pinDir2, OUTPUT);
    if(gspeed==0){
        digitalWrite(pinDir1, 0);
        digitalWrite(pinDir2, 0);
    }else
    if(gspeed>0){
        digitalWrite(pinDir1, 1);
        digitalWrite(pinDir2, 0);
    }else
    if(gspeed<0){
        digitalWrite(pinDir1, 0);
        digitalWrite(pinDir2, 1);
    }
    analogWrite(pinPwm, abs(gspeed));//analogWrite(3, 200); pwm引脚3设置为200,
                                   //占空 比为abs(gspeed)/255=200/255
}
void motorModule2(int pinDir1,int pinDir2, int gspeed)
{
    pinMode(pinDir1, OUTPUT);
    pinMode(pinDir2, OUTPUT);
    if(gspeed==0){
        digitalWrite(pinDir1, 0);
        digitalWrite(pinDir2, 0);
    }else
    if(gspeed>0){
        digitalWrite(pinDir1, 1);
        digitalWrite(pinDir2, 0);
    }else
    if(gspeed<0){
        digitalWrite(pinDir1, 0);
        digitalWrite(pinDir2, 1);
    }
}
  
void settimer20(int pinDir1,int pinDir2,float ocr2a,float ocr2b,int mode,int timer)
{
  pinMode(pinDir1, OUTPUT); 
  pinMode(pinDir2, OUTPUT);

  if(timer==1)//timer1 ,10,9
  {
      //WGM12=1是相位修正,WGM10=1是8位
      if(mode==0)//快速8位
      {
         TCCR1A = _BV(COM1A1) | _BV(COM1B1) | _BV(WGM10);  
         TCCR1B = _BV(WGM12) | _BV(CS11) | _BV(CS10);
      }else
      if(mode==1)//相位修正8位
      {
         TCCR1A = _BV(COM1A1) | _BV(COM1B1) | _BV(WGM10);  
         TCCR1B = _BV(CS11) | _BV(CS10);  
      }
      //ICR1=0x00ff; //最大值

      OCR1AH =0x00;
      OCR1AL =abs((int)ocr2a); 
      OCR1BH =0x00;
      OCR1BL =abs((int)ocr2b); 
      //占空比 = (OCR1A / ICR1) * 100%

  }
  else
  if(timer==2)//timer2 ,11,3
  {
    if(mode==0)
    { //快速模式WGM设置为011 _BV(WGM21)
       TCCR2A = _BV(COM2A1) | _BV(COM2B1) | _BV(WGM21) | _BV(WGM20);  
       //波形产生模式。COM2A1,表示COM2A的第1位(从0开始)。
       //所以:_BV(COM2A1)表示COM2A = 10;_BV(WGM21) | _BV(WGM20) 表示 WGM2 = 011。
       TCCR2B = _BV(CS22);  
     //定时器的预除数,表示100,意为:CS22=1,CS21=0,CS20=0 分频为64
    }else
    if(mode==1)
    {//相位修正模式WGM设置为001,WGM20=1,这种模式频率接近降低了一倍,计算频率的时候要除以2 =/2
     TCCR2A = _BV(COM2A1) | _BV(COM2B1) | _BV(WGM20);  
     TCCR2B = _BV(CS22);  
  
    }else
    if(mode==2)
    {  // _BV(CS22)修改频率模式,OCRA用来设置总数,OCRB用来设置比较器,每次计数器数到头的时候,输出A做一次反相,这样能凑合输出一个占空比为50%的方波。因为A做了一次反向,最后计算要多除以2  =/2
     //在修改频率的模式下,时钟从0开始计数到OCRA而不是255,注意这个OCRA我们之前是用来做比较用的。这样一来,频率的设置就非常灵活了。对Timer1来说,OCRA可以设置到16位(应该是0~65535),计算的时候是除以修改值 /(180+1) 
     //快速PWM下,修改时钟的计数上限 WGM设置为111
     TCCR2A = _BV(COM2A0) | _BV(COM2B1) | _BV(WGM21) | _BV(WGM20);  
     TCCR2B = _BV(WGM22) | _BV(CS22);  
  
    }else
    if(mode==3)
    {  //相位修正PWM下,修改时钟的计数上限 WGM设置为101
       TCCR2A = _BV(COM2A0) | _BV(COM2B1) | _BV(WGM20);  
       TCCR2B = _BV(WGM22) | _BV(CS22);  
  
    }

  
    //Timer2所控制的管脚是pin11和pin3
    //Timer0控制5,6;
    //Timer1控制9,10
    //定时器速度(HZ) = Arduino UNO时钟速度(16MHz) / 预分频器系数
    //中断频率(Hz)=(Arduino时钟速度16MHz)/(预分频器*(比较匹配寄存器+ 1))
    //比较匹配寄存器= [16,000,000Hz /(预分频器*所需的中断频率)] - 1

    //主板频率是16 MHz 时钟都是从0计数到255
    //TCCR2B = _BV(CS22); 表示100,意为:CS22=1,CS21=0,CS20=0 分频为64
    //OCR2A = 180;  
    //输出 A 频率:   16 MHz / 64 / 256 = 976.5625Hz 16*1024*1024Hz/256 20kHz就听不到噪音
    //输出 A 占空比:     (180+1) / 256 = 70.7%
    //OCR2B = 50; 
    //输出 B 频率:   16 MHz / 64 / 256 = 976.5625Hz
    //输出 B 占空比:      (50+1) / 256 = 19.9%
    //表示两路输出的占空比=((int)ocr2a+1)/256

    OCR2A =abs((int)ocr2a); //决定连接到该引脚的pin11 PWM信号的占空比
    OCR2B =abs((int)ocr2b); //决定连接到该引脚的pin3 PWM信号的占空比
    Serial.print("OCR2A=");
    Serial.println(OCR2A);
    Serial.print("OCR2B=");
    Serial.println(OCR2B);
  }
 
}


//超声波测距
float ultrasonicSensor(int trigPin, int echoPin)
{
    float distance;
    unsigned int temp;
    pinMode(trigPin, OUTPUT); 
    digitalWrite(trigPin, LOW);
    delayMicroseconds(2);
    digitalWrite(trigPin, HIGH);
    delayMicroseconds(10);
    digitalWrite(trigPin, LOW);
    pinMode(echoPin, INPUT);
    temp = pulseIn(echoPin, HIGH);
    distance = (float)temp / 58.2;
    // un-comm this for nekomimi ultrasonic
    /*
    if(distance > 6){
      distance *= 1.28;
    }
    */
    if(distance == 0){ distance = 999; }
    return distance;
}

//履带车---------------------------------------------------------------
void smartcar_run(int speed1,int speed2,int delay0)//强度1,强度2,延时0
{

  settimer20(pwm0,pwm1,speed1,speed2,0,1);//设置力度
  motorModule2(4,5,speed1);
  motorModule2(6,7,speed2);
  delay(delay0);
}
void smartcar_forward(int speed,int delay0)
{

  smartcar_run(speed,speed,delay0);

}
void smartcar_backward(int speed,int delay0)
{
  smartcar_run(-speed,-speed,delay0);
}
void smartcar_right(int speed,int delay0)
{
   smartcar_run(speed,-speed,delay0);
}
void smartcar_left(int speed,int delay0)
{
   smartcar_run(-speed,speed,delay0);
}
void smartcar_stop()
{
   smartcar_run(0,0,0);
}

void smartcar_forward50(int delay0){  smartcar_run(50,50,delay0);}
void smartcar_forwardright10050(int delay0){  smartcar_run(100,50,delay0);}
void smartcar_forwardleft10050(int delay0){  smartcar_run(50,100,delay0);}
void smartcar_backward50(int delay0){  smartcar_run(-50,-50,delay0);}
void smartcar_right50(int delay0){   smartcar_run(50,-50,delay0);}
void smartcar_left50(int delay0){   smartcar_run(-50,50,delay0);}


//超声波取平均值
float smartcar_csb(int pin)
{
    int i=0;
    int ultrasonic_x=0;

    while (i<10)
    {
       ultrasonic_x=ultrasonic_x+ultrasonicSensor(pin,pin);//获取超声波测距,这个设置不能和其它引脚冲突,否则会发生问题
       if(ultrasonic_x>0) i++;
    }
    ultrasonic_x=ultrasonic_x/10;
    Serial.print("超声波=");
    Serial.println(ultrasonic_x);
    return ultrasonic_x;
}

//选择转向
void smartcar_select_leftright(int delay0)
{
   float csb1,csb2;
   smartcar_right50(delay0*2);
   csb1=smartcar_csb(pinultrasonic);
   smartcar_left50(delay0*4);
   csb2=smartcar_csb(pinultrasonic);
   if(csb1<csb2) {}
   else
   {
      smartcar_right50(delay0*4);
   }

}
//读取轮子
void smartcar_reads(float ultrasonic_x_c)
{
    noInterrupts();  // 禁止中断
    long gencoderCount1 = encoderCount1;
    long gencoderCount2 = encoderCount2;

    float gmillis=(float)millis();
    float smillis=gmillis-millisold;
    millisold=gmillis;
    encoderspeed1=(float)gencoderCount1*ultrasonic_x_c/(float)smillis;
    encoderspeed2=(float)gencoderCount2*ultrasonic_x_c/(float)smillis;
    encoderCount1=0;
    encoderCount2=0;
    Serial.print("Motor millis= ");
    Serial.println(smillis);
    Serial.print("Motor count1= ");
    Serial.print(gencoderCount1);
    Serial.print(" speed1= ");
    Serial.println(encoderspeed1);
    Serial.print("Motor count2= ");
    Serial.print(gencoderCount2);
    Serial.print(" speed2= ");
    Serial.println(encoderspeed2);
    interrupts();  // 允许中断
}

void updateEncoder1() 
{

  if (digitalRead(encoderPin1A) == digitalRead(encoderPin1B)) 
  {
     encoderCount1++;
  } 
  else 
  {
     encoderCount1--;
  }
}
void updateEncoder2() 
{

  if (digitalRead(encoderPin2A) == digitalRead(encoderPin2B)) 
  {
     encoderCount2--;
  } 
  else 
  {
     encoderCount2++;
  }
}

void geta_init_smartcar()
{
    ultrasonic_x_old=0;
    ultrasonic_x_i=0;

  pinMode(encoderPin1A, INPUT);  
  pinMode(encoderPin1B, INPUT);
  pinMode(encoderPin2A, INPUT);  
  pinMode(encoderPin2B, INPUT);
  attachInterrupt(digitalPinToInterrupt(encoderPin1A), updateEncoder1, CHANGE);
  attachInterrupt(digitalPinToInterrupt(encoderPin2A), updateEncoder2, CHANGE);
  interrupts();  // 允许中断
      // attachInterrupt(中断引脚,中断函数,CHANGE)
      //中断引脚只能用2引脚、3引脚,Arduino Uno具有两个外部中断引脚,分别是2号引脚(INT0)和3号引脚(INT1)
      //LOW: 当引脚为低电平时触发中断服务程序
      //CHANGE: 当引脚电平发生变化时触发中断服务程序
      //RISING: 当引脚电平由低电平变为高电平时触发中断服务程序
      //FALLING: 当引脚电平由高电平变为低电平时触发中断服务程序

}
void smartcar()//履带车
{
   int speed1,speed2,delay0;
   float ultrasonic_x_c;
   float speedrange=0.1*5;
   speed1=50;
   speed2=100;
   delay0=500;
   
   
   float ultrasonic_x=smartcar_csb(pinultrasonic);//超声波获取3个的平均值

   ultrasonic_x_c=ultrasonic_x_old-ultrasonic_x;
   ultrasonic_x_old=ultrasonic_x;

   smartcar_reads(abs(ultrasonic_x_c));//读取智能小车的轮子

   //开发板外接电源必须9v,作用板子上的电压才为5v
   //如果>30 就前进,否则就停止
   //如果被卡住,就后退,右转。
   //如果<=30 可以右转,也可以左转。
   //可以让其先右转,看看距离,再左转,看看距离,然后判断方向,

   if(ultrasonic_x>30) 
   {
       if((encoderspeed1>-speedrange && encoderspeed1<speedrange) || (encoderspeed2>-speedrange && encoderspeed2<speedrange))
           //正常范围在0.2左右,<0.1轮子转速慢,被阻挡,再*超声波测距,大约0.1*5
       {

               smartcar_stop();
               delay(100);
               smartcar_backward50(delay0*6);
               smartcar_select_leftright(delay0);
       }
       else
       {
           smartcar_forward50(delay0);
       }
       
   }
   else
   {
      smartcar_select_leftright(delay0);
   } 
   smartcar_stop();
   delay(10);

}
//-------------------------------------------------------------------
void setup(){

  chei=0;
  Serial.begin(9600);//串口初始化
  PID_init(&pid0);
  PID_init(&pid1);
  PID_SetSpeed(&pid0,0);
  PID_SetSpeed(&pid1,0);

  geta_init_smartcar();//履带车初始化

}

void loop()
{
    smartcar();//履带车
}

  • 5
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当然,我可以帮你提供一个基本的 Arduino 智能小车代码框架。请注意,这是一个简单的示例,你可以根据自己的需求进行修改和扩展。 ```cpp // 定义引脚 const int leftMotorPin1 = 2; const int leftMotorPin2 = 3; const int rightMotorPin1 = 4; const int rightMotorPin2 = 5; const int trigPin = 6; const int echoPin = 7; // 定义速度 const int motorSpeed = 200; // 设置引脚模式 void setup() { pinMode(leftMotorPin1, OUTPUT); pinMode(leftMotorPin2, OUTPUT); pinMode(rightMotorPin1, OUTPUT); pinMode(rightMotorPin2, OUTPUT); pinMode(trigPin, OUTPUT); pinMode(echoPin, INPUT); // 初始化串口通信 Serial.begin(9600); } // 主循环 void loop() { // 获取超声波测距值 long duration, distance; digitalWrite(trigPin, LOW); delayMicroseconds(2); digitalWrite(trigPin, HIGH); delayMicroseconds(10); digitalWrite(trigPin, LOW); duration = pulseIn(echoPin, HIGH); distance = duration / 58; // 输出距离值 Serial.print("Distance: "); Serial.print(distance); Serial.println(" cm"); // 根据距离控制小车运动 if (distance > 20) { moveForward(); delay(500); stopMotors(); delay(500); } else { turnRight(); delay(500); stopMotors(); delay(500); } } // 控制小车向前移动 void moveForward() { digitalWrite(leftMotorPin1, HIGH); digitalWrite(leftMotorPin2, LOW); digitalWrite(rightMotorPin1, HIGH); digitalWrite(rightMotorPin2, LOW); analogWrite(leftMotorPin2, motorSpeed); analogWrite(rightMotorPin2, motorSpeed); } // 控制小车停止 void stopMotors() { digitalWrite(leftMotorPin1, LOW); digitalWrite(leftMotorPin2, LOW); digitalWrite(rightMotorPin1, LOW); digitalWrite(rightMotorPin2, LOW); } // 控制小车向右转 void turnRight() { digitalWrite(leftMotorPin1, HIGH); digitalWrite(leftMotorPin2, LOW); digitalWrite(rightMotorPin1, LOW); digitalWrite(rightMotorPin2, HIGH); analogWrite(leftMotorPin2, motorSpeed); analogWrite(rightMotorPin2, motorSpeed); } ``` 上述代码是一个简单的智能小车示例,使用超声波测距模块控制小车的运动。根据测得的距离值,如果大于20cm,小车会向前移动一段时间后停止;如果距离小于等于20cm,小车会向右转一段时间后停止。你可以根据自己的实际需求修改代码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值