找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 14|回复: 0
收起左侧

基于arduino系统的pid循迹小车开发

[复制链接]
ID:1155871 发表于 2025-7-3 10:26 | 显示全部楼层 |阅读模式
该小车采用Arduino UNO主控制核心,通过传感器传来的信号,对当前环境作出判断,最后对电机做出相应的动作。单片机通过红外传感器检测场地黑线,从而控制电机驱动模块,改变电机转速来控制小车方向,从而达到循迹的目的
整个系统包括Arduino UNO主控板、电机驱动模块L298n、循迹传感器TCR5000L、锂电池(建议是可充放电的)和车体。

循迹代码:
float Kp , Ki = 0, Kd ;                         //pid弯道参数参数
float error = 0, P = 0, I = 0, D = 0, PID_value = 0;      //pid直道参数
float previous_error = 0, previous_I = 0;               //误差值
static int initial_motor_speed = 70;      //此处值为0-255的值,受电池电压影响,需要自己调试
int A[5] = {19, 18, 17, 16, 15};
double L, R;
float a, b, c, d, p, m;
int ena = 5;
int enb = 10;
void setup()
{
  Serial.begin(9600);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);

  pinMode(ena, OUTPUT);
  pinMode(enb, OUTPUT);

  pinMode(A1, INPUT);
  pinMode(A2, INPUT);
  pinMode(A3, INPUT);
  pinMode(A4, INPUT);
  pinMode(A5, INPUT);
}

void loop()
{
Kp =3.25;
    Kd =30;               //此处的Kp和Kd也需使用者根据车的结构和既定轨迹调试进行调试,
  m = 0;
  a = 3, b = 6, c = 11, d = 18, p = 1;
  trac_run();
}
void trac()
{
  unsigned char temp = 0b00000;       //临时变量用于新一轮采集
  for (int i = 0; i < 5; i++)
    temp |= digitalRead(A[ i]) << i;       //轮询5个传感器输出,并将查询结果转换为编码形式
  switch (temp)
  {
    case 0b01111: error = -d; break;
    case 0b00111: error = -c; break;
    case 0b10111: error = -b; break;
    case 0b10011: error = -a, m = 10; break;
    case 0b11011: error = 0, m = 20; break;
    case 0b11001: error = a, m = 10; break;
    case 0b11101: error = b; break;
    case 0b11100: error = c; break;
    case 0b11110: error = d; break;
    default: p = 1; break;
  }
}

void pid()
{
  P = error;
  I = I + error;
  D = error - previous_error;
  PID_value = (Kp * P) + (Ki * I) + (Kd * D);
  previous_error = error;
}

void trac_run()
{
  trac();
  pid();
  L = p * ( initial_motor_speed + PID_value + m);
  R = p * ( initial_motor_speed - PID_value + m);
  if (abs(L) > 255) L = L / abs(L) * 255;
  if (abs(R) > 255) R = R / abs(R) * 255;
  if (abs(L) == 0) L = 1;
  if (abs(R) == 0) R = 1;
  motor();
}

void motor()
{
  if (L > 0 && R > 0)
    analogWrite(enb, L),
                analogWrite(ena, R),
                motordir(0, 1, 1, 0);
  else if (- L > 0 && - R > 0)
    analogWrite(enb, -L),
                analogWrite(ena, -R),
                motordir(1, 0, 0, 1);
  else if (- L > 0 && R > 0)
    analogWrite(enb, -L),
                analogWrite(ena, R),
                motordir(0, 1, 0, 1);
  else if (L > 0 && -R > 0)
    analogWrite(enb, L),
                analogWrite(ena, -R),
                motordir(1, 0, 1, 0);
  else

    motordir(0, 0, 0, 0);
}

void motordir(int out1, int out2, int out3, int out4)   //输入1 0,控制方向
{
  digitalWrite(6, out1);
  digitalWrite(7, out2);
  digitalWrite(8, out3);
  digitalWrite(9, out4);
}


整体图

整体图

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

Powered by 单片机教程网

快速回复 返回顶部 返回列表