很多人做DIY小车都会遇到同一个问题:程序里给左右轮写了同样的速度,车子却总是往一边偏,跑几米就歪出赛道。问题多半不在电机,而在"开环控制"——你只告诉驱动板输出多少PWM,却从来不知道轮子实际转了多少圈。想让它走直线,得先让控制器看得见轮速,这就是编码器加闭环调速要解决的事。

开环控制为什么必然跑偏
直流电机的转速对电压非常敏感:同样给12V,两个电机的实际转速可能差5%到10%,随着电量下降、负载变化、地面摩擦不同,这个偏差还会漂移。开环控制里,单片机只能设定占空比,电机转快转慢它一无所知,偏差一路累积,小车自然跑不直。
闭环控制的思路很直接:给电机装一个编码器,实时读出它转了多少、转多快,再拿目标速度和实测速度做差,用这个误差反过来调整PWM。误差大就多给电,误差小就少给,这就是PID(比例-积分-微分)控制的日常用法。
硬件清单
这次用一套很经典的组合,成本不高,资料也全:
- Arduino UNO 开发板一块
- JGB37-520 直流减速电机(带霍尔编码器,配轮子)一只
- L298N 电机驱动模块一块
- 2节18650锂电池加带开关的电池盒
- 杜邦线若干
编码器怎么把转速读出来
JGB37-520 用的是增量式编码器,减速比9.6比1。电机轴上的编码器每转一圈输出11个脉冲,经过减速箱之后,输出轴每转一圈对应的脉冲数是 11 乘 9.6 约等于 105.6 个。所以只要在固定时间窗口里数脉冲,就能反推转速:
转速(RPM)等于 这段时间的脉冲数除以采样时间秒数,再乘以 60 除以 105.6。
举个直观的例子:如果在0.1秒里数到大约17.6个脉冲,就说明输出轴大概在100转每分钟附近。实际调试时可以用外部转速表对一下,确认系数没算错。
接线:六根线各归各位
JGB37-520 引出的六根线颜色是固定的,接错最容易烧编码器,务必对号入座:
- 红(M1):电机正极
- 白(M2):电机负极
- 黄(C1):编码器A相输出
- 绿(C2):编码器B相输出
- 蓝:编码器供电正,接3.3V或5V
- 黑:编码器供电负,接GND
电机的红白两根接到 L298N 的输出端,A、B两相接到 UNO 的两个中断引脚,比如D2和D3,编码器的电源单独接,不要和电机动力线共用一路。

从PID到PI:先加滤波再调参
轮速信号天生带噪声,直接丢进控制器会让输出抖得厉害。一个简单的办法是加一阶低通滤波:把上一次的滤波值和这次的新读数按比例混合,新读数权重小一点,曲线就平顺了。滤波系数取0.7左右,能在跟得上变化和压得住抖动之间取得平衡。
电机调速里通常只用PI就够了:比例项Kp负责响应速度,误差一大立刻加大输出;积分项Ki负责消稳态误差,让最终转速稳稳停在目标值。微分项对速度这种带噪声的信号反而容易放大抖动,先不引入。参考参数可以从 Kp等于2、Ki等于3 起步,再按实际手感微调。

调参顺序,别一上来就乱试
第一步,把Ki设为0,只留Kp,从小到大加,直到电机能快速接近目标转速但开始轻微来回摆。第二步,把Kp回退一点,再慢慢加Ki,观察稳态误差是不是被压下去了;如果出现越来越大的振荡,说明Ki给多了。第三步,回到滤波系数,如果目标一变电机就抽一下,把系数调大一点让信号更平滑。
调好之后,把左右轮设成同一个目标转速,小车就能明显走直了;想让它在不同地面都稳,可以给两边各跑一套独立的闭环。
闭环调速不算玄学,核心就是把看不见的转速变成看得见的数字,再用误差去纠偏。等你把这一套跑通,平衡车、差速底盘、甚至云台稳像的底层逻辑,其实都是同一件事。











Kp=2、Ki=3先抄作业了,回头拿我的小车跑一下看看走不走得直
这个接线颜色说明太有用了,我之前就是编码器供电接错,直接烧了一个电机
105.6脉冲每圈这个数终于有人讲清楚了,之前自己算老是差一点
调参顺序这块很实在,先Kp再Ki确实比一上来瞎试强太多