循迹小车

记得09年时候,还不会单片机,专业课也还没开单片机的课,想做个循迹和避障小车。网上搜资料,发现ardunio非常不错,简单好入门,x宝花了一百多块买了一个Arduino Uno和一个USBtinyISP开启了我的DIY之路。现在x宝上各种模块都全了,价格也便宜。

一、硬件配置

1.Arduino pro mini 主控板x1,价格:8.4元;


2.电机驱动L9110S直流电机驱动板x1,价格:2.35元


3.红外对管传感器x5,价格:1.35x5=6.75元


4.CP2102 USB转TTL模块x1,价格:5.5元


5.RT4智能小车底盘x1,价格:22.45元


6.5V稳压电源模块x1(我是用了一个以前项目的板子,有5V输出),价格:2.28元


7.杜板线若干、18650电池两节、万能板、电工黑胶带和一些其他基本的工具;


二、程序

float Kp = 10, Ki = 0.5, Kd = 0;
float error = 0, P = 0, I = 0, D = 0, PID_value = 0;
float previous_error = 0, previous_I = 0;
int sensor[5] = {0, 0, 0, 0, 0};
static int initial_motor_speed = 60;

void read_sensor_values(void);
void calc_pid(void);
void motor_control(void);

// The pins used:
const int IN_A1 = 3;   // Motor A input A
const int IN_A2 = 9;   // Motor A input B
const int IN_B1 = 10;  // Motor B input A
const int IN_B2 = 11;  // Motor B input B

void setup()
{
  // set up motor control pins as output
  pinMode(IN_A1, OUTPUT);
  pinMode(IN_A2, OUTPUT);
  pinMode(IN_B1, OUTPUT);
  pinMode(IN_B2, OUTPUT);

  pinMode(4, INPUT);
  pinMode(5, INPUT);
  pinMode(6, INPUT);
  pinMode(7, INPUT);
  pinMode(8, INPUT);
  
  Serial.begin(9600); //Enable Serial Communications
}

void loop()
{
  read_sensor_values();
  calc_pid();
  motor_control();
}

//速度设定范围(-255,255)
void motorsWrite(int speedL, int speedR)
{
  if (speedR > 0) {
    analogWrite(IN_A1, speedR);
    analogWrite(IN_A2, 0);
  } else {
    analogWrite(IN_A1, 0);
    analogWrite(IN_A2, -speedR);
  }

  if (speedL > 0) {
    analogWrite(IN_B1, speedL);
    analogWrite(IN_B2, 0);
  } else {
    analogWrite(IN_B1, 0);
    analogWrite(IN_B2, -speedL);
  }
}

//速度设定范围(-100,100)
void motorsWritePct(int speedLpct, int speedRpct) {
  //speedLpct, speedRpct ranges from -100 to 100
  motorsWrite(speedLpct * 2.55, speedRpct * 2.55);
}
void motorsStop() {
  analogWrite(IN_A1, 0);
  analogWrite(IN_A2, 0);

  analogWrite(IN_B1, 0);
  analogWrite(IN_B2, 0);
}

void read_sensor_values()
{
  sensor[0] = digitalRead(4);
  sensor[1] = digitalRead(5);
  sensor[2] = digitalRead(6);
  sensor[3] = digitalRead(7);
  sensor[4] = digitalRead(8);

    if ((sensor[0] == 0) && (sensor[1] == 0) && (sensor[2] == 0) && (sensor[3] == 0) && (sensor[4] == 1)) {
      error = 2;
    } else if ((sensor[0] == 0) && (sensor[1] == 0) && (sensor[2] == 0) && (sensor[3] == 1) && (sensor[4] == 0)) {
      error = 1;
    } else if ((sensor[0] == 0) && (sensor[1] == 0) && (sensor[2] == 1) && (sensor[3] == 0) && (sensor[4] == 0)) {
      error = 0;
    } else if ((sensor[0] == 0) && (sensor[1] == 1) && (sensor[2] == 0) && (sensor[3] == 0) && (sensor[4] == 0)) {
      error = -1;
    } else if ((sensor[0] == 1) && (sensor[1] == 0) && (sensor[2] == 0) && (sensor[3] == 0) && (sensor[4] == 0)) {
      error = -2;
    } else if ((sensor[0] == 0) && (sensor[1] == 0) && (sensor[2] == 0) && (sensor[3] == 0) && (sensor[4] == 0)) {
      if (error == -2) {
        error = -3;
      }else{
        error = 3;
      }
    }
}

void calc_pid()
{
  P = error;
  I = I + error;
  D = error - previous_error;

  PID_value = (Kp * P) + (Ki * I) + (Kd * D);

  previous_error = error;
}

void motor_control()
{
  int left_motor_speed = initial_motor_speed - PID_value;
  int right_motor_speed = initial_motor_speed + PID_value;
  
  if(left_motor_speed < -255){
    left_motor_speed = -255;
  }
  if(left_motor_speed > 255){
    left_motor_speed = 255;
  }
  motorsWrite(left_motor_speed,right_motor_speed);

  Serial.print("move_A: ");
  Serial.print(left_motor_speed, OCT);
  Serial.print(" move_B: ");
  Serial.print(right_motor_speed, OCT);
  Serial.print(" error: ");
  Serial.print(error, OCT);
  Serial.print(" P: ");
  Serial.print(Kp, OCT);
  Serial.print(" PID_value: ");
  Serial.print(PID_value, OCT);
  Serial.println();
}

三、计划改进

加入nrf24l01模块实现无线串口连接。


四、完成图片




  • 10
    点赞
  • 52
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值