ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Arduino+L298N电机驱动五大坑:接线、PWM、共地、电流余量全解析

Arduino+L298N电机驱动五大坑:接线、PWM、共地、电流余量全解析 做智能小车或者桌面机器人Arduino UNO配L298N电机驱动模块绝对是很多人入门电机控制的第一套组合。便宜、接线直观、资料铺天盖地搜一下“arduino智能小车”出来一堆教程照着插好像也能转。但真正到了自己写代码控制转速、搞差速转向、处理电源的时候问题就全冒出来了电机要么纹丝不动要么全速飞车要么转两秒Arduino就重启甚至模块自己开始冒烟。这篇文章就专门聊我这些年玩L298N踩过的坑整理成5个最常见也最隐蔽的错误PWM信号接错引脚、跳线帽没处理、供电共地忽略、频率死区没概念、电流余量不摸底。从接线一路讲到PWM调速每一个问题我都会告诉你现象是什么、原理是什么、怎么解决。你拿小板子对照自查大部分毛病都能省下几个小时的Debug时间。1. 动手之前先搞懂L298N这几个关键接口很多朋友接线翻车其实不是手残而是没搞明白L298N模块上那几个接口和跳线帽的真实作用。模块上丝印很多但真正跟Arduino交互的就两类方向控制脚IN1~IN4和使能/调速脚ENA、ENB再加上电源区和输出区。1.1 模块上那几个跳线帽功能完全不一样L298N模块上通常有三个跳线帽位置不一样作用也完全是两码事新手最容易在这上面栽跟头。第一个是5V输出选择跳线帽通常插在“5V”和“EN”下面那个位置附近有的板子丝印写的是“5V_EN”。插上的时候模块板载的78M05稳压芯片会把VS输入的电压降压成5V从模块的5V引脚输出可以直接给Arduino供电。拔掉之后5V引脚就断开了逻辑部分的5V要靠外部提供。这一个跳线帽决定了你是“单电源供电”还是“双电源供电”后面我会细说。第二个和第三个是ENA、ENB的使能跳线帽出厂默认是插上的。插上之后ENA/ENB这两个引脚在模块内部被拉到高电平相当于使能端永远开着电机只受IN1~IN4方向控制速度是满的。你想用Arduino的PWM信号调速就必须把这两个跳线帽拔掉否则PWM信号根本进不到芯片内部。这一点可以说是整个避坑指南里最核心的一条实测十个“调速失灵”的案例里有八个都是这个原因。1.2 标准接线表照着接10分钟通电接线之前先把供电方案定下来。我的建议是新手优先用“双电源”也就是电机电源和Arduino电源分开然后共地。这样最稳也最好排查。下面这套接法我用了很多次稳定可靠L298N模块接口接Arduino / 电源说明VS电池正极6~12V电机供电普通小车用7.4V 2S锂电池或6节AA电池都行GND电池负极同时接Arduino GND电机电源负和逻辑电源负必须连在一起这就是共地5V输出此处建议不接拔掉5V跳线帽Arduino优先用USB或独立5V供电IN1、IN2Arduino D8、D7控制A电机方向IN3、IN4Arduino D6、D5控制B电机方向ENAArduino D9PWM脚控制A电机速度ENBArduino D10PWM脚控制B电机速度OUT1、OUT2A电机两根线正反不管转反了交换两根线就行OUT3、OUT4B电机两根线同上接完之后模块的GND和Arduino的GND之间一定要有一根杜邦线连着。别嫌多余这根线少了什么诡异问题都能冒出来后面第4部分专门讲。还有一个小提醒接线别图省事用劣质长杜邦线。电机电流虽然不大但启动瞬间和堵转瞬间的尖峰不小劣质杜邦线压降大会造成模块供电不足小车一启动就像没吃饭一样。我一般习惯用短粗线接电源和电机信号线用普通杜邦线就够。2. 常见错误一PWM信号接到IN引脚电机为什么又抖又不受控这个错误真的太常见了而且迷惑性很强。很多人写完代码用analogWrite()给IN1引脚输出PWM电机确实转了转速也确实变了但工作状态很怪低速抖、噪声大、刹车感很明显甚至偶尔方向还会自己跳一下。2.1 IN和ENA的分工一个是方向盘一个是油门要搞懂这个问题得先说清楚L298N内部H桥的工作逻辑。下面是数据手册里简化出来的真值表ENAIN1IN2电机状态HHL正转HLH反转HHH制动HLL制动L任意任意停止滑行看出来没有IN1和IN2是“方向盘”决定电机往哪转、要不要刹车ENA才是“油门”决定输出多少动力。当你把PWM信号接到IN1上IN2保持低电平ENA保持高电平会发生什么PWM高电平期间IN1H、IN2L电机正转PWM低电平期间IN1L、IN2L电机进入制动状态注意是“制动”不是“滑行”。于是电机就在“正转”和“刹车”之间来回切换频率几百赫兹相当于一直在用制动来降速。这样确实能改变平均速度但代价是电流尖峰很大电机容易发热L298N内部管子压力也大还伴随明显的“嗡嗡”声。2.2 正确姿势digitalWrite管方向analogWrite管速度正确的做法是分开控制方向引脚用digitalWrite()输出H/L速度引脚用analogWrite()输出PWM。下面是我一直在用的双电机标准代码逻辑// 定义引脚 int ENA 9; // PWM调速引脚 int IN1 8; int IN2 7; int ENB 10; int IN3 6; int IN4 5; void setup() { pinMode(ENA, OUTPUT); pinMode(IN1, OUTPUT); pinMode(IN2, OUTPUT); pinMode(ENB, OUTPUT); pinMode(IN3, OUTPUT); pinMode(IN4, OUTPUT); } void motorAForward(int speed) { digitalWrite(IN1, HIGH); digitalWrite(IN2, LOW); analogWrite(ENA, speed); // speed取值范围0~255 } void motorABackward(int speed) { digitalWrite(IN1, LOW); digitalWrite(IN2, HIGH); analogWrite(ENA, speed); } void motorAStop() { // 用刹车方式快速停住 digitalWrite(IN1, HIGH); digitalWrite(IN2, HIGH); analogWrite(ENA, 0); } void loop() { motorAForward(150); delay(2000); motorAStop(); delay(1000); motorABackward(150); delay(2000); motorAStop(); delay(1000); }这里有一个小细节新手经常忽略当你调用analogWrite(ENA, 0)时电机只是切断了驱动它会靠着惯性继续滑行一段距离。如果你的小车需要精确停在线上那就把IN1和IN2同时拉高让电机进入制动状态这样能停得更干脆。这个小技巧在巡线小车里特别有用。顺带说一句舵机的PWM和电机驱动的PWM完全是两回事。舵机用的是50Hz左右、脉宽1~2ms的周期信号L298N调速用的是几百Hz到几千Hz、占空比变化的方波。别把两个概念混在一起否则你会被“为什么舵机不动但电机在嗡嗡响”这种问题折磨一晚上。3. 常见错误二使能端跳线帽不拔调速代码写再多也白搭这个是“PWM电机飞车”的典型原因也绝对是我见过最多的问题。论坛里隔三差五就有人发帖说“我代码里写的是analogWrite(ENA, 100)为什么电机还是全速跑”下面回复五花八门有说代码错的有说供电不够的其实绝大多数情况就是把ENA上的跳线帽忘了拔。3.1 跳线帽不拔PWM信号进不了芯片L298N模块上的ENA/ENB跳线帽插上以后会把ENA引脚在模块内部直接拉到5V。这时候ENA就是永远的高电平相当于使能端被“焊死”了无论你用Arduino引脚输出了什么样的PWM波形电气上都到不了L298N芯片里面。这时候电机处于什么状态就看IN1和IN2了。如果你的程序里IN1拉了高、IN2拉了低那么电机就是全速正转速度永远100%跟你的analogWrite值一点关系都没有。很多智能小车一上电就全速往前冲怎么也刹不住多半就是这个原因。我管这种现象叫“飞车”在小车调试现场特别吓人容易直接撞墙。3.2 三个跳线帽的状态检查清单上电之前花十秒钟把模块上的三个跳线帽检查一遍比什么都强。我的固定习惯是5V输出跳线帽如果Arduino用USB/独立5V供电必须拔掉如果想让模块5V给Arduino供电插上。ENA跳线帽只要用Arduino做调速必须拔掉。ENB跳线帽同上必须拔掉。拔掉ENA跳线帽之后ENA引脚就变成悬空状态了这时候软件里如果不做任何设置引脚电平是不确定的电机可能乱转。所以拔掉之后一定要记得用杜邦线把ENA接到Arduino的D9之类的引脚并在setup()里把它设置为OUTPUT。还有一个容易连带的坑有些模块的ENA和ENB是靠跳线帽旁边那个排针引出信号的拔掉跳线帽后你可能需要额外插一根杜邦线到EN引脚上。不同厂家的模块丝印略有差异有的写“ENA”有的写“EN A”有的是靠跳线帽插拔方向切换“使能/调速”模式接线前最好看一眼自己买的那家模块的说明书或者商品详情图。4. 常见错误三电源和共地处理不当单片机重启、数码管乱跳都怪它如果说前两个错误是“电机不听话”那这个错误就是“整个系统发疯”。现象千奇百怪Arduino莫名其妙重启、串口打印乱码、数码管数字疯狂闪跳、传感器读数全是负的。这些问题的根源往往不在传感器和代码而在电源和地线。4.1 5V输出跳线帽什么时候插什么时候拔先说供电方案。L298N模块上的5V输出引脚确实可以给Arduino供电但前提是电机电源电压别太高、Arduino负载别太大。我之前在12V电机电源下尝试让模块的78M05给Arduino供电结果Arduino有几率重启后来一摸稳压芯片烫得不敢碰。原因是78M05是线性稳压输入12V输出5V压差7V如果Arduino和其他传感器加起来吃200mA电流光稳压芯片上就要耗掉1.4W的热量小封装根本扛不住。所以我后来基本只用两种接法双电源方案最推荐电机电源接VS和GNDArduino用USB或者独立5V电源模块5V输出跳线帽拔掉。然后必须把模块GND和Arduino GND用杜邦线连起来。单电源方案电机电源在6~9V左右模块5V输出跳线帽插上5V引脚接Arduino的5V。适合整体电流很小、不带太多传感器的简易小车。如果用双电源却忘了拔5V输出跳线帽模块的5V引脚会和Arduino的5V互相“打架”。两边电位有细微差异就会出现电流倒灌严重的甚至烧掉Arduino板载稳压器。这个操作我在新手群里提醒过很多次但每次总有人中招。4.2 共地不是可选项是必选项什么叫共地就是把两个电源的负极也就是GND用导线连到一起。在你用双电源方案的时候模块GND和Arduino GND必须连通。很多人不理解问我都用了两个独立电源了为什么还要把负极连起来道理很简单Arduino判断一个引脚是高还是低是拿引脚电压和它自己的GND来比的。L298N判断IN1是高还是低是拿这个引脚电压和它自己的GND来比的。如果两个GND不是同一个参考点可能Arduino输出5V到了L298N那边看却不是5V而是3.5V或者别的什么值于是逻辑就乱套了。我实测过不共地的状态电机偶尔动一下模块上的IN指示灯忽亮忽灭Arduino串口打印里全是乱码整个系统就跟中了邪一样。接上一根共地线之后所有症状全部消失。所以说共地不是可选项是必选项。这句话记牢了能帮你少走好多弯路。4.3 干扰实测电机一转数码管就乱跳电机是个很大的干扰源。直流电机的电刷在换向的时候会产生火花这些火花会让电流波形变得非常脏产生大量高频干扰脉冲顺着电源线往回传。如果共地没做好、滤波电容没加这些干扰就可能直接打进Arduino造成复位或者逻辑错乱。我有一次做一个小项目Arduino驱动一个四位数码管显示转速电机一启动数码管上的数值就随机乱跳完全没法看。一开始我以为代码有问题查了半天没结果后来用示波器量了一下电源线好家伙全是毛刺。解决办法也简单在电机电源输入端并联一个大电解电容推荐470uF到1000uF耐压至少是电源电压的1.5倍。在电机两个接线端子旁边并联一个0.1uF的陶瓷电容104越靠近电机越好。把电源线和电机线尽量缩短有条件的话用双绞线。加了这几个电容之后数码管显示立刻稳定了Arduino也不再重启。这个土办法成本不到一块钱但比换芯片、改程序有效多了。注意电解电容是有极性的正极接VS负极接GND接反了轻则电容烧穿重则“啪”一声直接炸开操作的时候别马虎。5. 常见错误四PWM频率和死区没概念电机啸叫、低速抖动接线和电源都正常了电机也能转了接下来就是PWM调速的参数问题。很多朋友说“我PWM都写了占空比也调了为什么电机低速的时候一抖一抖的声音还特别尖”这就是对PWM频率和工作死区没有概念。5.1 Arduino默认PWM频率D5/D6和D3/D11不一样Arduino UNO的analogWrite()并不是所有PWM引脚频率都一样。这里有个很容易被忽略的细节D5、D6由Timer0控制默认频率约980HzD3、D9、D10、D11分别由Timer2和Timer1控制默认频率约490Hz为什么会有这个差别因为Arduino核心库初始化定时器的时候给Timer0用的分频系数不一样导致它跑得更快一点。实际用起来这个差别对小车的直流电机影响不是特别大。但如果你想进一步优化电机噪声和发热就需要自己改定时器寄存器把PWM频率整体提上去。改频率的原理不复杂。PWM频率由单片机的定时器时钟源和计数上限决定修改预分频就能改变频率。下面这段代码可以把D3和D11的PWM频率从约490Hz提高到约3.9kHzvoid setup() { // 修改Timer2预分频影响D3、D11的analogWrite频率 // 默认预分频是64 - 频率约490Hz // 改为预分频8 - 频率约3.9kHz TCCR2B (TCCR2B 0b11111000) | 0x02; pinMode(3, OUTPUT); pinMode(11, OUTPUT); }注意改了Timer2之后D3和D11的PWM频率会同时变。如果你有两个电机恰好想把它们分别接在D3和D11上那这俩引脚频率会一起变其实也没问题。但如果你的程序已经把别的功能绑定在Timer2上比如某些库使用了D3/D11就得小心冲突。我个人的习惯是用D9和D10做两个电机的PWM因为它们在Timer1上频率一致左右轮调速更对称改起来也方便。那PWM频率是不是越高越好也不是。L298N内部是双极型晶体管频率太高的话开关损耗会明显增加模块会比其他情况更烫。我自己试过把PWM调到20kHz以上L298N吼叫是没了但模块温度明显上升有点得不偿失。建议在2kHz到10kHz之间找一个平衡点既避开人耳最敏感的频率段又不至于让模块发热失控。5.2 低速死区20%占空比电机为什么不动另一个让新手抓狂的问题PWM占空比都写到50了约20%电机怎么还是不动只发出“嗡嗡”的声音这就是直流电机的死区现象。电机要转起来需要克服转子上的静摩擦力矩和负载力矩。当PWM占空比太低时平均电压太小产生的电磁力矩不足以推动转子电机就停在原地。但电流一直在过绕组电机听起来像在哼歌时间长了还会发热。解决思路很简单也是最常见的做法软启动。启动的时候先给一个较高的占空比比如80%运行50到100毫秒等电机真的转起来了再把占空比慢慢降到目标值。这样既能让电机从静止状态顺利启动又能在低速下保持转动。很多智能小车程序里你会看到pwm选择从120直接跳上去而不是从0开始慢慢爬就是为了绕开死区。还有一个实操经验如果你的小车需要很低的行驶速度与其硬调低占空比不如换更大减速比的电机或者机械齿轮。用PWM硬压速度电机发热、效率低、噪音大不如从机械结构上直接解决。5.3 把PWM频率提到3.9kHz的寄存器写法上面那段代码已经给了很直接的方式。再补充一点修改频率之后analogWrite()的占空比参数依然是0~255不影响你原来的代码这一点很友好。改完频率你可能会发现同样占空比下电机的转速和之前略有不同这是正常的因为高频PWM的电流纹波更小电机运行更平顺实际有效功率和490Hz时候不完全一样。如果你用的是ESP32或者STM32这类更高级的板子PWM频率、分辨率都是软件里直接配的就完全不需要动寄存器了。比如ESP32的ledcSetup()可以任意指定频率用起来非常灵活Arduino那套固定的PWM模式反而更像一个入门阶段的限制。但不管在哪个平台PWM的本质都一样用方波的占空比控制平均电压频率决定纹波和噪声死区决定最低可启动占空比。理解了这一层换什么板子你都能快速上手。顺带提一句以前很多人用555 PWM电路做调速一个555加几个电阻电容就能产生可调占空比的方波那个思路非常适合理解PWM的概念。现在用Arduino做软件PWM更方便但你理解了555的振荡原理对PWM的频率、占空比这些概念会理解得更深。6. 常见错误五忽略电流余量模块过热、重启、彻底烧毁最后一个错误不是接线错误是选型和负载估算方面的失误。L298N确实便宜大碗但它不是万能的。很多朋友把它用在大功率电机上结果模块热得能煎鸡蛋甚至直接冒烟烧毁。其实芯片本身是有明确电流天花板的。6.1 用万用表实测电机电流别凭感觉猜L298的数据手册写得清楚每个输出通道的持续电流是1A峰值能到2A。注意是“每个通道”不是两个通道加起来。如果是同时驱动两个电机两个通道各1A那总电流就是2A。但很多标称1A以下的减速电机工作时实际电流并不等于标签上的额定电流堵转的时候电流可以飙升到正常工作电流的5倍以上。所以拿到一个电机尤其是从玩具上拆下来的或者便宜套件里送的电机我的建议是先测电流。方法很简单把万用表打到直流电流档红表笔接电池正极黑表笔接L298N的VS串联进去然后让电机转起来读数值。再用手捏住电机轴模拟堵转看堵转电流有多大。注意堵转测试时间别太长几秒钟就够了否则电机线也会发热。实测下来如果堵转电流在2A以上L298N单通道就会非常吃力。这不仅仅是发热的问题过流保护不及时的话芯片内部会直接击穿输出电压异常电机要么不转要么全速转彻底失控。6.2 L298N和TB6612怎么选如果你的电机电流需求已经超过了L298N的安全范围或者你受不了L298N大电流下的发热可以看看TB6612FNG这个模块也是市面上很常见的“tb6612电机驱动模块”。它和L298N最大的区别是内部用了MOSFET做H桥导通电阻小压降低同样负载下发热比L298N小得多。对比项L298N模块TB6612FNG模块内部驱动器件双极型晶体管BJTMOSFET每通道持续电流约1A约1.2A峰值电流2A3.2A左右短时导通压降1.5~2.0V0.5V级别逻辑电源5V2.7V~5.5V可接3.3VPWM频率适应范围建议10kHz以内可以更高一些发热大电流下发热明显相对低很多模块尺寸大小从我实际体验来看做巡线小车、遥控小车这类负载不高的项目L298N完全够用胜在便宜和接线简单。但如果用的是大功率电机、双轴机器人、爬坡小车或者你想把模块塞进很小的空间TB6612是更合适的选择。还有一点TB6612的逻辑电压范围更宽能直接接3.3V的单片机比如ESP32、STM32系列不需要额外电平转换这一点特别方便。如果你的电流需求更大超过了TB6612的承受范围那就应该考虑分立MOS管H桥模块或者干脆上带霍尔编码器的电机加专用的电机驱动一步步升级各玩各的不用拘泥于某一种模块。这就像你买鞋前脚掌挤不挤只有上脚才知道电流也一样挂个万用表量一下心里就有底了。7. 遇到问题如何快速定位一张排查表和排错顺序前面5个错误可以单独出现也可以组合出现。跑到最后我建议你养成一个固定的排错习惯。下面这个速查表我调试的时候经常用也推荐给你症状可能原因排查方法电机完全不转电源没接好、ENA跳线帽没拔/没接、IN引脚悬空、供电电压不够先量VS电压用代码置ENA高电平再看IN电平电机全速飞车PWM无效ENA/ENB跳线帽没拔拔掉跳线帽ENA接Arduino PWM引脚只能正转不能反转IN1/IN2逻辑接反交换IN1和IN2的IO定义或对调电机两根线低速发抖、嗡嗡响占空比过低、死区用软启动起始占空比拉高电机转但Arduino重启干扰、共地不好、电源压降加共地、加电容、换更粗的电源线模块过热、转一会停一会电流超限、L298N过温保护测电流、换TB6612/大模块、加散热片数码管/传感器数据乱跳电机干扰串入电源和地共地、电源端电解电容、电机端104电容7.1 常见问题速查表上面表格基本覆盖了日常能碰到的绝大多数问题。如果你严格按照这个表格排查一遍还找不到原因那就要考虑是不是模块本身有问题了。可以换个L298N模块试一试毕竟模块质量良莠不齐有些山寨板子的器件参数缩水标注1A实际500mA就开始发烫这种就只能当教学耗材看待。7.2 从上到下的排错顺序排错有个顺序不要一上来就怀疑代码。我的习惯是先电源再逻辑再PWM最后才看程序。先电源用万用表直流电压档量VS和GND之间的电压确认电机电源确实到位。不合格的话换电池、换线、看有没有虚接。再逻辑检查ENA/ENB跳线帽状态检查Arduino和模块的GND有没有共地。然后PWM用一个简单的digitalWrite(ENA, HIGH)测试电机能否转能转说明方向逻辑没问题再换成analogWrite(ENA, 128)测试调速是否生效。最后程序把代码简化到最少逐个功能添加看到哪一步开始出问题。这套流程看起来麻烦其实化整为零最省时间。有个“最小硬件测试程序”的说法就是别一上来就写完整的小车巡线代码。先用两个按键控制一个电机正转、反转全速测试方向再用一个电位器控制PWM测试调速硬件链路通了再往上叠功能。很多所谓“玄学Bug”都是硬件和代码混在一起时出现一旦拆开排查问题特别清晰。在这里我也想顺便提一句如果你暂时没有硬件其实可以用Wokwi这类在线Arduino仿真平台先把逻辑跑通很多接线和代码逻辑在仿真是能查出来的。不过要注意仿真平台不会告诉你共地没接、跳线帽没拔这种事所以实物排错还是躲不掉。而且现在越来越多人的项目会从Arduino往ESP32迁移。ESP32的PWM通道更多、频率可配置范围更宽还能用蓝牙WiFi做无线遥控小车代码思路和驱动模块接线基本一样。等你在ArduinoL298N这套组合上积累了经验换到ESP32TB6612也是水到渠成的事。最后分享一个我自己的调试习惯拿到任何新的驱动模块我不会立刻写复杂程序而是先用最简单的代码把硬件链路测通。这个习惯救了我太多次。别看这只是一个很小的习惯它能让你在做更复杂项目的时候把精力放在算法和功能上而不是一遍遍怀疑电机模块坏了。做硬件就是这样基础打得越稳后面走得越快。
返回列表