arduino uno小车开发接线与程序记录
一、硬件连接总览(所有模块与Arduino扩展板的最终接线)
1. 四路红外避障模块
红外模块引脚 | 扩展板引脚(Arduino) | 功能说明 |
---|---|---|
VCC | 5V | 电源正极 |
GND | GND | 接地 |
IN1 | D2 | 第一路红外信号输入 |
IN2 | D3 | 第二路红外信号输入 |
IN3 | D4 | 第三路红外信号输入 |
IN4 | D5 | 第四路红外信号输入 |
2. 超声波模块(HC-SR04)
超声波引脚 | 扩展板引脚(Arduino) | 功能说明 |
---|---|---|
VCC | 5V | 电源正极 |
GND | GND | 接地 |
Trig | D6 | 触发信号 |
Echo | D7 | 回响信号 |
3. 舵机
舵机线颜色 | 扩展板引脚(Arduino) | 功能说明 |
---|---|---|
棕色/黑色 | GND | 接地 |
红色 | 5V | 电源正极 |
橙色/黄色 | D9 | 信号控制 |
4. 电机驱动模块(L298N)
驱动板引脚 | 扩展板引脚(Arduino) | 功能说明 |
---|---|---|
IN1 | D10 | 左电机正转 |
IN2 | D11 | 左电机反转 |
IN3 | D12 | 右电机正转 |
IN4 | D13 | 右电机反转 |
ENA | D3 | 左电机PWM(原D6,调整后避免冲突) |
ENB | D5 | 右电机PWM(原D11,调整后避免冲突) |
12V | 外部电池正极(不接扩展板) | 电机电源 |
GND(电机) | GND(与扩展板共地) | 电机电源地 |
二、更改后的程序(适配新引脚分配)
// 引脚定义(全部调整后)
const int trigPin = 6; // 超声波触发引脚(原D2→D6)
const int echoPin = 7; // 超声波回响引脚(原D3→D7)
const int avoidPin1 = 2; // 第一路红外
const int avoidPin2 = 3; // 第二路红外
const int avoidPin3 = 4; // 第三路红外
const int avoidPin4 = 5; // 第四路红外
const int servoPin = 9; // 舵机控制引脚(不变)
const int motorLeftFwd = 10; // 左电机正转
const int motorLeftRev = 11; // 左电机反转
const int motorRightFwd = 12;// 右电机正转
const int motorRightRev = 13;// 右电机反转
const int enA = 3; // 左电机PWM(原D6→D3)
const int enB = 5; // 右电机PWM(原D11→D5)#include <Servo.h>
Servo myServo; // 舵机对象void setup() {Serial.begin(9600);// 初始化所有引脚模式pinMode(trigPin, OUTPUT);pinMode(echoPin, INPUT);pinMode(avoidPin1, INPUT);pinMode(avoidPin2, INPUT);pinMode(avoidPin3, INPUT);pinMode(avoidPin4, INPUT);pinMode(motorLeftFwd, OUTPUT);pinMode(motorLeftRev, OUTPUT);pinMode(motorRightFwd, OUTPUT);pinMode(motorRightRev, OUTPUT);pinMode(enA, OUTPUT);pinMode(enB, OUTPUT);// 设置电机初始速度(0-255)analogWrite(enA, 200);analogWrite(enB, 200);// 初始化舵机myServo.attach(servoPin);myServo.write(90); // 舵机居中delay(1000);
}// 测量超声波距离(厘米)
long getDistance() {digitalWrite(trigPin, LOW);delayMicroseconds(2);digitalWrite(trigPin, HIGH);delayMicroseconds(10);digitalWrite(trigPin, LOW);long duration = pulseIn(echoPin, HIGH);return duration * 0.034 / 2;
}// 电机动作函数
void forward() {digitalWrite(motorLeftFwd, HIGH);digitalWrite(motorLeftRev, LOW);digitalWrite(motorRightFwd, HIGH);digitalWrite(motorRightRev, LOW);
}void stop() {digitalWrite(motorLeftFwd, LOW);digitalWrite(motorLeftRev, LOW);digitalWrite(motorRightFwd, LOW);digitalWrite(motorRightRev, LOW);
}void turnLeft() {digitalWrite(motorLeftFwd, LOW);digitalWrite(motorLeftRev, HIGH);digitalWrite(motorRightFwd, HIGH);digitalWrite(motorRightRev, LOW);delay(500);
}void turnRight() {digitalWrite(motorLeftFwd, HIGH);digitalWrite(motorLeftRev, LOW);digitalWrite(motorRightFwd, LOW);digitalWrite(motorRightRev, HIGH);delay(500);
}void loop() {long distance = getDistance();// 读取四路红外信号int ir1 = digitalRead(avoidPin1);int ir2 = digitalRead(avoidPin2);int ir3 = digitalRead(avoidPin3);int ir4 = digitalRead(avoidPin4);// 避障逻辑:超声波<30cm 或 任意一路红外检测到障碍物if (distance < 30 || ir1 == LOW || ir2 == LOW || ir3 == LOW || ir4 == LOW) {stop();delay(500);// 舵机左扫测距myServo.write(30);delay(1000);long leftDist = getDistance();// 舵机右扫测距myServo.write(150);delay(1000);long rightDist = getDistance();myServo.write(90); // 舵机回中delay(500);// 选择更宽的方向转向if (leftDist > rightDist) {turnLeft();} else {turnRight();}} else {forward(); // 无障碍物,前进}delay(100);
}
三、接线说明(关键冲突解决)
-
超声波与红外引脚分离:
- 超声波原Trig/Echo占用D2/D3,现在移到D6/D7,释放D2-D5给四路红外(avoidPin1-4)。
-
电机驱动PWM引脚调整:
- 原电机PWM(enA/enB)占用D6/D11,现在enA移到D3,enB移到D5,避开红外和超声波的新引脚。
-
共地与电源:
- 所有模块的GND必须连接到扩展板的GND(共地),VCC连接到扩展板5V(统一供电)。
四、调试建议
- 先单独测试四路红外:用手遮挡某一路,观察串口输出或LED(若模块有指示灯)是否响应。
- 再测试超声波:用尺子测量距离,对比
getDistance()
返回值是否准确。 - 最后测试电机与舵机:上传程序后,手动触发避障,观察转向是否符合预期。
这样调整后,所有模块的引脚完全不冲突,且程序逻辑保持完整的避障功能~
// 引脚定义(保持不变)
const int trigPin = 6; // 超声波触发引脚
const int echoPin = 7; // 超声波回响引脚
const int avoidPin1 = 2; // 第一路红外
const int avoidPin2 = 3; // 第二路红外
const int avoidPin3 = 4; // 第三路红外
const int avoidPin4 = 5; // 第四路红外
const int servoPin = 9; // 舵机控制引脚
const int motorLeftFwd = 10; // 左电机正转(硬件定义)
const int motorLeftRev = 11; // 左电机反转(硬件定义)
const int motorRightFwd = 12;// 右电机正转(硬件定义)
const int motorRightRev = 13;// 右电机反转(硬件定义)#include <Servo.h>
Servo myServo; // 舵机对象void setup() {Serial.begin(9600);// 初始化所有引脚模式pinMode(trigPin, OUTPUT);pinMode(echoPin, INPUT);pinMode(avoidPin1, INPUT);pinMode(avoidPin2, INPUT);pinMode(avoidPin3, INPUT);pinMode(avoidPin4, INPUT);pinMode(motorLeftFwd, OUTPUT);pinMode(motorLeftRev, OUTPUT);pinMode(motorRightFwd, OUTPUT);pinMode(motorRightRev, OUTPUT);// 初始化舵机(如果舵机方向也反了,可将90改为270-90=180,即myServo.write(180))myServo.attach(servoPin);myServo.write(90); // 舵机居中delay(1000);
}// 测量超声波距离(厘米)
long getDistance() {digitalWrite(trigPin, LOW);delayMicroseconds(2);digitalWrite(trigPin, HIGH);delayMicroseconds(10);digitalWrite(trigPin, LOW);long duration = pulseIn(echoPin, HIGH);return duration * 0.034 / 2;
}// 核心修改:将原前进改为后退,原后退改为前进,实现方向反转
void forward() {// 原逻辑是前进,现在改为后退(对应物理车头方向前进)digitalWrite(motorLeftFwd, LOW);digitalWrite(motorLeftRev, HIGH);digitalWrite(motorRightFwd, LOW);digitalWrite(motorRightRev, HIGH);
}void stop() {// 停止逻辑不变digitalWrite(motorLeftFwd, LOW);digitalWrite(motorLeftRev, LOW);digitalWrite(motorRightFwd, LOW);digitalWrite(motorRightRev, LOW);
}// 左转逻辑反转(原左转变为右转,适应新车头方向)
void turnLeft() {digitalWrite(motorLeftFwd, HIGH);digitalWrite(motorLeftRev, LOW);digitalWrite(motorRightFwd, LOW);digitalWrite(motorRightRev, HIGH);delay(500);
}// 右转逻辑反转(原右转变为左转,适应新车头方向)
void turnRight() {digitalWrite(motorLeftFwd, LOW);digitalWrite(motorLeftRev, HIGH);digitalWrite(motorRightFwd, HIGH);digitalWrite(motorRightRev, LOW);delay(500);
}void loop() {long distance = getDistance();// 读取四路红外信号int ir1 = digitalRead(avoidPin1);int ir2 = digitalRead(avoidPin2);int ir3 = digitalRead(avoidPin3);int ir4 = digitalRead(avoidPin4);// 避障逻辑不变(传感器已在新车头位置)if (distance < 30 || ir1 == LOW || ir2 == LOW || ir3 == LOW || ir4 == LOW) {stop();delay(500);// 舵机左扫测距(如果舵机方向反了,30和150互换)myServo.write(30);delay(1000);long leftDist = getDistance();// 舵机右扫测距myServo.write(150);delay(1000);long rightDist = getDistance();myServo.write(90); // 舵机回中delay(500);// 选择更宽的方向转向if (leftDist > rightDist) {turnLeft();} else {turnRight();}} else {forward(); // 无障碍物,前进(实际是原后退方向)}delay(100);
}