1. 为什么我劝你第一台机器人从智能小车做起
如果你刚接触嵌入式或者机器人方向,想找一个能跑通“感知—决策—执行”完整闭环的项目,智能小车几乎是成本最低、反馈最直接的选择。它不像机械臂那样需要复杂的运动学解算,也不像四足机器人那样对控制算法要求极高,几十块钱的底盘加上一块主控板,你就能在一个下午看到它自己沿着黑线跑起来,或者感应到障碍物后自动转向。这种即时反馈对建立信心特别重要。
我见过不少初学者一上来就啃人形机器人或者高精度SLAM方案,结果卡在硬件调试和数学推导上,热情很快被消磨掉。智能小车的好处在于它的技术栈是“可裁剪”的:你可以只做最基础的红外循迹,也可以逐步叠加超声波避障、蓝牙遥控、摄像头视觉识别,甚至后期换成激光雷达做建图导航。每一步都有明确的验证标准,不会让你陷入“不知道哪里出了问题”的困境。
这篇文章面向的是零基础或者刚入门的爱好者,我会把整个制作过程拆成选型、组装、接线、编程、调试五个阶段,每个阶段都告诉你为什么这么选、参数怎么算、坑在哪里。你不需要提前掌握单片机或者C语言,只要跟着做,手头有一把螺丝刀和一台电脑就能开始。文中涉及的所有代码和配置都是可以直接复现的,硬件型号我会用通用描述代替,你根据手头能买到的类似规格替换即可。
2. 硬件选型与整体方案设计
2.1 核心需求拆解与功能定义
动手之前先想清楚这台小车要干什么。我的建议是第一版只做两件事:能走直线和转弯、能感知前方障碍并停下或转向。这两个功能覆盖了电机控制、传感器输入、逻辑判断三个核心环节,做完之后你对整个系统的运作方式就有了肌肉记忆。
不要一开始就追求“自动循迹+避障+遥控+图传”全功能,那会让接线和代码复杂度指数级上升。我自己的习惯是先用最小系统跑通,再像搭积木一样往上加模块。比如第一版只用一块主控板、一个电机驱动模块、两个直流减速电机、一个超声波模块和一个电池盒。底盘可以用亚克力板自己打孔,也可以直接买现成的三轮或四轮底盘套件,后者省去机械加工的时间,对新手更友好。
功能定义清楚了,后面选型就有了判断标准:电机扭矩够不够带动底盘、驱动模块电流是否匹配、主控引脚数量是否够用、电池电压是否在安全范围内。这些参数不是拍脑袋定的,下面我会给出具体的计算过程。
2.2 主控板选型:为什么我推荐从这类开发板入手
市面上常见的入门主控有基于8位单片机的开发板、基于32位ARM的开发板,以及各种Linux小板子。对于智能小车这个场景,我的建议是优先选引脚多、社区资料丰富、支持图形化或Arduino框架的32位开发板。
原因有三点。第一,智能小车至少需要控制两个电机的方向(每个电机两个逻辑引脚)和速度(每个电机一个PWM引脚),再加上超声波模块的触发和回响两个引脚,以及可能的循迹传感器四到五个引脚,总共需要十几个IO口。8位单片机虽然也能做,但引脚复用多,后期加模块容易捉襟见肘。第二,32位主控的PWM分辨率和定时器资源更充裕,电机调速更平滑,不会出现低速时抖动严重的情况。第三,社区资料多意味着你遇到问题能快速搜到答案,这对新手至关重要。
具体选型时看三个指标:IO口数量不少于20个、PWM通道不少于4路、工作电压3.3V或5V且兼容常见传感器。价格通常在十几到几十元之间,没必要追求高端型号,够用就行。我试过用一块十几元的国产32位板子跑完整套逻辑,稳定运行几个月没出问题。
2.3 电机与驱动模块的匹配计算
电机选型是很多新手容易翻车的地方。常见的小车电机有直流减速电机和步进电机两类,前者便宜、驱动简单,后者精度高但需要专用驱动器。智能小车用直流减速电机就够了。
关键参数是转速和扭矩。转速决定了小车的最大速度,扭矩决定了它能不能爬坡和载重。假设你的底盘轮子直径是65毫米,电机转速是200转每分钟,那么理论最大速度是:
速度 = 转速 × 轮子周长 = 200 × π × 0.065 ≈ 40.8米每分钟 ≈ 0.68米每秒
这个速度对于室内小车来说偏快,实际用PWM调速到50%左右比较合适。扭矩方面,如果底盘加电池总重500克,两个电机分担,每个电机需要克服的滚动阻力大约在0.1到0.2千克力之间,常见减速电机的堵转扭矩在0.5到2千克力之间,余量充足。
驱动模块的选择取决于电机的堵转电流。比如某款减速电机堵转电流是1.2安培,两个电机同时堵转就是2.4安培,那么驱动模块的持续输出电流至少要3安培以上,峰值要能扛住5安培。常用的双路驱动模块如L298N、TB6612等,前者便宜但压降大、发热明显,后者效率高、体积小,我个人更推荐TB6612这类基于MOS管的方案。接线时注意电机驱动模块的电源地和主控地必须共地,否则信号电平没有参考点,电机会乱转或者不转。
2.4 传感器与电源方案
避障功能用超声波模块就够了,它通过发射和接收声波计算距离,有效范围一般在2厘米到4米之间,精度足够判断前方是否有障碍物。它的工作原理是:触发引脚给一个10微秒的高电平脉冲,模块发射8个40kHz的声波,然后回响引脚输出高电平,高电平持续时间就是声波往返的时间。距离计算公式是:
距离 = 声速 × 时间 / 2 = 340米每秒 × 时间 / 2
注意单位换算,代码里通常用微秒计时,所以距离(厘米)= 时间(微秒)× 0.034 / 2。
电源方面,推荐用两节18650锂电池串联,标称电压7.4伏,充满8.4伏。这个电压可以直接给电机驱动模块供电,同时通过主控板上的降压模块降到5伏给主控和传感器供电。不要用9伏方块电池,它的放电电流太小,电机一启动电压就跌落,主控会反复重启。电池容量建议在2000毫安时以上,续航时间估算方法是:
续航 = 电池容量 / 平均工作电流
假设平均电流500毫安,2000毫安时电池理论上能跑4小时,实际打七折约2.8小时,足够一下午的调试。
3. 组装接线与核心电路解析
3.1 底盘组装与电机固定
拿到底盘套件后,先把两个减速电机用螺丝固定在底盘两侧。注意电机的输出轴方向要朝向底盘后方或者前方,保持一致,否则一个轮子往前转一个往后转,小车会原地打转。固定时螺丝不要拧太紧,亚克力板容易裂,拧到电机不晃动即可。
轮子安装有个小技巧:先在轮毂和电机轴之间涂一点点热熔胶或者缠一圈生料带,再用力压进去。很多套件的轮子用久了会打滑,就是因为配合太松。万向轮或者牛眼轮装在底盘前端或后端作为支撑点,高度要调整到和驱动轮一致,否则小车会像跷跷板一样前后晃。
电池盒用双面胶或者扎带固定在底盘底部,尽量靠近中心位置,这样重心低、转弯稳。我试过把电池放在顶部,结果小车一加速就往后翻,后来改到底部就再没出现过。
3.2 驱动模块与主控的接线逻辑
以TB6612为例,它有两路电机输出,每路需要三个控制信号:方向1、方向2、PWM调速。方向信号决定电机正转还是反转,PWM信号决定转速。接线时把主控的普通IO口接方向引脚,带PWM功能的IO口接调速引脚。
具体对应关系如下表:
| 驱动模块引脚 | 主控引脚 | 功能说明 |
|---|---|---|
| AIN1 | 普通IO 1 | 电机A方向控制 |
| AIN2 | 普通IO 2 | 电机A方向控制 |
| PWMA | PWM IO 1 | 电机A速度控制 |
| BIN1 | 普通IO 3 | 电机B方向控制 |
| BIN2 | 普通IO 4 | 电机B方向控制 |
| PWMB | PWM IO 2 | 电机B速度控制 |
| STBY | 普通IO 5 | 使能引脚,高电平工作 |
| VCC | 5V输出 | 逻辑电源 |
| GND | 共地 | 信号地 |
| VM | 电池正极 | 电机电源 |
| GND | 电池负极 | 电机电源地 |
注意:STBY引脚必须拉高,否则驱动模块不工作。有些模块内部已经上拉,但为了保险,建议用主控的一个IO口控制它,初始化时置高。
电机线接到驱动模块的A01、A02和B01、B02,如果发现转向和预期相反,把对应电机的两根线对调即可,不需要改代码。
3.3 超声波模块的安装与滤波
超声波模块装在小车正前方,离地高度建议在10到20厘米之间,太低容易受地面反射干扰,太高可能探测不到矮障碍物。模块的两个“眼睛”要朝前,不要被底盘或者排线挡住。
接线只有四根:VCC接5V,GND接地,Trig接触发IO,Echo接回响IO。代码里读取距离时,连续读三次取中间值,可以过滤掉偶尔的异常值。如果发现距离跳动很大,检查供电是否稳定,超声波模块对电源纹波比较敏感,可以在它的VCC和GND之间并一个100微法的电解电容。
3.4 电源分配与共地处理
整个系统的电源流向是:电池输出7.4伏给驱动模块的VM引脚,同时电池经过主控板上的降压芯片得到5伏,给主控、超声波模块供电。驱动模块的逻辑电源VCC也从主控的5伏取。
这里最容易犯的错误是只接了信号线没接共地线。主控和驱动模块之间除了信号线,必须有一根线把两者的GND连在一起,否则信号电平没有共同参考点,电机会出现随机转动或者完全不转。我帮别人排查问题时,十次有三次是忘了接共地线。
另外,电机启动瞬间电流很大,会在电源线上产生压降,可能导致主控复位。解决办法是在驱动模块的VM和GND之间并一个470微法以上的电解电容,靠近模块引脚放置,能有效吸收电流尖峰。
4. 程序编写与核心逻辑实现
4.1 开发环境搭建与基础测试
我习惯用Arduino框架来写小车程序,因为它封装了底层寄存器操作,几行代码就能让电机转起来。如果你用的是其他主控,找对应的GPIO和PWM库即可,逻辑是一样的。
环境搭好后先做两个基础测试。第一个是串口通信测试,在代码里初始化串口,循环打印“hello”,打开串口监视器能看到输出,说明主控和电脑通信正常。第二个是电机测试,写一段代码让两个电机正转两秒、反转两秒、停止两秒,循环执行。如果电机不转,先检查STBY引脚是否拉高、电池是否接好、共地线是否连接。如果只有一个电机转,交换驱动模块的A、B通道接线,判断是驱动模块问题还是电机问题。
4.2 电机控制函数封装
直接在主循环里写电机控制代码会很乱,我通常封装三个函数:motorForward(速度)、motorBackward(速度)、motorStop()。速度参数用0到255的整数,对应PWM占空比。
以向前为例,逻辑是:AIN1置高、AIN2置低、PWMA输出速度值;BIN1置高、BIN2置低、PWMB输出速度值。向后则反过来。停止就是所有方向引脚置低、PWM置零。
封装好之后,主循环里只需要调用函数名,代码可读性大幅提升。这里有个细节:改变电机转向时,先让电机停止再反向,不要直接从正转跳到反转,否则瞬间反向电流会冲击驱动模块,长期这样操作容易烧芯片。
4.3 超声波测距与避障逻辑
超声波测距函数返回距离值,单位厘米。避障逻辑我推荐用状态机而不是简单的if-else嵌套。状态机有三个状态:前进、后退、转向。
- 前进状态:距离大于30厘米,保持前进。
- 后退状态:距离小于15厘米,先后退200毫秒,然后进入转向状态。
- 转向状态:随机选择左转或右转,持续300到500毫秒,然后回到前进状态。
为什么用状态机?因为简单的if-else在距离临界值附近会反复切换状态,小车会抖动。状态机加延时后,每次决策至少持续几百毫秒,动作干净利落。转向时间可以根据你的小车转弯半径调整,太短转不过去,太长会原地画圈。
4.4 主循环结构与调试信息输出
主循环的结构是:读超声波距离、根据距离更新状态、执行对应动作、通过串口打印当前距离和状态。串口打印非常重要,调试时你能看到小车“看到”的距离是多少、做了什么决策,比盯着小车猜原因高效得多。
我一般每100毫秒打印一次,格式类似“距离: 25厘米 状态: 前进”。如果发现距离一直是0或者一个固定值,检查超声波模块的Trig和Echo引脚是否接反、供电是否正常。如果距离数值合理但小车行为异常,检查状态切换的阈值和延时是否合适。
5. 调试与常见问题排查
5.1 电机不转或只往一个方向转
这是最高频的问题。排查顺序如下:
- 用万用表测驱动模块VM引脚电压,正常应该在7伏左右。如果为零,检查电池是否没电或者开关没开。
- 测STBY引脚电压,正常应该是高电平。如果为零,检查代码里是否初始化了该引脚并置高。
- 测主控和驱动模块的GND之间是否导通,不导通就是共地线没接。
- 交换电机线,如果原来不转的电机换了通道后转了,说明驱动模块对应通道损坏,更换模块。
5.2 超声波读数跳动大或不准确
超声波模块对安装角度和电源质量很敏感。先确认模块是否正对前方、没有被遮挡。然后在代码里加中值滤波,连续读五次,去掉最大和最小值,剩下三个取平均。如果还是跳动,在模块电源引脚并一个100微法电容,或者换一个质量好一点的模块。另外,超声波测量周期不要低于60毫秒,否则上一次的回波还没消失,下一次触发就来了,读数会混乱。
5.3 小车走不直
两个电机的实际转速不可能完全一致,走偏是正常的。解决办法有两种:一是硬件上给转速快的电机串联一个可调电阻,手动调平衡;二是软件上给两个电机不同的PWM值,比如左轮200、右轮190,通过实验找到补偿值。我通常先用软件补偿,因为不用动烙铁,改个数字就行。
5.4 电池续航短或主控频繁重启
主控重启的典型原因是电机启动瞬间电压跌落。除了加电容,还可以在代码里加“软启动”:PWM值从0逐渐增加到目标值,比如每10毫秒增加10,这样电流上升平缓,电压不会瞬间拉低。续航短则要检查是否有模块一直在耗电,比如超声波模块如果一直触发,功耗会比间歇工作高不少。可以在主循环里让超声波每200毫秒测一次,而不是一直测。
5.5 常见问题速查表
| 现象 | 可能原因 | 解决方法 |
|---|---|---|
| 上电后主控不亮 | 电池没电或降压模块损坏 | 测电池电压,更换降压模块 |
| 电机嗡嗡响但不转 | PWM值太低或堵转 | 提高PWM值,检查轮子是否卡住 |
| 小车原地打转 | 一个电机线接反 | 对调该电机两根线 |
| 避障反应迟钝 | 超声波测量周期太长 | 缩短到60到100毫秒 |
| 遥控距离短 | 蓝牙模块天线被遮挡 | 调整模块位置,远离电机线 |
| 循迹时冲出黑线 | 传感器离地太高 | 调整到离地1到2厘米 |
6. 后续扩展方向与个人经验
基础功能跑通之后,你可以按自己的兴趣往不同方向扩展。喜欢控制感的可以加蓝牙模块,用手机APP遥控;喜欢算法的可以加摄像头,跑简单的颜色识别或者巡线;喜欢机械的可以换麦克纳姆轮,实现全向移动。每加一个模块,先单独测试,确认没问题再集成到主程序里,不要一次性全接上,否则出了问题很难定位。
我个人在多次制作小车的过程中,最大的体会是电源和接地比代码重要得多。很多莫名其妙的故障,最后查出来都是供电不稳或者地线没接好。所以每次动手前,我都会先用万用表把电源网络检查一遍,确认电压正常、极性正确、共地可靠,再开始写代码。这个习惯帮我省下了大量排查时间。
另外,代码版本管理也很关键。每完成一个功能就保存一个副本,比如car_v1_前进后退、car_v2_加避障。当你改代码改出问题想回退时,直接打开上一个版本,比一点点删代码快得多。我吃过这个亏,一次改避障逻辑把电机控制也改乱了,花了两个小时才恢复,从那以后就老老实实做版本备份。
最后分享一个小技巧:调试时把小车架起来,让轮子悬空,这样你可以安全地观察电机转向和传感器读数,不用担心它突然冲出去撞墙。等逻辑确认无误了再放到地上跑。这个习惯能帮你避免很多“一上电就撞坏东西”的意外。