精通 L298N 电机驱动:Arduino 控制、原理图与示例代码
概述
本 Arduino 教程将学习如何用 Arduino 控制直流电机。我们将介绍控制直流电机的基本技术,并通过两个示例学习如何使用 L298N 电机驱动板和 Arduino 控制直流电机。
你可以观看下方视频或阅读以下图文教程。
PWM 直流电机调速
控制直流电机速度最常用的方法是控制输入电压,通常采用 PWM(脉宽调制)信号。PWM 通过高频开关电源,调节导通占空比来改变平均电压。


根据电机功率,可用 Arduino PWM 引脚驱动三极管或 MOSFET 栅极,以低功率 PWM 控制高功率电机。

H 桥直流电机换向
控制旋转方向需改变电流方向,最常用的是 H 桥电路。H 桥由四个开关元件(三极管/MOSFET)组成,电机在中心形成 H 形。同时导通对角两管即可改变电流方向,从而改变转向。

结合 PWM 和 H 桥即可完全控制直流电机。L298N 就是集成了这两种功能的驱动芯片。
L298N 驱动板
L298N 是双 H 桥驱动器,可同时控制两路直流电机的速度和方向。驱动电压 5-35V,峰值电流 2A。

引脚说明:两路电机接线端子(A/B),电源端子(GND、VCC、5V)。板载 5V 稳压器由跳线帽启用/禁用:电机供电 ≤12V 时可接跳线帽,5V 引脚作输出可给 Arduino 供电;>12V 必须拔掉跳线帽,5V 引脚作输入需外接 5V 给芯片供电。注意 L298N 内部约 2V 压降,如 12V 供电电机端仅得 ~10V,无法发挥 12V 电机最高转速。


逻辑控制引脚:ENA/ENB 使能并控制速度(接跳线帽全速,接 PWM 调速,接地禁用);IN1/IN2 控制电机 A 方向,IN3/IN4 控制电机 B。IN1 低 IN2 高 → 正转;IN1 高 IN2 低 → 反转;同电平停止。同理 IN3/IN4。

Arduino 与 L298N 电机驱动
示例 1:电位器调速 + 按钮换向

所需:L298N、直流电机、电位器、按钮、Arduino。
- L298N 驱动板
- 12V 高扭矩直流电机
- 带轮胎直流电机
- Arduino 开发板
- 面包板和跳线
Arduino 代码
/* Arduino 直流电机控制 - PWM | H桥 | L298N - 示例 01 by Dejan Nedelkovski, www.HowToMechatronics.com */
#define enA 9
#define in1 6
#define in2 7
#define button 4
int rotDirection = 0;
bool pressed = false;
void setup() {
pinMode(enA, OUTPUT); pinMode(in1, OUTPUT); pinMode(in2, OUTPUT); pinMode(button, INPUT);
digitalWrite(in1, LOW); digitalWrite(in2, HIGH); // 初始正转
}
void loop() {
int potValue = analogRead(A0);
int pwmOutput = map(potValue, 0, 1023, 0, 255);
analogWrite(enA, pwmOutput); // PWM 给使能引脚
// 按钮消抖切换方向
if (digitalRead(button) == true) { pressed = !pressed; }
while (digitalRead(button) == true); delay(20);
if (pressed && rotDirection == 0) { digitalWrite(in1, HIGH); digitalWrite(in2, LOW); rotDirection = 1; delay(20); }
if (!pressed && rotDirection == 1) { digitalWrite(in1, LOW); digitalWrite(in2, HIGH); rotDirection = 0; delay(20); }
}
说明:定义引脚变量。setup 设引脚模式和初始方向。loop 读电位器映射 0-255 写 ENA 产生 PWM。按钮消抖后切换 IN1/IN2 电平实现正反转切换。
示例 2:Arduino 机器人小车(摇杆控制双电机)

底盘用 3mm 胶合板,金属支架固定电机,装轮子和万向轮。供电三节 3.7V 锂电串联 11V。

代码核心逻辑:
int xAxis = analogRead(A0); // 摇杆 X
int yAxis = analogRead(A1); // 摇杆 Y
摇杆中位约 512,容差 470-550 视为中立。Y 轴控制前进后退:<470 后退,>550 前进,map 映射为 0-255 PWM。X 轴控制左右转向:<470 左转(左减右加),>550 右转(右减左加),算术运算后用 if 限幅 0-255。低速防抖(<70 设 0)。最后 analogWrite 给 ENA/ENB。


// Y轴前进后退
if (yAxis < 470) { digitalWrite(in1,HIGH); digitalWrite(in2,LOW); digitalWrite(in3,HIGH); digitalWrite(in4,LOW); motorSpeedA=map(yAxis,470,0,0,255); motorSpeedB=map(yAxis,470,0,0,255); }
else if (yAxis > 550) { digitalWrite(in1,LOW); digitalWrite(in2,HIGH); digitalWrite(in3,LOW); digitalWrite(in4,HIGH); motorSpeedA=map(yAxis,550,1023,0,255); motorSpeedB=map(yAxis,550,1023,0,255); }
else { motorSpeedA=0; motorSpeedB=0; }
// X轴左右
if (xAxis < 470) { int xMapped=map(xAxis,470,0,0,255); motorSpeedA-=xMapped; motorSpeedB+=xMapped; if(motorSpeedA<0)motorSpeedA=0; if(motorSpeedB>255)motorSpeedB=255; }
if (xAxis > 550) { int xMapped=map(xAxis,550,1023,0,255); motorSpeedA+=xMapped; motorSpeedB-=xMapped; if(motorSpeedA>255)motorSpeedA=255; if(motorSpeedB<0)motorSpeedB=0; }
// 低速防抖
if (motorSpeedA<70) motorSpeedA=0; if (motorSpeedB<70) motorSpeedB=0;
analogWrite(enA,motorSpeedA); analogWrite(enB,motorSpeedB);
完整机器人小车代码
/* Arduino 直流电机控制 - PWM | H桥 | L298N 示例 02 - Arduino 机器人小车控制 by Dejan Nedelkovski, www.HowToMechatronics.com */
#define enA 9 #define in1 4 #define in2 5
#define enB 10 #define in3 6 #define in4 7
int motorSpeedA=0, motorSpeedB=0;
void setup() {
pinMode(enA,OUTPUT); pinMode(enB,OUTPUT);
pinMode(in1,OUTPUT); pinMode(in2,OUTPUT);
pinMode(in3,OUTPUT); pinMode(in4,OUTPUT);
}
void loop() {
int xAxis=analogRead(A0); int yAxis=analogRead(A1);
if (yAxis < 470) { digitalWrite(in1,HIGH); digitalWrite(in2,LOW); digitalWrite(in3,HIGH); digitalWrite(in4,LOW); motorSpeedA=map(yAxis,470,0,0,255); motorSpeedB=map(yAxis,470,0,0,255); }
else if (yAxis > 550) { digitalWrite(in1,LOW); digitalWrite(in2,HIGH); digitalWrite(in3,LOW); digitalWrite(in4,HIGH); motorSpeedA=map(yAxis,550,1023,0,255); motorSpeedB=map(yAxis,550,1023,0,255); }
else { motorSpeedA=0; motorSpeedB=0; }
if (xAxis < 470) { int xMapped=map(xAxis,470,0,0,255); motorSpeedA-=xMapped; motorSpeedB+=xMapped; if(motorSpeedA<0)motorSpeedA=0; if(motorSpeedB>255)motorSpeedB=255; }
if (xAxis > 550) { int xMapped=map(xAxis,550,1023,0,255); motorSpeedA+=xMapped; motorSpeedB-=xMapped; if(motorSpeedA>255)motorSpeedA=255; if(motorSpeedB<0)motorSpeedB=0; }
if (motorSpeedA<70) motorSpeedA=0; if (motorSpeedB<70) motorSpeedB=0;
analogWrite(enA,motorSpeedA); analogWrite(enB,motorSpeedB);
}
本教程到此结束,下期将为这台小车加装蓝牙和无线模块实现手机/无线控制。欢迎评论区提问,别忘了查看我的 Arduino 项目合集。
制造工艺
- 用 Arduino 制作万能红外遥控器:分步指南
- Arduino UNO 自制循迹小车:从零构建自主巡线机器人
- Arduino Mega 2560 接 NEO-6M GPS 模块完整教程
- Arduino Mega 2560 综合实训平台 - 传感器/电机/显示/PCB 一体化开发板
- 热敏电阻测温轻松上手:Arduino 分步实战教程
- DIY 手势控制机械臂:基于 Arduino + 柔性传感器 + IMU + 蓝牙的六自由度仿生臂
- 高性能 Arduino 直流电机控制库
- 废旧 DVD 光驱改装迷你 CNC 2D 绘图机 —— 基于 L293D 电机扩展板
- 在家用 Arduino 和 MPU-6050 构建手势控制机器人
- 掌握 Arduino 多任务编程:原型线程分步教程
- 直驱电机(Direct Drive Motor)技术全景:原理、分类、优势与工业应用
- 脑机接口:重连思维与行动