arduino uno四路红外2轮循线小车(含PID算法)

电机驱动采用的是DRV8833直流驱动模块,可以直接替换TB6612驱动模块,管脚基本完全兼容。

我把4路红外循线模块的高低电平分别对应1和0,然后有轻度偏离(0010,0100)、中度偏离(1100,1110,0111,0011)、重度偏离(1000和0001)这几种情况,然后根据偏离程度不同分别采取不同的误差err,左右偏离分别取正负,因为PWM范围在0~255,因此为了防止err过大或过小导致PWM大于255或者小于0,故需要添加if语句比如:当PWM大于130或者小于10时直接令PWM为你设定的阈值。

当然也可以不用PID算法,但是用了PID小车更加稳定不需要频繁的去更改速度来应对不同的路线,反之用了PID算法可以应对许多情况当你把KP,KI,KD设置好后可以应对许多不同的路线不需要再频繁的去调节速度。我这里只用了PD,所以强烈推荐学习PID。

PID我推荐这篇文章讲的真的通俗易懂:PID算法通俗解释_冬日黎明的博客-CSDN博客_pid算法通俗讲解啥是PID?PID,就是“比例(proportional)、积分(integral)、微分(derivative)”,是一种很常见的控制算法。在工程实际中,应用最为广泛的调节器控制规律为比例、积分、微分控制,简称PID控制,又称PID调节。它以其结构简单、稳定性好、工作可靠、调整方便而成为工业控制的主要技术之一。算法是不可以吃的。PID已经有107年的历史了。它并不是什么很神圣的东西,大家一定都见过PID的实际应用。比如四轴飞行器,再比如平衡小车......还有汽...https://blog.csdn.net/tangdongming/article/details/107746975

代码如下:

int Left_motor_back=2; //左电机后退
int Left_motor_go=3; //左电机前进

int Right_motor_back=4; // 右电机后退
int Right_motor_go=5; // 右电机前进

const int SensorRight1=6;//红外循线模块
const int SensorRight2=7;
const int SensorLeft1=8;
const int SensorLeft2=9;

int S1;
int S2;
int S3;
int S4;

float err,last_err=0;
float P,D;

int v=70;//基础速度可以自己调节

int kp=20,kd=10;//系数需要自己调节

void setup()
{
  //初始化电机驱动IO为输出方式
  pinMode(Left_motor_go,OUTPUT);
  pinMode(Left_motor_back,OUTPUT);

  pinMode(Right_motor_go,OUTPUT);
  pinMode(Right_motor_back,OUTPUT);

  pinMode(SensorRight1, INPUT);
  pinMode(SensorRight2, INPUT);
  pinMode(SensorLeft1, INPUT);
  pinMode(SensorLeft2, INPUT);
}

//=======================智能小车的基本动作=========================

void run(int x)//小车驱动
{
  int v1,v2;
  v1=v-x;
  v2=v+x;
  
  if(v1>=130)
  v1==130;
  if(v1<=10)
  v1==10;
  
  if(v2>=130)
  v2==130;
  if(v2<=10)
  v2==10;
  
  digitalWrite(Right_motor_back,LOW);//控制右电机
  digitalWrite(Right_motor_go,HIGH);

  analogWrite(Right_motor_back,0);
  analogWrite(Right_motor_go,v1);

  digitalWrite(Left_motor_back,LOW);//控制左电机
  digitalWrite(Left_motor_go,HIGH);

  analogWrite(Left_motor_back,0);
  analogWrite(Left_motor_go,v2);

  delay(5); //执行时间,可以调整
}

void brake()//电机停止,刹车
{
  digitalWrite(Right_motor_go,LOW);
  digitalWrite(Right_motor_back,LOW);
  digitalWrite(Left_motor_go,LOW);
  digitalWrite(Left_motor_back,LOW);  
}

int pid()//PD算法
{
  int output;
  P=err;
  D=err-last_err;
  output=kp*P+kd*D; 
  last_err=err;
  return output;
}

void loop()
{

  S1 = digitalRead(SensorRight1);
  S2 = digitalRead(SensorRight2);
  S3 = digitalRead(SensorLeft1);
  S4 = digitalRead(SensorLeft2);
//一共8种情况
  if(S1==LOW&&S2==LOW&&S3==LOW&&S4==LOW)//0000此时小车未在线上电机停止
  brake();
  else 
 {
  if(S1==HIGH&&S2==LOW&&S3==LOW&&S4==LOW)//1000小车重度偏右,需要向左大幅度偏转
  err=3;
  else if((S1==HIGH&&S2==HIGH&&S3==LOW&&S4==LOW)||(S1==HIGH&&S2==HIGH&&S3==HIGH&&S4==LOW))//1100  1110小车中度偏右
  err=2;
  else if(S1==LOW&&S2==HIGH&&S3==LOW&&S4==LOW)//0100小车轻度偏右
  err=1;
  else if((S1==LOW&&S2==HIGH&&S3==HIGH&&S4==LOW)||(S1==HIGH&&S2==HIGH&&S3==HIGH&&S4==HIGH))//0110  1111小车居中直行
  err=0;
  else if(S1==LOW&&S2==LOW&&S3==HIGH&&S4==LOW)//0010小车轻度偏左
  err=-1;
  else if((S1==LOW&&S2==LOW&&S3==HIGH&&S4==HIGH)||(S1==LOW&&S2==HIGH&&S3==HIGH&&S4==HIGH))//0011  0111小车中度偏左
  err=-2;
  else if(S1==LOW&&S2==LOW&&S3==LOW&&S4==HIGH)//0001小车重度偏左,需要向右大幅度偏转
  err=-3;

  run(pid());
 }
}

  • 7
    点赞
  • 135
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值