这次我们来看一个低成本桌面轮式机器人的 DIY 项目。核心目标很明确:用大约 50 元的预算,从零开始搭建一个能跑、能遥控、具备基础扩展能力的桌面级机器人小车。这不仅仅是买套件组装,而是涉及结构设计、主控选择、电机驱动、电源管理和基础编程的完整实践。
对于嵌入式初学者、电子爱好者或想带孩子体验创客乐趣的家长来说,这个项目门槛不高,但涵盖的知识点很全。它不追求复杂的 SLAM 或视觉识别,而是聚焦于让轮子先可靠地转起来,并搭建一个可后续升级的硬件平台。本文将带你从物料清单开始,一步步完成机械组装、电路连接、程序烧录和遥控测试,最终让你获得一个完全由自己“手搓”出来的可编程机器人底盘。
1. 核心能力速览
| 能力项 | 说明 |
|---|---|
| 项目类型 | 桌面轮式机器人 DIY(两轮差分驱动底盘) |
| 核心功能 | 前进/后退/转向遥控、可编程控制、基础扩展接口 |
| 主控芯片 | 常见 8位/32位单片机(如 STC89C52、STM32F103、Arduino Nano) |
| 驱动方案 | L298N 或 TB6612 电机驱动模块 |
| 动力系统 | N20 微型减速电机(带编码器可选) |
| 电源系统 | 18650 锂电池组或 9V 电池,配合降压模块 |
| 控制方式 | 蓝牙(HC-05/06)遥控或红外遥控,后续可扩展 WiFi |
| 车身结构 | 亚克力板激光切割或 3D 打印,成本极低 |
| 编程环境 | Arduino IDE、Keil 等,依赖主控选择 |
| 总成本估算 | 核心控制在 50 元人民币左右(视具体物料渠道浮动) |
| 适合场景 | 嵌入式学习、电子DIY入门、创客教育、机器人底盘验证 |
2. 适用场景与使用边界
这个项目最适合以下几类人:
- 嵌入式/单片机初学者:想通过一个完整项目,实践 GPIO 控制、PWM 调速、串口通信等核心技能。
- 电子DIY爱好者:享受从画图、切割到焊接、调试的全过程乐趣。
- 教育工作者或家长:寻找一个安全、低成本、效果直观的 STEM 教学或亲子活动项目。
- 机器人算法验证者:需要一个稳定、廉价的差分驱动底盘来测试巡线、避障等基础算法。
它能解决什么问题?
- 理论与实践结合:将枯燥的单片机引脚定义转化为能让小车跑起来的实际代码。
- 建立系统观:理解一个最小机器人系统所需的电源管理、信号控制、机械结构等模块如何协同工作。
- 提供可扩展平台:完成基础底盘后,可以方便地加装超声波传感器、红外探头、摄像头等,升级功能。
它的局限性是什么?
- 性能有限:N20 电机扭矩小,不适合负重或复杂地形。
- 功能基础:初始版本仅实现遥控移动,智能功能需额外开发。
- 精度一般:除非使用带编码器的电机并进行闭环控制,否则直线行走和转角精度不高。
安全与合规边界:
- 使用锂电池时,必须注意充电安全,防止短路,建议使用带保护板的电池。
- 小型电机和齿轮箱运行时,避免手指或衣物被卷入。
- 本项目为学习与实验目的设计,不应用于可能造成人身伤害或财产损失的场合。
3. 环境准备与前置条件
在开始采购和焊接前,请确保你已准备好以下软硬件环境:
1. 硬件工作台:
- 一个宽敞、明亮、静电防护良好的桌面。
- 必备工具:电烙铁、焊锡丝、松香、吸锡器、万用表、螺丝刀套装、镊子、剥线钳。
- 可选但推荐:一台 3D 打印机(用于打印车架)或 access to 激光切割服务(用于切割亚克力板)。
2. 软件与开发环境:
- 电路设计(可选):可以使用立创 EDA 等免费工具绘制简单的电源分配板原理图,但本项目直接使用杜邦线连接模块也可行。
- 结构设计:使用 Fusion 360、SolidWorks 或简单的 Inkscape 设计车架图纸。
- 编程环境:
- 如果主控选用Arduino Nano/Uno:安装 Arduino IDE。
- 如果主控选用STC89C52:安装 Keil C51 和 STC-ISP 下载软件。
- 如果主控选用STM32F103C8T6:安装 Arduino IDE 并配置 STM32 支持,或安装 Keil MDK。
- 手机APP(蓝牙遥控):在手机应用商店搜索“蓝牙串口”或“Arduino Bluetooth Controller”,提前安装好。
3. 核心物料清单(预算约50元):以下是基于常见电商平台散件价格的估算清单,购买时请注意选择兼容的电压和接口。
| 物料名称 | 规格/型号 | 数量 | 预估单价(元) | 备注 |
|---|---|---|---|---|
| 主控板 | Arduino Nano 兼容版 | 1 | 8-12 | 核心控制器,易编程 |
| 电机驱动 | L298N 模块 | 1 | 5-7 | 驱动两个直流电机 |
| 直流电机 | N20 减速电机(6V) | 2 | 4-6 *2 | 提供动力,注意转速和扭矩 |
| 车轮 | 65mm 塑料轮 | 2 | 1.5-2 *2 | 匹配电机轴径(通常为3mm) |
| 电源 | 18650 电池*2 | 2 | 4-6 *2 | 或使用 9V 方块电池 |
| 电池盒/支架 | 18650 双节电池盒 | 1 | 2-3 | 带开关为佳 |
| 电压降压模块 | LM2596 或 MP1584 | 1 | 2-3 | 将电池电压降至 5V 给主控供电 |
| 蓝牙模块 | HC-05 或 HC-06 | 1 | 8-10 | 用于手机遥控 |
| 车架材料 | 3mm 亚克力板或 3D 打印耗材 | 1套 | 5-10 | 结构主体 |
| 万向轮/牛眼轮 | 小型万向轮 | 1 | 1-2 | 用于支撑与转向 |
| 连接线 | 杜邦线(公对公、公对母) | 1包 | 2-3 | 用于模块间连接 |
| 紧固件 | M3螺丝螺母套装 | 1套 | 2-3 | 用于固定各部件 |
| 总计 | ~50元 | 价格随渠道和选择浮动 |
4. 机械结构组装
车架是机器人的骨骼,其稳定性和电机安装精度直接影响运动性能。
设计要点:
- 尺寸:根据车轮和电池尺寸设计,通常成品长约15-20cm,宽约10-15cm。
- 电机固定:设计精准的安装孔位,确保两个驱动轮轴线平行,否则小车会跑偏。
- 重心:将较重的电池布置在车体中部或靠近驱动轴的位置,降低重心,提高稳定性。
- 万向轮:在车架前部或后部中心位置设计一个万向轮安装点,形成“两驱+一万向”的经典结构。
制作方法二选一:
- 方案A:3D 打印
- 使用建模软件(如 Fusion 360)设计车架,导出 STL 文件。
- 用 3D 打印机使用 PLA 材料打印。建议填充率 20%-30%,确保强度。
// 这是一个极简的 OpenSCAD 示例,用于生成一个底板 difference(){ cube([150, 100, 3], center=true); // 底板 // 在这里添加电机座、电池盒等安装孔 translate([60, 35, 0]) cylinder(h=5, d=3, center=true); // 示例安装孔 } - 方案B:亚克力板激光切割
- 使用矢量绘图软件(如 Inkscape)绘制车架图纸,包含所有切割和雕刻线。
- 将图纸交给激光切割服务商或使用自有设备切割 3mm 厚亚克力板。
- 亚克力板强度高、美观,但脆性大,钻孔和安装时需小心。
组装步骤:
- 将两个 N20 电机用螺丝固定在车架两侧的电机座上。
- 将车轮紧紧压入电机轴(通常是 D 型轴,注意方向)。
- 在车架预留位置安装万向轮。
- 将电池盒、主控板、驱动板等用螺丝或尼龙柱固定在车架平台上。布局时考虑走线方便。
5. 电路连接与焊接
这是将各个电子模块“编织”成神经网络的关键一步。请务必在断电状态下操作,并对照原理图或下表逐一连接。
核心连接逻辑:
- 电源流:电池 -> 降压模块 -> 为各模块提供稳定电压。
- 控制流:主控板(接收指令) -> 电机驱动板 -> 电机。
- 信号流:蓝牙模块 <-> 主控板串口。
以下以 Arduino Nano + L298N + HC-05 为例,给出接线表:
| 从 (From) | 连接到 (To) | 线缆类型 | 功能说明 |
|---|---|---|---|
| 电池正极 (+) | L298N 模块12V输入口 | 红线 | 为电机驱动供电 |
| 电池正极 (+) | 降压模块IN+ | 红线(可并联) | 为降压模块供电 |
| 电池负极 (-) | L298N 模块GND | 黑线 | 电源地 |
| 电池负极 (-) | 降压模块IN- | 黑线(可并联) | 电源地 |
降压模块OUT+(5V) | Arduino NanoVIN或5V | 红线 | 为 Arduino 供电 |
降压模块OUT-(GND) | Arduino NanoGND | 黑线 | 共地 |
Arduino NanoGND | L298N 模块GND | 杜邦线(黑) | 必须共地! |
| Arduino D5 | L298NIN1 | 杜邦线 | 控制电机A方向 |
| Arduino D6 | L298NIN2 | 杜邦线 | 控制电机A方向 |
| Arduino D9 | L298NENA | 杜邦线 | 控制电机A速度 (PWM) |
| Arduino D7 | L298NIN3 | 杜邦线 | 控制电机B方向 |
| Arduino D8 | L298NIN4 | 杜邦线 | 控制电机B方向 |
| Arduino D10 | L298NENB | 杜邦线 | 控制电机B速度 (PWM) |
L298NOUT1 | 左侧电机 线1 | 导线 | 驱动电机A |
L298NOUT2 | 左侧电机 线2 | 导线 | 驱动电机A |
L298NOUT3 | 右侧电机 线1 | 导线 | 驱动电机B |
L298NOUT4 | 右侧电机 线2 | 导线 | 驱动电机B |
ArduinoRX(D0) | HC-05TXD | 杜邦线 | 串口接收数据 |
ArduinoTX(D1) | HC-05RXD | 杜邦线 | 串口发送数据 |
Arduino5V | HC-05VCC | 杜邦线(红) | 为蓝牙模块供电 |
ArduinoGND | HC-05GND | 杜邦线(黑) | 共地 |
接线检查清单:
- [ ] 电源极性是否正确?(正负极切勿接反)
- [ ] 所有
GND是否已连接到一起?(共地是电路正常工作的基础) - [ ] 电机驱动板的使能引脚(ENA, ENB)是否接到了 Arduino 的 PWM 引脚(带
~标识)? - [ ] 蓝牙模块的 TX/RX 是否与 Arduino 的 RX/TX交叉连接?(TX接RX,RX接TX)
- [ ] 所有接线是否牢固?有无虚焊或松动?
6. 程序烧录与基础驱动测试
硬件连接好后,我们先不着急做遥控,而是写一个简单的测试程序,确保两个电机能按预期正反转。
1. Arduino 基础电机驱动测试程序:打开 Arduino IDE,新建一个项目,复制以下代码。这段代码让小车依次执行:前进2秒 -> 停止1秒 -> 后退2秒 -> 停止1秒 -> 左转2秒 -> 右转2秒 -> 停止。
// 引脚定义 const int IN1 = 5; // 左电机方向1 const int IN2 = 6; // 左电机方向2 const int ENA = 9; // 左电机速度 (PWM) const int IN3 = 7; // 右电机方向1 const int IN4 = 8; // 右电机方向2 const int ENB = 10; // 右电机速度 (PWM) void setup() { // 初始化所有电机控制引脚为输出模式 pinMode(IN1, OUTPUT); pinMode(IN2, OUTPUT); pinMode(ENA, OUTPUT); pinMode(IN3, OUTPUT); pinMode(IN4, OUTPUT); pinMode(ENB, OUTPUT); // 初始状态:停止所有电机 stopMotors(); delay(1000); // 上电等待 } void loop() { // 测试前进 moveForward(150); // 速度值 0-255 delay(2000); stopMotors(); delay(1000); // 测试后退 moveBackward(150); delay(2000); stopMotors(); delay(1000); // 测试左转(原地) turnLeft(150); delay(2000); stopMotors(); delay(1000); // 测试右转(原地) turnRight(150); delay(2000); stopMotors(); delay(1000); // 循环结束,长时间停止 while(1){ stopMotors(); } } // 功能函数定义 void moveForward(int speed) { // 左电机前进 digitalWrite(IN1, HIGH); digitalWrite(IN2, LOW); analogWrite(ENA, speed); // 右电机前进 digitalWrite(IN3, HIGH); digitalWrite(IN4, LOW); analogWrite(ENB, speed); } void moveBackward(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, LOW); digitalWrite(IN2, HIGH); analogWrite(ENA, speed); digitalWrite(IN3, HIGH); digitalWrite(IN4, LOW); analogWrite(ENB, speed); } void turnRight(int speed) { // 左电机前进,右电机后退 -> 原地右转 digitalWrite(IN1, HIGH); digitalWrite(IN2, LOW); analogWrite(ENA, speed); digitalWrite(IN3, LOW); digitalWrite(IN4, HIGH); analogWrite(ENB, speed); } void stopMotors() { digitalWrite(IN1, LOW); digitalWrite(IN2, LOW); analogWrite(ENA, 0); digitalWrite(IN3, LOW); digitalWrite(IN4, LOW); analogWrite(ENB, 0); }2. 烧录与测试步骤:
- 用 USB 数据线连接 Arduino Nano 和电脑。
- 在 Arduino IDE 中选择正确的板卡类型(
Arduino Nano)和处理器(ATmega328P (Old Bootloader)或根据你的版本选择)。 - 选择正确的端口(COMxx 或 /dev/ttyUSBx)。
- 点击“上传”按钮,将程序烧录到 Arduino。
- 烧录成功后,将小车放在空旷地面,打开电池开关。
- 观察小车是否按“前进-后退-左转-右转”的顺序运动。
3. 问题排查:
- 小车不动:首先检查电池是否有电,开关是否打开。然后用万用表测量 Arduino 的 5V 和 GND 之间是否有电压。接着检查 L298N 模块上的电源指示灯是否亮起。
- 只有一个轮子转:检查不转的电机对应的接线(IN1/IN2/ENA 或 IN3/IN4/ENB)是否松动,程序中的引脚定义是否与实际接线一致。
- 转动方向相反:交换该电机连接 L298N
OUT1和OUT2的两根线即可。 - 运动不规律:检查所有
GND是否都已可靠连接。共地不良是导致信号紊乱最常见的原因。
7. 蓝牙遥控功能集成
基础驱动测试通过后,我们引入蓝牙模块,实现用手机遥控。
1. 蓝牙模块(HC-05)配置(通常只需一次):大多数 HC-05 模块出厂设置即可使用,但为了确保可靠,可以将其进入 AT 模式进行基础检查。需要将 HC-05 的EN(或KEY)引脚接高电平(3.3V或5V),然后通过 USB 转 TTL 模块连接电脑,用串口助手(波特率 38400)发送 AT 指令查询版本和地址。
# 示例 AT 指令 AT # 测试连接,应返回 OK AT+NAME? # 查询模块名称,可改为自定义名 AT+NAME=MyRobot AT+PSWD? # 查询配对密码,默认为 1234 AT+UART? # 查询串口参数,应与 Arduino 设置匹配(如 9600,0,0)配置完成后,断开EN引脚连接,使其进入正常工作模式。
2. Arduino 蓝牙遥控程序:以下程序实现通过手机蓝牙串口 APP 发送单个字符来控制小车。
‘F’:前进‘B’:后退‘L’:左转‘R’:右转‘S’:停止‘0’-‘9’:控制速度等级(映射到 PWM 值)
// 引脚定义 (与之前相同) const int IN1 = 5; const int IN2 = 6; const int ENA = 9; const int IN3 = 7; const int IN4 = 8; const int ENB = 10; int motorSpeed = 150; // 默认速度 void setup() { // 初始化电机引脚 pinMode(IN1, OUTPUT); pinMode(IN2, OUTPUT); pinMode(ENA, OUTPUT); pinMode(IN3, OUTPUT); pinMode(IN4, OUTPUT); pinMode(ENB, OUTPUT); stopMotors(); // 初始停止 // 初始化串口通信,用于蓝牙 Serial.begin(9600); // 波特率需与 HC-05 模块匹配 Serial.println("Bluetooth Robot Ready!"); } void loop() { // 检查串口是否有数据 if (Serial.available() > 0) { char command = Serial.read(); // 读取一个字符 Serial.print("Received: "); Serial.println(command); switch(command) { case 'F': moveForward(motorSpeed); Serial.println("Moving Forward"); break; case 'B': moveBackward(motorSpeed); Serial.println("Moving Backward"); break; case 'L': turnLeft(motorSpeed); Serial.println("Turning Left"); break; case 'R': turnRight(motorSpeed); Serial.println("Turning Right"); break; case 'S': stopMotors(); Serial.println("Stopped"); break; case '0'...'9': // 将字符'0'-'9'映射为速度 0-255 motorSpeed = map(command - '0', 0, 9, 0, 255); Serial.print("Speed set to: "); Serial.println(motorSpeed); break; default: // 忽略未知指令 break; } } // 可以添加一小段延时,防止过于频繁的循环 delay(10); } // 电机控制函数 (与之前相同,此处省略以节省篇幅) void moveForward(int speed) { ... } void moveBackward(int speed) { ... } void turnLeft(int speed) { ... } void turnRight(int speed) { ... } void stopMotors() { ... }3. 手机端连接与测试:
- 将新程序上传到 Arduino。
- 打开手机蓝牙,搜索名为 “HC-05” 或你自定义名称的设备。
- 点击配对,输入密码(默认为
1234)。 - 打开手机上的蓝牙串口 APP。
- 在 APP 内连接已配对的蓝牙模块。
- 连接成功后,APP 通常会显示一个简单的键盘或按钮界面。
- 尝试按下
F、B、L、R、S等按键,观察小车反应。同时可以在电脑的 Arduino IDE 串口监视器(波特率 9600)中查看收到的指令和反馈。
8. 系统调试与性能优化
完成基本遥控后,可以进行一些调试和优化,让小车运行更可靠、更“聪明”。
1. 电源系统观察:
- 电压监测:电机启动瞬间电流较大,可能导致 Arduino 重启。可以用万用表监测 Arduino 的 5V 引脚电压,在电机启停时是否出现大幅跌落。如果跌落严重,说明电池电量不足或降压模块带载能力不够。
- 解决方案:确保电池电量充足;选用输出电流更大的降压模块(如 3A);在 Arduino 的电源输入处并联一个较大容量的电容(如 1000uF)以缓冲瞬时电流。
2. 运动性能调优:
- 直线跑偏:由于两个电机特性不可能完全一致,即使 PWM 值相同,转速也有细微差别,导致跑偏。
- 解决方案:在程序中为两个电机设置不同的速度补偿值。例如,如果小车总是向右偏,可以略微调低右电机的速度或调高左电机的速度。
void moveForward(int speed) { int leftSpeed = speed; int rightSpeed = speed * 0.95; // 右电机补偿系数 analogWrite(ENA, leftSpeed); analogWrite(ENB, rightSpeed); // ... 方向控制代码不变 } - 启动/停止抖动:PWM 速度从 0 突变到设定值,或反之,可能导致机械冲击。
- 解决方案:加入速度渐变(软启动/软停止)。
void softStart(int targetSpeed, int duration) { for (int s = 0; s <= targetSpeed; s++) { analogWrite(ENA, s); analogWrite(ENB, s); delay(duration / targetSpeed); } }
3. 扩展接口预留:在车架上预留安装孔和电路接口,为后续升级做准备:
- 超声波传感器:用于避障。需要 1个 Trig 引脚和 1个 Echo 引脚。
- 红外巡线传感器:需要数字输入引脚。
- 舵机云台:用于安装摄像头或传感器,需要 PWM 引脚。
- WS2812 LED 灯带:用于状态指示或炫酷效果,需要 1个数字引脚。
- 蜂鸣器:用于提示音,需要 1个数字引脚。
可以在 Arduino 的剩余数字引脚(D2, D3, D4, D11, D12, D13 等)和模拟引脚(A0-A7)上焊接排针,方便后续插接传感器。
9. 常见问题与排查方法
在制作和调试过程中,你可能会遇到以下问题:
| 问题现象 | 可能原因 | 排查方式 | 解决方案 |
|---|---|---|---|
| 上电后毫无反应 | 1. 电池没电或开关损坏。 2. 电源线未接通或反接。 3. 降压模块故障。 | 1. 用万用表测电池电压。 2. 检查所有电源通路是否导通。 3. 测降压模块输入输出电压。 | 1. 充电或更换电池。 2. 重新焊接或连接。 3. 更换模块。 |
| Arduino 程序无法上传 | 1. 驱动未安装。 2. 板卡或端口选错。 3. bootloader 问题。 | 1. 检查设备管理器。 2. 确认 Arduino 型号和 COM 口。 3. 尝试按复位键后立即上传。 | 1. 安装 CH340 或 CP2102 驱动。 2. 重新选择。 3. 使用正确的 bootloader 选项。 |
| 电机不转,但驱动板指示灯亮 | 1. 电机线未接好。 2. 程序引脚定义错误。 3. 使能引脚(ENA/ENB)未使能。 | 1. 检查电机接线。 2. 核对代码与接线表。 3. 检查程序是否设置了正确的 PWM 输出。 | 1. 重新连接。 2. 修改代码。 3. 确保 analogWrite函数被调用。 |
| 蓝牙无法连接手机 | 1. 蓝牙模块未正确供电。 2. TX/RX 接反。 3. 波特率不匹配。 4. 模块处于 AT 模式。 | 1. 测 VCC 电压。 2. 检查是否交叉连接。 3. 检查代码与模块波特率。 4. 检查 EN/KEY引脚状态。 | 1. 确保供电 5V。 2. 交换 TX/RX 线。 3. 统一为 9600 或 38400。 4. 将 EN/KEY引脚悬空或接地。 |
| 小车运动时 Arduino 重启 | 电机启动电流过大,导致系统电压瞬间跌落。 | 监测 Arduino 5V 引脚在电机启动时的电压。 | 1. 电池并联大电容。 2. 使用动力型电池。 3. 电机电源与逻辑电源分开供电。 |
| 遥控指令反应迟钝或丢失 | 1. 蓝牙连接不稳定。 2. 串口缓冲区溢出。 3. 手机 APP 发送频率过高。 | 1. 拉近手机与小车距离。 2. 在代码中及时处理串口数据。 3. 降低 APP 发送频率。 | 1. 确保无遮挡。 2. 优化代码,及时 Serial.read()。3. 使用带延时的按钮或摇杆。 |
10. 项目总结与进阶方向
至此,一个成本约 50 元、功能完整的桌面轮式机器人小车就成功“手搓”出来了。这个项目的价值不在于做出了多炫酷的产品,而在于你完整地走通了从设计、采购、组装、编程到调试的全流程,这是任何现成套件都无法替代的经验。
最值得尝试的下一步扩展:
- 自动避障:加装一个 HC-SR04 超声波传感器,编写程序,让小车在前进时自动探测并避开障碍物。
- 巡线行驶:使用 3-5 个 TCRT5000 红外巡线模块,让小车能沿着地面的黑色轨迹自动行走。
- 手机姿态遥控:利用手机加速度计,编写 APP,通过手机倾斜角度来控制小车速度和方向,体验更直观的控制。
- WiFi 与摄像头:将主控换成 ESP32-CAM,实现 WiFi 遥控和第一人称视角(FPV)视频传输,成本会略有上升,但可玩性大增。
- PID 速度控制:如果使用了带编码器的电机,可以尝试编写 PID 算法,让两个轮子的转速更精确,实现更稳定的直线和定速控制。
这个小小的机器人底盘是一个绝佳的实验平台。当你成功让它动起来的那一刻,关于电源、信号、控制、编程的抽象知识就都变成了具体的经验。建议保存好这个项目的电路图和源代码,它将成为你未来更复杂项目最可靠的起点。