🚗 ESP32 L298N 电机驱动:让你的项目跑起来

📅 2026-05-25 · 📂 硬件编程 · ⏱ 阅读约 10 分钟

📺 B站推荐视频:Esp32使用L298N电机驱动模块控制电机 | 无字天书上海 · 11分钟手把手接线+代码

📦 物料清单

物料型号/参数数量参考价格
ESP32 开发板ESP32-WROOM-32 / ESP32-S31¥15~25
L298N 电机驱动模块红色 PCB 标准版(带散热片)1¥4~8
TT 减速电机1:48 减速比, 3~6V, 200RPM2¥5~8/个
18650 锂电池3.7V × 2 节串联(或 7.4V 电池组)2¥8~15/节
18650 电池盒2 节串联带 DC 插头1¥3~5
杜邦线公母各 10 根若干¥2~3
小车底盘2WD 亚克力底盘 + 轮胎1¥15~25
DC 电源插头5.5×2.1mm 公头转接线1¥1~2

💰 总计:约 ¥60~100(不含运费)。整套入门小车成本不到一百块。

🔌 接线图

L298N 模块有三组关键引脚:电源组、控制组、输出组。接线时务必注意:ESP32 的 GND 必须和 L298N 的 GND 共地!

┌─────────────────────────────────────────────────────────┐
│                    L298N 接线图                          │
├─────────────────────────────────────────────────────────┤
│                                                         │
│  【电源组】                                              │
│  L298N 12V  ──── 电池正极 (7.4V)                        │
│  L298N GND  ──── 电池负极 + ESP32 GND(共地!)          │
│  L298N 5V   ──── ESP32 VIN (5V)  ← 模块给ESP32供电      │
│           (拔掉 5V 使能跳线帽则需外接 5V)              │
│                                                         │
│  【控制组 — 电机A】                                      │
│  L298N IN1  ──── ESP32 GPIO 26                         │
│  L298N IN2  ──── ESP32 GPIO 27                         │
│  L298N ENA  ──── ESP32 GPIO 14  (PWM调速,拔掉跳线帽)   │
│                                                         │
│  【控制组 — 电机B】                                      │
│  L298N IN3  ──── ESP32 GPIO 32                         │
│  L298N IN4  ──── ESP32 GPIO 33                         │
│  L298N ENB  ──── ESP32 GPIO 15  (PWM调速,拔掉跳线帽)   │
│                                                         │
│  【输出组】                                              │
│  L298N OUT1/OUT2 ──── 电机A (左轮)                      │
│  L298N OUT3/OUT4 ──── 电机B (右轮)                      │
│                                                         │
└─────────────────────────────────────────────────────────┘
⚠️ 跳线帽说明:L298N 模块上 ENA 和 ENB 旁边各有一个黄色跳线帽。跳线帽插上 = 使能脚接 5V = 全速运行。
如果你要用 PWM 调速必须先拔掉跳线帽,然后用杜邦线将 ENA/ENB 分别连到 ESP32 的 PWM 引脚。不拔跳线帽直接接 GPIO 会导致 5V 灌入 ESP32 引脚——有烧板风险!

💻 基础代码:电机正反转 + PWM 调速

下面是一份完整的 Arduino 代码,实现两个电机的正转、反转、停止、PWM 调速功能。使用 analogWrite() 或 ESP32 的 ledcWrite() 来输出 PWM。

/** * ESP32 + L298N 双电机控制 * 功能:前进 / 后退 / 左转 / 右转 / 停止 / 调速 * 引脚:IN1=26, IN2=27, ENA=14, IN3=32, IN4=33, ENB=15 */ #define IN1 26 #define IN2 27 #define ENA 14 #define IN3 32 #define IN4 33 #define ENB 15 // PWM 参数 const int freq = 5000; const int resolution = 8; const int pwmChannelA = 0; const int pwmChannelB = 1; void setup() { pinMode(IN1, OUTPUT); pinMode(IN2, OUTPUT); pinMode(IN3, OUTPUT); pinMode(IN4, OUTPUT); // 配置 ESP32 PWM(替代 analogWrite) ledcSetup(pwmChannelA, freq, resolution); ledcSetup(pwmChannelB, freq, resolution); ledcAttachPin(ENA, pwmChannelA); ledcAttachPin(ENB, pwmChannelB); Serial.begin(115200); Serial.println("🚗 L298N 双电机控制启动!"); } // 电机A控制(左轮) void motorA(int speed) { if (speed > 0) { digitalWrite(IN1, HIGH); digitalWrite(IN2, LOW); } else if (speed < 0) { digitalWrite(IN1, LOW); digitalWrite(IN2, HIGH); } else { digitalWrite(IN1, LOW); digitalWrite(IN2, LOW); } ledcWrite(pwmChannelA, abs(speed)); } // 电机B控制(右轮) void motorB(int speed) { if (speed > 0) { digitalWrite(IN3, HIGH); digitalWrite(IN4, LOW); } else if (speed < 0) { digitalWrite(IN3, LOW); digitalWrite(IN4, HIGH); } else { digitalWrite(IN3, LOW); digitalWrite(IN4, LOW); } ledcWrite(pwmChannelB, abs(speed)); } // 小车动作宏 void forward(int speed) { motorA(speed); motorB(speed); } void backward(int speed) { motorA(-speed); motorB(-speed); } void turnLeft(int speed) { motorA(-speed); motorB(speed); } void turnRight(int speed) { motorA(speed); motorB(-speed); } void stopCar() { motorA(0); motorB(0); } void loop() { Serial.println("➡️ 前进 (150/255)"); forward(150); delay(2000); Serial.println(⏸️ 停止"); stopCar(); delay(1000); Serial.println(↩️ 左转 (180/255)"); turnLeft(180); delay(1500); Serial.println(↪️ 右转 (180/255)"); turnRight(180); delay(1500); Serial.println(⬅️ 后退 (120/255)"); backward(120); delay(2000); stopCar(); delay(3000); }
💡 代码解读:
speed 范围 0~255(8 位分辨率)——正数正转,负数反转。
• ESP32 没有硬件 analogWrite(),必须用 ledcSetup + ledcAttachPin + ledcWrite 三件套输出 PWM。
forward(150) 只开到约 60% 功率——低速先测试,避免小车冲出去!
• 左右轮的 motorA/motorB 函数中 speed 正负独立——所以 turnLeft 是左轮反转+右轮正转,实现原地转弯(差速转向)。

🚀 进阶应用

1. Web 遥控小车(结合 WiFi)

还记得 WebServer 教程吗?把 L298N 控制函数嵌入 Web 服务器,用手机浏览器遥控小车:

// 在 loop() 之前加入 WebServer(需要先连 WiFi) #include <WiFi.h> #include <WebServer.h> WebServer server(80); void handleForward() { forward(180); server.send(200, "text/plain", "前进"); } void handleBackward() { backward(180); server.send(200, "text/plain", "后退"); } void handleLeft() { turnLeft(200); server.send(200, "text/plain", "左转"); } void handleRight() { turnRight(200); server.send(200, "text/plain", "右转"); } void handleStop() { stopCar(); server.send(200, "text/plain", "停止"); } void setup() { // ... 电机引脚初始化同上 ... WiFi.begin("热点名", "密码"); while (WiFi.status() != WL_CONNECTED) delay(500); server.on("/forward", handleForward); server.on("/backward", handleBackward); server.on("/left", handleLeft); server.on("/right", handleRight); server.on("/stop", handleStop); server.begin(); }

手机连同一 WiFi,浏览器访问 http://esp32_ip/forward 即可控制小车——这就是最简 Web 遥控车!

2. 超声波自动避障

L298N + HC-SR04 超声波 = 自动避障小车。核心逻辑:

// 避障循环(伪代码骨架) void loop() { long distance = readUltrasonic(); // 读取前方距离 if (distance > 30) { forward(150); // 安全 → 直行 } else if (distance > 15) { turnRight(180); // 靠近 → 右转避让 delay(500); } else { backward(150); // 太近 → 后退 delay(800); turnLeft(200); // 左转绕开 delay(600); } }

🎯 实战场景

场景一:RFID 刷卡启动智能小车

场景描述:制作一台只有刷授权 IC 卡才能启动的智能小车——刷对卡启动,刷错卡报警。适合教学演示和实验室设备管理。

物料组合:ESP32 + L298N + TT 电机 + RC522 RFID + 有源蜂鸣器

工作流程:

  1. ESP32 上电后电机锁定(不转),等待刷卡
  2. RC522 读到卡 → 比对预存的白名单 UID
  3. UID 匹配 → 蜂鸣器短响 1 声 → forward(180) 启动小车
  4. UID 不匹配 → 蜂鸣器长响报警 → 电机不启动
  5. 再次刷卡 → 停车,回到锁定状态

这是一个完整的状态机项目——融合了 SPI 通信(RC522)、GPIO 控制(L298N)、PWM 调速,是从「点灯」迈向「系统级」的关键一步。

场景二:MQTT 远程物流小车

场景描述:办公室/仓库场景,用 MQTT 协议远程调度一台物流小车,从工位 A 运送到工位 B。

物料组合:ESP32 + L298N + 小车底盘 + MQTT 联网

工作流程:

  1. ESP32 连 WiFi 后订阅 cart/control 主题
  2. 手机/电脑通过 MQTT 客户端发送 "forward" / "left" / "stop" 等指令
  3. ESP32 收到消息 → 调用对应 motor 函数 → 小车执行动作
  4. 每 2 秒上报一次电池电压到 cart/status 主题(ADC 读电池电压)

这个场景串联了 L298N(驱动)+ WiFi(网络)+ MQTT(协议)+ ADC(电池监测)四大模块——是 IoT 机器人项目的标准架构。

❓ 常见问题

🔴 电机不转,但代码上传成功了

最常见原因:L298N 的 ENA/ENB 跳线帽没插,又没接 PWM 信号。
跳线帽是 ENA/ENB 的使能开关——如果你既拔了跳线帽没给 ENA 引脚接杜邦线到 ESP32 GPIO,ENA 脚相当于悬空,电机绝对不会转

快速排查:把跳线帽插回去 → 上传一个最简单的 digitalWrite(IN1, HIGH); digitalWrite(IN2, LOW); 看电机是否转。转 = 问题在 PWM 接线;不转 = 检查电源。
🔴 ESP32 USB 供电时电机无力/重启

根本原因:电脑 USB 端口只能提供 500mA(USB 2.0)或 900mA(USB 3.0)。两个 TT 电机起步就要 300~500mA(空载),带载轻松破 1A——USB 供电瞬间被拉低,ESP32 欠压重启。

正确做法:使用 7.4V(2 节 18650)独立电池组给 L298N 12V 端子供电。L298N 上的 5V 输出可以给 ESP32 供电,但要确认模块板载 5V 稳压的散热能力。
🔴 PWM 调速无效,电机总是全速转

常见原因 1:ENA/ENB 跳线帽还插着——这会强制使能脚拉高到 5V,PWM 信号被「覆盖」。必须拔掉跳线帽。
常见原因 2:ESP32 的 PWM 通道配置有误。注意 ESP32 的 ledcAttachPin 在某些引脚上不支持,推荐用 GPIO 14/15/16/17/18/19 这些无冲突引脚。
常见原因 3:L298N 的 ENA/ENB 引脚内部有上拉——如果你在代码里设 ENA 为 INPUT,它默认读到 HIGH,所以全速。必须设为 OUTPUT。
🔴 小车左右轮转速不一致,走不直

这是 TT 减速电机的通病——两个电机制造公差导致同样 PWM 下转速不同。

解决方法:
软件校准:单独测试每个电机,找出使两轮转速相等时的 PWM 差值。例如左轮 150 和右轮 140 同速——在 forward() 中用不同参数。
加编码器:升级到带霍尔编码器的电机(如 JGB37-520),用 PID 闭环控制转速——这就是下一阶段的内容。
加陀螺仪:用 MPU6050 读取偏航角,实时修正方向。