智能循迹小车实现方案
一、系统概述
智能循迹小车通过红外传感器检测地面黑色轨迹线,由微控制器处理传感器数据并控制电机实现自动循迹行驶。
二、硬件组件清单
核心控制模块
- 主控板:Arduino UNO R3(或STM32、ESP32)
- 电机驱动模块:L298N双H桥直流电机驱动板
- 循迹传感器:TCRT5000红外反射传感器 ×4-5个
- 电源系统:
- 18650锂电池 ×2(7.4V)
- 5V降压模块(LM2596)
- 开关电源模块
执行机构
- 直流减速电机:TT马达 ×2(3-6V,减速比1:48)
- 车轮:65mm橡胶轮 ×2
- 万向轮:1个(前部支撑)
辅助组件
- 车体底盘:亚克力或铝合金底盘
- 杜邦线:公对公、公对母若干
- 传感器支架:可调节高度的安装支架
三、电路连接图
电源连接
锂电池(7.4V) → L298N(12V输入) → 5V输出 → Arduino VIN
↓
LM2596降压 → 传感器组(5V)
传感器连接(4路方案)
TCRT5000模块引脚 → Arduino引脚
VCC → 5V
GND → GND
DO1(最左) → A0
DO2(左中) → A1
DO3(右中) → A2
DO4(最右) → A3
电机驱动连接
L298N模块 → Arduino → 电机
ENA → 5(PWM控制左轮速度)
IN1 → 6(左轮方向1)
IN2 → 7(左轮方向2)
ENB → 10(PWM控制右轮速度)
IN3 → 8(右轮方向1)
IN4 → 9(右轮方向2)
OUT1/OUT2 → 左电机正负极
OUT3/OUT4 → 右电机正负极
完整接线示意图
┌─────────────────────────────────────────────┐
│ 智能循迹小车电路连接图 │
├─────────────────────────────────────────────┤
│ 锂电池7.4V │
│ │ │
│ ├─→ L298N(12V输入) │
│ │ ├─5V输出→Arduino VIN │
│ │ ├─OUT1/2→左电机 │
│ │ └─OUT3/4→右电机 │
│ │ │
│ └─→ LM2596(降压至5V)→传感器组VCC │
│ │
│ Arduino UNO引脚分配: │
│ 数字引脚: │
│ 5(ENA) 6(IN1) 7(IN2) → L298N左电机控制 │
│ 8(IN3) 9(IN4) 10(ENB) → L298N右电机控制 │
│ │
│ 模拟引脚: │
│ A0-A3 → TCRT5000传感器DO输出 │
└─────────────────────────────────────────────┘
四、核心程序代码(Arduino)
基础循迹程序(4传感器)
/*
* 智能循迹小车程序
* 使用4路TCRT5000红外传感器
* L298N电机驱动模块
*/
// 电机控制引脚定义
#define ENA 5 // 左电机PWM速度控制
#define IN1 6 // 左电机方向1
#define IN2 7 // 左电机方向2
#define ENB 10 // 右电机PWM速度控制
#define IN3 8 // 右电机方向1
#define IN4 9 // 右电机方向2
// 传感器引脚定义
#define SENSOR_LEFT A0 // 最左侧传感器
#define SENSOR_MID_LEFT A1 // 左侧传感器
#define SENSOR_MID_RIGHT A2 // 右侧传感器
#define SENSOR_RIGHT A3 // 最右侧传感器
// 速度参数(PWM值,0-255)
#define BASE_SPEED 150 // 基础速度
#define TURN_SPEED 180 // 转弯速度
#define SLOW_SPEED 100 // 慢速
// 传感器阈值(根据实际调整)
#define SENSOR_THRESHOLD 500 // 黑白区分阈值
// 传感器状态变量
int sensorLeft, sensorMidLeft, sensorMidRight, sensorRight;
int sensorValues[4]; // 存储传感器值
void setup() {
Serial.begin(9600);
// 初始化电机控制引脚
pinMode(ENA, OUTPUT);
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
pinMode(ENB, OUTPUT);
pinMode(IN3, OUTPUT);
pinMode(IN4, OUTPUT);
// 初始化传感器引脚
pinMode(SENSOR_LEFT, INPUT);
pinMode(SENSOR_MID_LEFT, INPUT);
pinMode(SENSOR_MID_RIGHT, INPUT);
pinMode(SENSOR_RIGHT, INPUT);
// 初始停止状态
stopCar();
delay(1000);
Serial.println("智能循迹小车启动完成!");
}
void loop() {
// 1. 读取传感器数据
readSensors();
// 2. 显示传感器状态(调试用)
displaySensorStatus();
// 3. 根据传感器状态控制小车
lineFollowing();
// 短暂延迟
delay(10);
}
// 读取所有传感器值
void readSensors() {
sensorLeft = analogRead(SENSOR_LEFT);
sensorMidLeft = analogRead(SENSOR_MID_LEFT);
sensorMidRight = analogRead(SENSOR_MID_RIGHT);
sensorRight = analogRead(SENSOR_RIGHT);
// 转换为二值化数据(0:白线,1:黑线)
sensorValues[0] = (sensorLeft > SENSOR_THRESHOLD) ? 1 : 0;
sensorValues[1] = (sensorMidLeft > SENSOR_THRESHOLD) ? 1 : 0;
sensorValues[2] = (sensorMidRight > SENSOR_THRESHOLD) ? 1 : 0;
sensorValues[3] = (sensorRight > SENSOR_THRESHOLD) ? 1 : 0;
}
// 显示传感器状态
void displaySensorStatus() {
Serial.print("传感器状态: ");
Serial.print(sensorValues[0]);
Serial.print(" ");
Serial.print(sensorValues[1]);
Serial.print(" ");
Serial.print(sensorValues[2]);
Serial.print(" ");
Serial.print(sensorValues[3]);
Serial.println();
}
// 循迹控制逻辑
void lineFollowing() {
// 情况1:正常在轨迹上(中间两个传感器检测到黑线)
if (sensorValues[1] == 1 && sensorValues[2] == 1) {
forward(BASE_SPEED);
Serial.println("状态:直行");
}
// 情况2:轻微左偏(只有左侧传感器检测到)
else if (sensorValues[0] == 1 && sensorValues[1] == 1) {
turnLeft(TURN_SPEED);
Serial.println("状态:左转修正");
}
// 情况3:轻微右偏(只有右侧传感器检测到)
else if (sensorValues[2] == 1 && sensorValues[3] == 1) {
turnRight(TURN_SPEED);
Serial.println("状态:右转修正");
}
// 情况4:大幅左偏(只有最左侧传感器检测到)
else if (sensorValues[0] == 1) {
sharpLeft(TURN_SPEED);
Serial.println("状态:急左转");
}
// 情况5:大幅右偏(只有最右侧传感器检测到)
else if (sensorValues[3] == 1) {
sharpRight(TURN_SPEED);
Serial.println("状态:急右转");
}
// 情况6:丢失轨迹(所有传感器都检测到白色)
else if (sensorValues[0] == 0 && sensorValues[1] == 0 &&
sensorValues[2] == 0 && sensorValues[3] == 0) {
// 尝试寻找轨迹
searchLine();
Serial.println("状态:寻找轨迹");
}
// 情况7:十字路口(所有传感器都检测到黑色)
else if (sensorValues[0] == 1 && sensorValues[1] == 1 &&
sensorValues[2] == 1 && sensorValues[3] == 1) {
handleCrossroad();
Serial.println("状态:十字路口");
}
}
// 电机控制函数
void forward(int speed) {
// 左电机前进
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
analogWrite(ENA, speed);
// 右电机前进
digitalWrite(IN3, HIGH);
digitalWrite(IN4, LOW);
analogWrite(ENB, speed);
}
void backward(int speed) {
// 左电机后退
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
analogWrite(ENA, speed);
// 右电机后退
digitalWrite(IN3, LOW);
digitalWrite(IN4, HIGH);
analogWrite(ENB, speed);
}
void turnLeft(int speed) {
// 左电机慢速或停止
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
analogWrite(ENA, speed * 0.3);
// 右电机正常速度
digitalWrite(IN3, HIGH);
digitalWrite(IN4, LOW);
analogWrite(ENB, speed);
}
void turnRight(int speed) {
// 左电机正常速度
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
analogWrite(ENA, speed);
// 右电机慢速或停止
digitalWrite(IN3, HIGH);
digitalWrite(IN4, LOW);
analogWrite(ENB, speed * 0.3);
}
void sharpLeft(int speed) {
// 左电机后退
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
analogWrite(ENA, speed * 0.5);
// 右电机前进
digitalWrite(IN3, HIGH);
digitalWrite(IN4, LOW);
analogWrite(ENB, speed);
}
void sharpRight(int speed) {
// 左电机前进
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
analogWrite(ENA, speed);
// 右电机后退
digitalWrite(IN3, LOW);
digitalWrite(IN4, HIGH);
analogWrite(ENB, speed * 0.5);
}
void stopCar() {
digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW);
digitalWrite(IN3, LOW);
digitalWrite(IN4, LOW);
analogWrite(ENA, 0);
analogWrite(ENB, 0);
}
// 寻找轨迹(当丢失轨迹时)
void searchLine() {
// 先停止
stopCar();
delay(100);
// 尝试向左转寻找
turnLeft(SLOW_SPEED);
delay(200);
// 检查是否找到轨迹
readSensors();
if (sensorValues[1] == 1 || sensorValues[2] == 1) {
return; // 找到轨迹
}
// 如果没找到,尝试向右转
stopCar();
delay(100);
turnRight(SLOW_SPEED);
delay(400);
// 再次检查
readSensors();
if (sensorValues[1] == 1 || sensorValues[2] == 1) {
return; // 找到轨迹
}
// 如果还没找到,后退一点
backward(SLOW_SPEED);
delay(300);
stopCar();
}
// 处理十字路口
void handleCrossroad() {
// 这里可以根据需要实现不同的十字路口处理策略
// 示例:直行通过
forward(BASE_SPEED);
delay(500); // 通过十字路口的时间
// 或者:右转
// turnRight(TURN_SPEED);
// delay(300);
// forward(BASE_SPEED);
// delay(200);
}
高级版本(带PID控制)
/*
* PID循迹控制版本
* 提供更平滑的循迹效果
*/
// PID参数
float Kp = 25; // 比例系数
float Ki = 0.1; // 积分系数
float Kd = 15; // 微分系数
float error = 0, lastError = 0;
float P = 0, I = 0, D = 0;
float PID_value = 0;
// 电机基础速度
int leftMotorSpeed = 0;
int rightMotorSpeed = 0;
int motorBaseSpeed = 150;
void pidLineFollowing() {
// 计算误差值(-3到+3)
error = calculateError();
// PID计算
P = error;
I = I + error;
D = error - lastError;
PID_value = (Kp * P) + (Ki * I) + (Kd * D);
lastError = error;
// 计算电机速度
leftMotorSpeed = motorBaseSpeed - PID_value;
rightMotorSpeed = motorBaseSpeed + PID_value;
// 限制速度范围
leftMotorSpeed = constrain(leftMotorSpeed, 0, 255);
rightMotorSpeed = constrain(rightMotorSpeed, 0, 255);
// 设置电机速度
setMotorSpeed(leftMotorSpeed, rightMotorSpeed);
}
// 计算误差值
int calculateError() {
int errorValue = 0;
// 传感器权重分配
// 从左到右:-3, -1, +1, +3
if (sensorValues[0] == 1) errorValue = -3;
else if (sensorValues[1] == 1) errorValue = -1;
else if (sensorValues[2] == 1) errorValue = 1;
else if (sensorValues[3] == 1) errorValue = 3;
else errorValue = lastError; // 保持上次误差
return errorValue;
}
// 设置电机速度
void setMotorSpeed(int leftSpeed, int rightSpeed) {
// 左电机
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
analogWrite(ENA, leftSpeed);
// 右电机
digitalWrite(IN3, HIGH);
digitalWrite(IN4, LOW);
analogWrite(ENB, rightSpeed);
}
参考代码 智能循迹小车电路图和程序及仿真图 www.youwenfan.com/contentcnt/134324.html
五、调试与优化建议
1. 传感器校准
void calibrateSensors() {
Serial.println("开始传感器校准...");
Serial.println("将传感器放在白色区域,按任意键继续");
while(!Serial.available());
int whiteValues[4];
readRawSensors();
for(int i=0; i<4; i++) whiteValues[i] = sensorRaw[i];
Serial.println("将传感器放在黑色轨迹上,按任意键继续");
while(!Serial.available());
int blackValues[4];
readRawSensors();
for(int i=0; i<4; i++) blackValues[i] = sensorRaw[i];
// 计算阈值
for(int i=0; i<4; i++) {
thresholds[i] = (whiteValues[i] + blackValues[i]) / 2;
Serial.print("传感器");
Serial.print(i);
Serial.print("阈值:");
Serial.println(thresholds[i]);
}
}
2. 常见问题解决
| 问题现象 | 可能原因 | 解决方案 |
|---|---|---|
| 小车左右摇摆 | PID参数不合适 | 减小Kp,增加Kd |
| 无法检测黑线 | 传感器距离地面太远 | 调整传感器高度至5-10mm |
| 电机不转或反转 | 接线错误 | 检查IN1-IN4接线顺序 |
| 电源重启 | 电流不足 | 使用更大容量电池或电容滤波 |
3. 扩展功能建议
- 蓝牙遥控:添加HC-05/06模块实现手机控制
- 超声波避障:增加HC-SR04模块实现避障功能
- 速度编码器:安装光电编码器实现精确速度控制
- OLED显示:添加0.96寸OLED显示传感器状态和速度
- 多模式切换:增加按键实现手动/自动模式切换
六、轨迹制作建议
- 轨迹材料:黑色电工胶带(宽度15-20mm)
- 背景要求:浅色平整地面(白色或浅灰色)
- 转弯半径:最小半径建议≥15cm
- 交叉角度:十字路口90度垂直交叉
七、安全注意事项
- 确保所有接线牢固,避免短路
- 锂电池充电使用专用充电器
- 调试时小车架空,避免意外启动
- 电机堵转时间不超过10秒,防止烧毁

浙公网安备 33010602011771号