核心原理:无人机如何“看见”障碍物?
无人机避障的关键在于传感器,传感器负责探测前方、下方或四周是否存在障碍物,并将这个信息传递给 Arduino,Arduino 根据传感器的数据,结合无人机的飞行状态,做出决策:是继续前进、悬停、减速还是转向。

最常用和最适合 DIY 项目的传感器是超声波传感器和红外避障传感器。
-
超声波传感器 (Ultrasonic Sensor - HC-SR04):
- 原理: 像蝙蝠一样,它发射超声波(人耳听不到的高频声波),然后接收从障碍物反射回来的回波,通过计算发射和接收之间的时间差,可以精确计算出障碍物的距离。
- 优点: 测量距离较远(可达2-4米),精度高,不受光线影响。
- 缺点: 存在最小探测盲区(通常几厘米),对柔软、吸音的物体(如棉花、地毯)探测效果不佳,探测角度相对较窄。
-
红外避障传感器 (Infrared Obstacle Avoidance Sensor - TCRT5000):
- 原理: 发射红外光,通过检测红外光是否被障碍物反射回来来判断有无障碍物,它通常只输出一个数字信号(有障碍物/无障碍物),但有些模块可以模拟输出强度,从而粗略判断距离。
- 优点: 价格便宜,响应速度快,功耗低,可以探测柔软物体。
- 缺点: 易受环境光(尤其是强光)干扰,测距精度和范围远不如超声波,主要用于短距离的“有无”探测。
所需硬件清单
除了基础的无人机套件,你还需要额外准备以下组件:

-
核心控制器:
- Arduino Uno / Nano: 最常见的选择,适合学习和原型验证,引脚足够,易于上手。
- Arduino Pro Mini / Mini 3.3V: 如果追求轻量化和低功耗,这是一个更好的选择,但需要额外的USB转TTL模块进行编程。
- ESP32 / ESP8266: 强烈推荐!它自带 Wi-Fi 和蓝牙,不仅可以作为控制器,还能实现图传、数据上传到云服务器等高级功能。
-
传感器:
- 超声波传感器 (HC-SR04): 至少1个,用于前方避障,可以安装多个(如前、下、左、右)实现全方位避障。
- 红外避障传感器 (TCRT5000): 可以作为超声波的补充,用于近距离或侧方探测。
-
电机驱动板:
- Arduino 自带 PWM 引脚输出的能力有限,无法直接驱动无刷电机。 你需要一个专门的电调,常见的如:
- MultiWii 飞控: 集成了陀螺仪、加速度计和电调接口,是DIY无人机的经典选择。
- Cleanflight / Betaflight 飞控: 更现代、功能更强大的飞控,同样支持连接 Arduino 作为辅助板。
- 连接方式: Arduino 不直接驱动电机,而是通过向飞控发送PWM 信号来模拟遥控器的信号,从而控制无人机的油门、方向等。
- Arduino 自带 PWM 引脚输出的能力有限,无法直接驱动无刷电机。 你需要一个专门的电调,常见的如:
-
其他:
(图片来源网络,侵删)- 面包板和杜邦线: 用于原型搭建和测试。
- 电池: 为无人机和 Arduino 供电。
- 螺丝、扎带、支架: 用于将传感器和 Arduino 固定在无人机上。
系统架构与连接方式
一个典型的 Arduino 避障系统架构如下:
[遥控器] --> [飞控 (如 Naze32)] --> [无刷电机 & 电调]
|
+--> [Arduino] <-- [传感器 (超声波/红外)]
|
+--> [飞控] (通过PWM信号)
工作流程:
- 正常飞行: 飞控接收遥控器的信号,控制无人机飞行。
- 传感器探测: Arduino 持续读取超声波传感器的距离数据。
- 避障决策: Arduino 内部的程序判断:如果距离小于设定的安全阈值(50cm),则触发避障逻辑。
- 信号干预: Arduino 不会直接“切断”遥控信号,而是叠加一个控制信号到飞控上,当检测到前方障碍物时,Arduino 会向飞控发送一个“后退”或“上升”的PWM信号,同时略微降低“前进”的油门,从而实现平稳避障。
- 恢复: 当障碍物离开探测范围后,Arduino 停止发送干预信号,无人机恢复由遥控器控制。
软件实现与代码示例
我们将使用 Arduino Uno 和 HC-SR04 超声波传感器来实现一个最基本的前方避障功能。
硬件连接
- HC-SR04 VCC -> Arduino 5V
- HC-SR04 GND -> Arduino GND
- HC-SR04 Trig (触发) -> Arduino Pin 9
- HC-SR04 Echo (回波) -> Arduino Pin 10
Arduino 代码示例 (基础版)
这个代码只负责测量距离,并在串口打印出来,这是调试的第一步。
// 定义引脚
const int trigPin = 9;
const int echoPin = 10;
// 定义变量
long duration;
int distance;
void setup() {
// 初始化串口通信,波特率设为9600
Serial.begin(9600);
// 设置引脚模式
pinMode(trigPin, OUTPUT); // 触发脚为输出
pinMode(echoPin, INPUT); // 回波脚为输入
}
void loop() {
// 1. 发送一个10微秒的高电平脉冲来触发传感器
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
// 2. 读取回波脉冲的持续时间,单位为微秒
duration = pulseIn(echoPin, HIGH);
// 3. 计算距离
// 声速在空气中约为 340 m/s,即 0.034 cm/微秒。
// 往返距离需要除以2。
distance = duration * 0.034 / 2;
// 4. 通过串口打印距离
Serial.print("Distance: ");
Serial.print(distance);
Serial.println(" cm");
// 短暂延时,避免过于频繁的读取
delay(500);
}
上传代码后,打开 Arduino IDE 的串口监视器 (右上角放大镜图标),你应该能看到距离数据在不断变化。
集成到无人机控制 (进阶版)
将避障逻辑与飞控结合是真正的难点,你需要了解你所用飞控的辅助通道 功能。
假设你使用 MultiWii 或 Cleanflight 飞控,它有一个 AUX 通道,通常可以映射到不同的飞行模式(如稳定模式、定高模式等),我们可以利用这个通道。
修改后的代码思路:
- 定义一个安全距离
safeDistance(100cm)。 - 在
loop()中持续测量距离。 distance < safeDistance,则将一个引脚(Pin 11)设置为HIGH。- 否则,设置为
LOW。 - 将这个引脚连接到飞控的
AUX输入通道上。 - 在飞控的配置软件中,将
AUX通道映射到一个你想要的功能,比如“解锁电机”或“切换飞行模式”。
示例代码:
const int trigPin = 9;
const int echoPin = 10;
const int auxPin = 11; // 连接到飞控的AUX通道
const int safeDistance = 100; // 安全距离,单位:厘米
long duration;
int distance;
void setup() {
Serial.begin(9600);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
pinMode(auxPin, OUTPUT); // AUX引脚设置为输出
digitalWrite(auxPin, LOW); // 初始状态为LOW
}
void loop() {
// --- 测量距离部分 (同上) ---
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
distance = duration * 0.034 / 2;
Serial.print("Distance: ");
Serial.print(distance); 