Arduino智能小车源码如何实现功能控制?

99ANYc3cd6
预计阅读时长 28 分钟
位置: 首页 AI智能 正文

硬件连接概述

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

arduino智能小车源码
(图片来源网络,侵删)

核心组件

  1. Arduino 主板 (如 Arduino UNO R3)
  2. L298N 电机驱动模块:用于控制两个直流电机。
  3. 循迹模块 (TCRT5000 x2):通常是一个包含5个红外传感器的模块,我们这里使用最外侧的两个传感器(左和右)进行简单循迹。
  4. 超声波模块 (HC-SR04):用于前方测距,实现避障。
  5. 直流电机 x2车轮 x2
  6. 车轮支架、万向轮、电池盒 等。

连接说明

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);
}

如何使用和调试

  1. 连接硬件:严格按照上面的引脚连接表,将各个模块连接到 Arduino 上。请务必注意电源问题,电机驱动模块最好使用独立的电池组供电,并且将 GND 与 Arduino 的 GND 共地。

  2. 上传代码:将上述代码复制到 Arduino IDE 中,选择正确的开发板和端口,然后上传。

  3. 打开串口监视器

    arduino智能小车源码
    (图片来源网络,侵删)
    • 在 Arduino IDE 中,点击“工具” -> “串口监视器”。
    • 确保右下角的波特率设置为 9600
    • 上传成功后,你会在串口监视器中看到 "智能小车初始化完成!" 的信息。
    • 之后,当小车状态改变时(如检测到障碍物),串口监视器会打印相应的信息,这对于调试非常有帮助。
  4. 调整参数

    • BASE_SPEEDTURN_SPEED:如果小车行驶太慢或太快,调整这两个值,如果转弯不够灵活,可以适当调高 TURN_SPEED
    • OBSTACLE_THRESHOLD:如果你的避障距离需要更远或更近,修改这个值。
    • 传感器逻辑:如果你的循迹传感器在黑线上输出是 HIGH,白线上是 LOW,你需要将代码中的 ON_LINEOFF_LINE 定义反过来。
    • 避障动作时间:在 avoidObstacle() 函数中,delay() 的时间可能需要根据你的小车的速度和场地大小进行调整,以达到最佳的避障效果。

扩展与改进建议

这份代码是一个很好的起点,你可以基于此进行扩展:

  • PID 循迹:简单的“如果左偏则右转,如果右偏则左转”循迹方式不够平滑,可以实现 PID (比例-积分-微分) 算法来控制两个电机的速度差,实现更精准、更平滑的循迹。
  • 更复杂的避障:可以增加更多的超声波传感器(如左右两侧),实现“绕行”而不是简单的“后退-转向”。
  • 蓝牙/WiFi 控制:添加 HC-05/HC-06 蓝牙模块或 ESP8266 WiFi 模块,实现手机 App 或网页远程控制小车。
  • 摄像头视觉:使用 OpenMV 或 ESP32-CAM 等视觉模块,实现颜色识别、二维码识别或更高级的路径规划。
  • OLED 显示:添加一个 OLED 屏幕,实时显示小车的状态(如速度、距离、当前模式等)。

希望这份详尽的源码和说明能帮助你成功搭建和运行你的 Arduino 智能小车!祝你玩得开心!

arduino智能小车源码
(图片来源网络,侵删)
-- 展开阅读全文 --
头像
2025款Alienware参数有哪些升级?
« 上一篇 今天
androbench 5.0参数有哪些关键项?
下一篇 » 今天

相关文章

取消
微信二维码
支付宝二维码

最近发表

标签列表

目录[+]