硬件连接概述
在提供代码之前,我们先明确一下各个模块的连接方式,这是正确运行代码的基础。

(图片来源网络,侵删)
核心组件
- Arduino 主板 (如 Arduino UNO R3)
- L298N 电机驱动模块:用于控制两个直流电机。
- 循迹模块 (TCRT5000 x2):通常是一个包含5个红外传感器的模块,我们这里使用最外侧的两个传感器(左和右)进行简单循迹。
- 超声波模块 (HC-SR04):用于前方测距,实现避障。
- 直流电机 x2 和 车轮 x2
- 车轮支架、万向轮、电池盒 等。
连接说明
| Arduino 引脚 | 连接模块/设备 | 功能说明 |
|---|---|---|
| 数字引脚 5 | L298N ENA (使能A) |
左电机速度控制 (PWM) |
| 数字引脚 6 | L298N ENB (使能B) |
右电机速度控制 (PWM) |
| 数字引脚 7 | L298N IN1 |
左电机正转控制 |
| 数字引脚 8 | L298N IN2 |
左电机反转控制 |
| 数字引脚 9 | L298N IN3 |
右电机正转控制 |
| 数字引脚 10 | L298N IN4 |
右电机反转控制 |
| 数字引脚 2 | 超声波模块 Trig |
触发超声波 |
| 数字引脚 3 | 超声波模块 Echo |
接收回波 |
| 数字引脚 11 | 循迹模块 Left Sensor |
左侧红外传感器输出 |
| 数字引脚 12 | 循迹模块 Right Sensor |
右侧红外传感器输出 |
| 5V / GND | 各模块的 VCC / GND | 注意:电机驱动模块需要外接电源,Arduino 的 5V 可能无法提供足够电流。 |
Arduino 源码
下面是完整的源码,代码包含了详细的注释,解释了每个函数和变量的作用。
/*
* Arduino 智能小车源码
* 功能:结合循迹和避障功能
* 工作模式:
* 1. 正常循迹:小车在黑线上行驶。
* 2. 遇到障碍物:优先执行避障,绕过障碍物后,返回循迹模式。
*
* 硬件连接 (请参考上表):
* - L298N 电机驱动
* - HC-SR04 超声波模块
* - TCRT5000 循迹模块 (使用左右两个传感器)
*/
// =================================================================
// 1. 定义引脚
// =================================================================
// --- L298N 电机驱动模块引脚 ---
// 左电机
#define ENA 5 // 使能A,控制左电机速度 (PWM)
#define IN1 7 // 控制左电机方向1
#define IN2 8 // 控制左电机方向2
// 右电机
#define ENB 6 // 使能B,控制右电机速度 (PWM)
#define IN3 9 // 控制右电机方向1
#define IN4 10 // 控制右电机方向2
// --- 传感器模块引脚 ---
#define TRIG_PIN 2 // 超声波模块 Trig 引脚
#define ECHO_PIN 3 // 超声波模块 Echo 引脚
#define LEFT_SENSOR_PIN 11 // 左侧循迹传感器输出
#define RIGHT_SENSOR_PIN 12 // 右侧循迹传感器输出
// =================================================================
// 2. 全局变量和常量
// =================================================================
// --- 电机速度 ---
#define BASE_SPEED 180 // 基础速度 (0-255),可根据小车实际情况调整
#define TURN_SPEED 150 // 转弯时的速度
// --- 超声波避障阈值 (单位: 厘米) ---
#define OBSTACLE_THRESHOLD 20 // 如果前方距离小于此值,则认为有障碍物
// --- 循迹传感器状态 ---
// 假设传感器在白色背景上输出为 HIGH (1),在黑色线上输出为 LOW (0)
// 根据你的传感器安装和接线,可能需要反转这个逻辑
#define ON_LINE LOW
#define OFF_LINE HIGH
// --- 运动状态枚举 (使代码更清晰) ---
enum State {
TRACKING, // 正在循迹
AVOIDING // 正在避障
};
State currentState = TRACKING; // 初始状态为循迹
// =================================================================
// 3. Arduino 初始化函数 (setup)
// =================================================================
void setup() {
// 设置所有电机引脚为输出模式
pinMode(ENA, OUTPUT);
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
pinMode(ENB, OUTPUT);
pinMode(IN3, OUTPUT);
pinMode(IN4, OUTPUT);
// 设置所有传感器引脚为输入模式
pinMode(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
pinMode(LEFT_SENSOR_PIN, INPUT);
pinMode(RIGHT_SENSOR_PIN, INPUT);
// 初始化串口通信,波特率设为 9600,用于调试
Serial.begin(9600);
Serial.println("智能小车初始化完成!");
}
// =================================================================
// 4. Arduino 主循环函数 (loop)
// =================================================================
void loop() {
// 1. 读取传感器数据
int leftSensor = digitalRead(LEFT_SENSOR_PIN);
int rightSensor = digitalRead(RIGHT_SENSOR_PIN);
long distance = getDistance();
// 2. 根据当前状态执行不同逻辑
if (currentState == TRACKING) {
// 如果正在循迹,但检测到障碍物,则切换到避障模式
if (distance < OBSTACLE_THRESHOLD) {
Serial.println("检测到障碍物!切换到避障模式。");
currentState = AVOIDING;
} else {
// 没有障碍物,正常循迹
track(leftSensor, rightSensor);
}
} else if (currentState == AVOIDING) {
// 如果正在避障,但前方已经没有障碍物,则切换回循迹模式
if (distance >= OBSTACLE_THRESHOLD) {
Serial.println("障碍物已清除!切换回循迹模式。");
currentState = TRACKING;
stop(); // 先停下来,平稳过渡
delay(500); // 短暂暂停,确保状态切换稳定
} else {
// 仍有障碍物,继续避障
avoidObstacle();
}
}
}
// =================================================================
// 5. 核心功能函数
// =================================================================
/**
* @brief 循迹函数
* @param leftState 左侧传感器状态 (HIGH/LOW)
* @param rightState 右侧传感器状态 (HIGH/LOW)
*/
void track(int leftState, int rightState) {
Serial.print("循迹状态 - 左: "); Serial.print(leftState); Serial.print(" 右: "); Serial.println(rightState);
if (leftState == ON_LINE && rightState == ON_LINE) {
// 两侧都在线上,直行
moveForward();
} else if (leftState == OFF_LINE && rightState == ON_LINE) {
// 右侧在左线外,向左转
turnLeft();
} else if (leftState == ON_LINE && rightState == OFF_LINE) {
// 左侧在右线外,向右转
turnRight();
} else {
// 两侧都离开线 (例如十字路口或丢失路线),停止或缓慢前进
// 这里选择停止,防止冲出赛道
stop();
}
}
/**
* @brief 避障函数
* 使用简单的“后退-转向-前进”策略
*/
void avoidObstacle() {
Serial.println("执行避障...");
// 1. 后退一小段距离
moveBackward();
delay(500);
// 2. 原地转向 (向右转90度)
turnRight();
delay(800); // 转向时间,需要根据实际情况调整
// 3. 前进一小段距离,脱离障碍物区域
moveForward();
delay(1000); // 前进时间,需要根据实际情况调整
}
/**
* @brief 获取超声波测量的距离 (单位: 厘米)
* @return 距离值
*/
long getDistance() {
// 发送一个10us的高电平来触发Trig
digitalWrite(TRIG_PIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
// 读取Echo返回的高电平持续时间
long duration = pulseIn(ECHO_PIN, HIGH);
// 声速 = 340m/s = 0.034cm/us
// 距离 = (高电平持续时间 * 声速) / 2 (因为去和回)
long distance = duration * 0.034 / 2;
return distance;
}
// =================================================================
// 6. 电机控制函数 (基础动作)
// =================================================================
void moveForward() {
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
digitalWrite(IN3, HIGH);
digitalWrite(IN4, LOW);
analogWrite(ENA, BASE_SPEED);
analogWrite(ENB, BASE_SPEED);
}
void moveBackward() {
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
digitalWrite(IN3, LOW);
digitalWrite(IN4, HIGH);
analogWrite(ENA, BASE_SPEED);
analogWrite(ENB, BASE_SPEED);
}
void turnLeft() {
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH); // 左电机反转
digitalWrite(IN3, HIGH);
digitalWrite(IN4, LOW); // 右电机正转
analogWrite(ENA, TURN_SPEED);
analogWrite(ENB, TURN_SPEED);
}
void turnRight() {
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW); // 左电机正转
digitalWrite(IN3, LOW);
digitalWrite(IN4, HIGH); // 右电机反转
analogWrite(ENA, TURN_SPEED);
analogWrite(ENB, TURN_SPEED);
}
void stop() {
digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW);
digitalWrite(IN3, LOW);
digitalWrite(IN4, LOW);
analogWrite(ENA, 0);
analogWrite(ENB, 0);
}
如何使用和调试
-
连接硬件:严格按照上面的引脚连接表,将各个模块连接到 Arduino 上。请务必注意电源问题,电机驱动模块最好使用独立的电池组供电,并且将 GND 与 Arduino 的 GND 共地。
-
上传代码:将上述代码复制到 Arduino IDE 中,选择正确的开发板和端口,然后上传。
-
打开串口监视器:
(图片来源网络,侵删)- 在 Arduino IDE 中,点击“工具” -> “串口监视器”。
- 确保右下角的波特率设置为
9600。 - 上传成功后,你会在串口监视器中看到 "智能小车初始化完成!" 的信息。
- 之后,当小车状态改变时(如检测到障碍物),串口监视器会打印相应的信息,这对于调试非常有帮助。
-
调整参数:
BASE_SPEED和TURN_SPEED:如果小车行驶太慢或太快,调整这两个值,如果转弯不够灵活,可以适当调高TURN_SPEED。OBSTACLE_THRESHOLD:如果你的避障距离需要更远或更近,修改这个值。- 传感器逻辑:如果你的循迹传感器在黑线上输出是
HIGH,白线上是LOW,你需要将代码中的ON_LINE和OFF_LINE定义反过来。 - 避障动作时间:在
avoidObstacle()函数中,delay()的时间可能需要根据你的小车的速度和场地大小进行调整,以达到最佳的避障效果。
扩展与改进建议
这份代码是一个很好的起点,你可以基于此进行扩展:
- PID 循迹:简单的“如果左偏则右转,如果右偏则左转”循迹方式不够平滑,可以实现 PID (比例-积分-微分) 算法来控制两个电机的速度差,实现更精准、更平滑的循迹。
- 更复杂的避障:可以增加更多的超声波传感器(如左右两侧),实现“绕行”而不是简单的“后退-转向”。
- 蓝牙/WiFi 控制:添加 HC-05/HC-06 蓝牙模块或 ESP8266 WiFi 模块,实现手机 App 或网页远程控制小车。
- 摄像头视觉:使用 OpenMV 或 ESP32-CAM 等视觉模块,实现颜色识别、二维码识别或更高级的路径规划。
- OLED 显示:添加一个 OLED 屏幕,实时显示小车的状态(如速度、距离、当前模式等)。
希望这份详尽的源码和说明能帮助你成功搭建和运行你的 Arduino 智能小车!祝你玩得开心!

(图片来源网络,侵删)
