一、实现目标
本项目使用五路循迹模块,能实现闭环赛道的简单循迹。(如下图)
五路循迹模块含有5个传感器,用于判断路况。赛道使用黑色胶带搭建,背景使用白色或者反射性强的,以便传感器能准确检测。
二、使用配件
Arduino uno R3开发板
L298N电机驱动模块
TCRT5000五路循迹模块
小车模块
杜邦线若干、六角铜柱、螺丝螺母若干
以上配件均可在某宝购买。
三、小车的安装与调试
(本图仅供参考)
L298N电机驱动模块的连接:out1,out2,out3,out4分别连接两个马达的两端,注意正反,IN1,IN2,IN3,IN4分别连接开发板上的引脚2,4,7,8。左右两端的使能端需要拔掉键帽,再用杜邦线连接,ENA,ENB分别连接开发板上的引脚3和5。12v电源端接电源正极,5v电源端接开发板上的5v,用于给开发板供电,GND接地。
TCRT5000五路循迹模块的连接:5v电源端接开发板上的5v,GND接地。out1,2,3,4,5分别接引脚9,10,11,12,13。
连接完成
以下是测试代码(使用Arduino IDE进行编译,烧录),可以控制小车前进,左转,右转,后退,停车。
const int IN_A1 = 2;
const int PWM_A = 3;
const int IN_A2 = 4;
const int PWM_B = 5;
const int IN_B1 = 7;
const int IN_B2 = 8;
void setup() {
pinMode(IN_A1, OUTPUT);
pinMode(IN_A2, OUTPUT);
pinMode(IN_B1, OUTPUT);
pinMode(IN_B2, OUTPUT);
}
void moveLeft(void)
{
digitalWrite(IN_A1, LOW);
digitalWrite(IN_B1, HIGH);
digitalWrite(IN_A2, LOW);
digitalWrite(IN_B2, LOW);
analogWrite(PWM_A, 255);
analogWrite(PWM_B, 255);
}
void moveRight(void)
{
digitalWrite(IN_A1, HIGH);
digitalWrite(IN_B1, LOW);
digitalWrite(IN_A2, LOW);
digitalWrite(IN_B2, LOW);
analogWrite(PWM_A, 255);
analogWrite(PWM_B, 255);
}
void moveForward(void)
{
digitalWrite(IN_A1, HIGH);
digitalWrite(IN_B1, HIGH);
digitalWrite(IN_A2, LOW);
digitalWrite(IN_B2, LOW);
analogWrite(PWM_A, 255);
analogWrite(PWM_B, 255);
}
void moveBackward(void)
{
digitalWrite(IN_A1, LOW);
digitalWrite(IN_B1, LOW);
digitalWrite(IN_A2, HIGH);
digitalWrite(IN_B2, HIGH);
analogWrite(PWM_A, 255);
analogWrite(PWM_B, 255);
}
void stopCar(void)
{
digitalWrite(IN_A1, LOW);
digitalWrite(IN_B1, LOW);
digitalWrite(IN_A2, LOW);
digitalWrite(IN_B2, LOW);
analogWrite(PWM_A, 255);
analogWrite(PWM_B, 255);
}
void loop() {
moveForward();
delay(3000);
moveLeft();
delay(3000);
moveRight();
delay(3000);
moveBackward();
delay(3000);
stopCar();
delay(3000);
}
测试电机没问题后,还要对循迹模块进行测试,用六角铜柱连接以保证离地间距,在比较光洁的地面上,5个灯应该是全亮的状态。然后用手或者黑色胶带放到每个模块下,观察灯是否熄灭,逐一测试,没问题后可以进行下一步。(注意:灯亮代表1,灯灭代表0)
四、循迹
搭建好赛道,就可以放上小车进行循迹了。下面是代码:
const int IN_A1 = 2;
const int PWM_A = 3;
const int IN_A2 = 4;
const int PWM_B = 5;
const int IN_B1 = 7;
const int IN_B2 = 8;
const int sensor1 = 9;
const int sensor2 = 10;
const int sensor3 = 11;
const int sensor4 = 12;
const int sensor5 = 13;
int sensor[5] = {0, 0, 0, 0, 0};
float Kp = 30, Ki = 10, Kd = 1;
float error = 0, P = 0, I = 0, D = 0, PID_value = 0;
float previous_error = 0, previous_I = 0;
int DIN_A1 = 100;
int DIN_B1 = 100;
void setup() {
Serial.begin(9600);
pinMode(IN_A1, OUTPUT);
pinMode(IN_A2, OUTPUT);
pinMode(IN_B1, OUTPUT);
pinMode(IN_B2, OUTPUT);
pinMode(sensor1, INPUT);
pinMode(sensor2, INPUT);
pinMode(sensor3, INPUT);
pinMode(sensor4, INPUT);
pinMode(sensor5, INPUT);
}
void loop() {
sensor[0] = digitalRead(sensor1);
sensor[1] = digitalRead(sensor2);
sensor[2] = digitalRead(sensor3);
sensor[3] = digitalRead(sensor4);
sensor[4] = digitalRead(sensor5);
if (sensor[0] == 0 && 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) {
error = -2;
} else if (sensor[1] == 0 && sensor[0] != 0 && sensor[2] != 0 && sensor[3] != 0 && sensor[4] != 0) {
error = -1;
} else if (sensor[1] == 0 && sensor[0] != 0 && sensor[2] == 0 && sensor[3] != 0 && sensor[4] != 0) {
error = -1;
} else if (sensor[2] == 0 && sensor[1] != 0 && sensor[0] != 0 && sensor[3] != 0 && sensor[4] != 0) {
error = 0;
} else if (sensor[2] == 0 && sensor[1] == 0 && sensor[0] != 0 && sensor[3] == 0 && sensor[4] != 0) {
error = 0;
} else if (sensor[3] == 0 && sensor[1] != 0 && sensor[2] != 0 && sensor[0] != 0 && sensor[4] != 0) {
error = 1;
} else if (sensor[3] == 0 && sensor[1] != 0 && sensor[2] == 0 && sensor[0] != 0 && sensor[4] != 0) {
error = 1;
} else if (sensor[4] == 0 && sensor[1] != 0 && sensor[2] != 0 && sensor[3] == 0 && sensor[0] != 0) {
error = 2;
} else if (sensor[4] == 0 && sensor[1] != 0 && sensor[2] != 0 && sensor[3] != 0 && sensor[0] != 0) {
error = 2;
} else {
error = 0;
}
P = error;
I = I + previous_I;
D = error - previous_error;
PID_value = (Kp * P) + (Ki * I) + (Kd * D);
previous_I = I;
previous_error = error;
int left_motor_speed = DIN_A1 - PID_value;
int right_motor_speed = DIN_B1 + PID_value;
constrain(left_motor_speed, 0, 255);
constrain(right_motor_speed, 0, 255);
digitalWrite(IN_A2, HIGH);
digitalWrite(IN_B2, HIGH);
digitalWrite(IN_A1, LOW);
digitalWrite(IN_B1, LOW);
analogWrite(PWM_A, DIN_A1 - PID_value);
analogWrite(PWM_B, DIN_B1 + PID_value);
}
烧入Arduino开发板,大功告成。