尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

用ESP32从零打造一台可遥控的瓦力机器人

发布时间:2026/9/24 12:48:19

资讯中心
01
ARTICLE

用ESP32从零打造一台可遥控的瓦力机器人

用ESP32从零打造一台可遥控的瓦力机器人
从三年前第一次看《机器人总动员》起我就一直想动手做一台属于自己的瓦力。当时搜遍了市面上的套件要么是纯模型不能动要么是遥控底盘加个壳完全没有“它自己会思考”的那种感觉。直到接触ESP32之后我意识到这个设想终于能落地了——ESP32自带WiFi和蓝牙IO口多算力也够配上一堆3D打印零件和一套靠谱的电机驱动方案就能攒出一台既能在地面上灵活机动、又能用手机遥控、还能通过传感器感知环境的瓦力。这篇文章把我从打印第一块外壳到最后遥控跑通的完整过程拆开来讲涉及模型切片、电机驱动选型、接线供电、固件编写、无线遥控以及我在这个过程中踩过的所有坑。如果你也想做一台不光是摆着看、而是能跑能玩的瓦力或者说你想借这个项目系统接触一次ESP32的全栈开发这篇可以当你的参考手册。1. 这个项目到底在做什么它不是玩具而是一套完整的嵌入式训练场1.1 为什么选瓦力这个形象做机器人项目第一步往往不是画电路图而是想清楚你到底要做一个什么东西。瓦力这个IP形象有一层很现实的优势它的身体结构极其适合作为机器人底盘。瓦力的身体是左右两条履带这意味着它天然就是一台差速驱动机器人——不需要复杂的转向机构只需要控制左右两侧电机转速差就能实现前进、后退、原地转弯和弧线运动。它的眼睛是两根独立控制的光学传感器组件可以上下左右转动对应两个舵机就可以把“表情”做出来。它的方形身体内部空间足够塞下一块ESP32开发板、一个电机驱动模块和一块锂电池简直就是为DIY机器人量身定制的壳体。所以这个项目表面上是“复刻一个电影角色”实际上是借瓦力的外形走一遍完整的嵌入式开发流程3D打印结构件、直流减速电机的闭环控制、PWM调速、舵机驱动、无线通信、电源管理。这一整套东西做下来你收获的远远不止是一个能动的模型而是一套可以迁移到任何机器人项目上的底层能力。1.2 系统架构的总体拆解我在动手之前先把整个系统分成了四个层次第一层是机械本体也就是3D打印出来的外壳、履带轮、内部支架。这一层的核心问题是装配公差和强度。第二层是动力系统包括左右两个直流减速电机、两个舵机和对应的驱动模块。第三层是控制系统一块ESP32开发板负责读取指令、计算运动学、输出PWM信号。第四层是交互系统也就是无线遥控端我最终实现了蓝牙手机App和WiFi网页控制两种方式。层与层之间的接口要非常明确。比如电机驱动模块和ESP32之间只通过6根信号线连接舵机则走独立的PWM引脚电源统一由一块3.7V或7.4V锂电池供给再通过稳压模块分出不同电压给各个部分。把接口固定下来之后每一层都可以单独调试哪一层出问题也不会牵连到其他部分。1.3 材料清单和预算参考部件型号/规格数量用途主控乐鑫 ESP32 DevKitC V41运行控制逻辑、接收遥控指令电机130或N20直流减速电机1:482驱动左右履带电机驱动TB6612FNG1双路H桥电机驱动舵机SG90 9g2控制眼睛上下左右转动电池7.4V 18650锂电池组1整机供电稳压AMS1117-5.0或MP1584降压模块1舵机/ESP32供电3D打印PLA耗材约300g若干打印外壳和结构件这个清单的成本不算打印机能耗总体在200元上下。比起买一套现成的教育机器人套件这个项目不仅便宜得多而且每一个环节你都知道它为什么是这样设计的。2. 3D打印环节模型、切片参数和装配公差才是成败关键2.1 模型从哪里来瓦力的3D模型在各大模型站上有不少版本但质量参差不齐。我的经验是优先找那种“为实际组装而设计”的模型也就是作者明确标注了打印方向、预留了螺丝孔和卡扣位的版本。如果模型页面上展示的只是漂亮的渲染图没有任何内部结构的说明大概率打印出来只是只能看不能动的摆件。我自己用的是Thingiverse上一套分件方案大致分为身体左右壳体、履带轮左右组件、履带链节或一体化履带、眼睛组件、颈部组件、手臂、底盘框架。分件越多装配灵活性越大但打印时间也越长。如果你打印经验不多我建议选“身体一体打印履带分体”的方案减少后期粘接。2.2 切片参数设置建议打印参数直接影响装配效果我用Cura切片以下几个参数的调整对机器人项目尤其关键层高0.2mm比较均衡外观件如果想光滑可以降到0.12mm但结构件没必要。壁厚与外壳层数至少3层外壳也就是壁厚1.2mm以上。瓦力的身体要承受电机振动和电池重量壁太薄会在螺丝孔附近开裂。填充率结构件建议20%~30%纯外观件10%即可。履带轮这类受力件我会单独加到40%。支撑眼睛组件和颈部连接处几乎必然需要支撑建议打开“树形支撑”Tree Supports比普通支撑更容易拆除对细小结构的损伤也小。打印方向履带轮的轴孔要垂直于打印平台这样孔的圆度才有保证螺丝孔尽量让轴向竖直方向否则层间粘接力会让螺纹部分容易断裂。2.3 装配中的实际指导打印完成之后不要急着拧螺丝先把所有零件按位置摆开对一遍公差。PLA在打印不同批次时会有0.2~0.4mm的收缩差异这很正常。尤其是轴的配合我建议设计时预留0.3mm的间隙不然打印出来轴孔会紧到装不进去。装配顺序我摸索出的经验是先装底盘框架再把电机固定在框架里然后从左右两侧合上身体外壳最后安装履带。中间每固定一个零件就顺手转动一下电机输出轴确认没有卡涩。如果有卡涩多半是螺丝拧得过紧导致壳体变形或者轴孔有打印残留物用美工刀刮一下就能解决。另外一个容易被忽略的点是履带的松紧度。履带太紧会加剧电机负载导致电流偏大甚至堵转太松则会在转向时脱带。最合适的标准是装好履带后用手指在履带中间能按下2到3毫米的幅度这个松紧度既能保证动力传递又不会让电机过载。3. 电机驱动选型L298N、TB6612、DRV8833到底怎么选3.1 瓦力的运动机构与电机需求瓦力采用的是履带式差速驱动理论上只需要两个电机不需要转向舵机。这里说的电机是指带减速箱的直流减速电机输出轴转速一般在100~300转/分钟扭矩足够推动几百克的机身。直流减速电机的控制核心就是两件事方向和速度。方向由电枢两端电压极性决定速度由PWM占空比决定。要做到这两件事最经典的电路是H桥。3.2 H桥驱动电路原理H桥这个名字源自电路拓扑长得像字母H。四个开关管分别接在电机两端把同一侧的两个开关接通时电机正转把另一侧的两个开关接通时电机反转四个开关都断开时电机自由滑行同一侧两个开关同时闭合就是刹车。实际的电机驱动模块都是在这个原理上做的改进。你在使用任何驱动模块时只需要关心三组信号方向控制引脚IN1/IN2使能引脚EN或者直接给PWM以及供电引脚VM和逻辑电源VCC。3.3 不同驱动模块的实际对比模块最大电流PWM频率压降特点L298N2A/通道峰值较低较大约1.5~2V经典发热大适合学习TB6612FNG1.2A/通道可达100kHz较小低功耗适合小型机器人DRV88331.5A/通道可达250kHz极小体积小自带过流保护A4950峰值3.5A高极小适合大电流电机说到L298N很多教程还在推荐它理由是便宜且经典。我第一版也确实用了L298N但它有一个很实际的问题内部用的是三极管开关导通压降很高。7.4V电池经过L298N到电机实际到电机端的电压可能只剩5.5V左右表现为带载能力差、跑一会儿就开始烫手。对于瓦力这种小电流机器人L298N的体积和发热都显得不划算。相比之下TB6612FNG是MOS管H桥导通压降小体积只有指甲盖那么大空闲电流还低非常适合电池供电的小型机器人。我后来切到TB6612之后续航明显变长发热问题也消失了。3.4 我的最终选择我最终选择了TB6612FNG作为主驱动模块理由简单电流需求小、压降小、体积小、支持独立PWM调速。如果你的电机功率很大超过2A可以考虑A4950或者更高规格的模块但瓦力这个级别用TB6612是性价比最高的方案。DRV8833也是一个不错的选择它自带过流保护堵转时不容易烧芯片。只是DRV8833的封装更小焊接难度稍大如果经验不多还是选TB6612稳妥。4. 接线和供电最容易翻车的三个环节4.1 完整接线说明与引脚分配接线是整个项目中返工率最高的环节。我一开始凭记忆接线结果电机正负极接反、信号线插反折腾了半天。后来把所有引脚分配做成表格贴在开发板旁边再没出过这种问题。ESP32 GND → TB6612 GNDESP32 GPIO26 → TB6612 PWMA左侧电机PWMESP32 GPIO27 → TB6612 AIN1左侧电机方向1ESP32 GPIO14 → TB6612 AIN2左侧电机方向2ESP32 GPIO33 → TB6612 PWMB右侧电机PWMESP32 GPIO32 → TB6612 BIN1右侧电机方向1ESP32 GPIO15 → TB6612 BIN2右侧电机方向2ESP32 GPIO13 → 舵机1眼睛左右信号线ESP32 GPIO12 → 舵机2眼睛上下信号线电机接线要特别注意TB6612的两路输出AO1/AO2接左侧电机BO1/BO2接右侧电机。如果发现电机转向和控制逻辑相反直接交换这两个输出就好不需要改代码。4.2 供电架构与注意事项供电是第一个大坑。ESP32开发板上有板载USB转串口芯片很多人习惯直接用USB线供电调试但接上电机之后电机启动瞬间的大电流会把USB口的电压瞬间拉低导致ESP32直接掉电重启。更严重的情况是USB口供电能力不足时电机的反电动势会沿着地线窜进ESP32把GPIO口打坏。正确的供电方式是电池正负极先接到一个总开关然后分两条路。一路通过降压模块降到5V给舵机和ESP32的5V引脚供电另一路直接给电机驱动模块VM引脚供电。两组地线必须连到一起否则PWM信号没有参考地电机根本无法正常控制。7.4V锂电池经过TB6612的VM引脚直接驱动电机是没问题的但我建议在电池和VM之间加一个大电容比如470uF电解电容用于吸收电机启动时的瞬态电流波动。没有这个电容电池电压在电机急加速时会跌出ESP32稳压范围表现为机器人急停时指示灯闪一下。4.3 保护与滤波电机是感性负载启停时会产生反向感应电动势。虽然TB6612内部集成了续流二极管但为了保险起见我仍然建议在电机两端并联一个小容量的瓷片电容104来吸收高频噪声。这个噪声如果不处理会在蓝牙遥控时表现为随机性的丢命令。舵机对电源纹波的要求比电机更高。舵机启动瞬间的电流非常大如果和ESP32共用一条电源线会导致ESP32复位。我在舵机电源线上串了一个二极管压降约0.7V并把舵机地线直接接到电池负极把这个瞬时电流隔离在控制电路之外重启问题彻底消失。5. 固件开发从点动电机到自动巡线的前置铺垫5.1 开发环境搭建ESP32的开发环境有两种主流的搭法Arduino IDE和PlatformIO。我推荐PlatformIO原因有三点项目管理清晰、库依赖版本可控、编译速度比Arduino IDE快很多。安装PlatformIO之后先创建一个基于espressif32平台的项目选择开发板型号为esp32dev。这个平台的工具链会自动下载唯一可能卡住的地方是网络下载太慢耐心等就行。5.2 电机驱动基础代码先用最简单的代码验证电机驱动是否正常。下边这段代码让左右电机交替正反转各两秒#include Arduino.h const int PWMA 26; const int AIN1 27; const int AIN2 14; const int PWMB 33; const int BIN1 32; const int BIN2 15; void setup() { pinMode(PWMA, OUTPUT); pinMode(AIN1, OUTPUT); pinMode(AIN2, OUTPUT); pinMode(PWMB, OUTPUT); pinMode(BIN1, OUTPUT); pinMode(BIN2, OUTPUT); } void setMotorA(int speed, bool forward) { digitalWrite(AIN1, forward ? HIGH : LOW); digitalWrite(AIN2, forward ? LOW : HIGH); analogWrite(PWMA, speed); } void setMotorB(int speed, bool forward) { digitalWrite(BIN1, forward ? HIGH : LOW); digitalWrite(BIN2, forward ? LOW : HIGH); analogWrite(PWMB, speed); } void loop() { setMotorA(200, true); setMotorB(200, true); delay(2000); setMotorA(200, false); setMotorB(200, false); delay(2000); }注意ESP32的analogWrite背后用的是LEDC PWM模块频率默认是5kHz对直流电机的控制来说足够了。如果你用Arduino的analogWrite函数需要在初始化时设置ledcSetup和ledcAttachPin不过新版本的Arduino-ESP32核心已经把analogWrite封装好了直接使用没有毛病。5.3 头部的舵机控制瓦力的眼睛部分是整个模型的灵魂。我用两个SG90舵机实现眼睛的左右转动和上下摆动代码层面只需要给对应引脚输出不同占空比的PWM信号。SG90的标准PWM频率是50Hz脉宽0.5ms对应0度2.5ms对应180度。如果用ESP32的LEDC来实现#include ESP32Servo.h Servo eyeServoX; Servo eyeServoY; void setup() { eyeServoX.attach(13); eyeServoY.attach(12); } void loop() { eyeServoX.write(90); eyeServoY.write(90); delay(1000); eyeServoX.write(0); delay(500); eyeServoX.write(180); delay(500); }ESP32Servo库已经自动处理了PWM脉宽到舵机角度的转换不需要自己算计数值。如果舵机振动或者听到明显嗞嗞声多半是供电电压不足或者PWM频率不对。5.4 运动控制逻辑封装有了电机和舵机的基础能力之后我把运动控制封装成了一组高阶函数这样后续接遥控指令时不用再逐条重复底层寄存器操作void forward(int speed) { setMotorA(speed, true); setMotorB(speed, true); } void backward(int speed) { setMotorA(speed, false); setMotorB(speed, false); } void turnLeft(int speed) { setMotorA(0, true); setMotorB(speed, true); } void turnRight(int speed) { setMotorA(speed, true); setMotorB(0, true); } void stopMotors() { setMotorA(0, true); setMotorB(0, true); }这套封装的好处是后续接蓝牙、WiFi或者手机App时只需要在指令解析函数里调用forward(200)或turnLeft(150)就行代码逻辑非常清晰。这也是我第一次强烈建议新手把代码分层——驱动层、逻辑层、应用层分开写出bug时定位会轻松很多。6. 无线遥控实现蓝牙和WiFi两条路线的完整改造6.1 蓝牙遥控串口透传最省事ESP32支持经典蓝牙BR/EDR和低功耗蓝牙BLE对遥控场景而言各有优劣。经典蓝牙的优点是延迟低、吞吐量大手机端能像操作串口一样直接收发数据BLE的优点是省电、配对快但数据包小不适合高频传输。我的第一版遥控就是用的经典蓝牙手机端装一个“蓝牙串口”App与ESP32配对后建立虚拟串口连接App里发送的每一个字符都能直接进入ESP32的串口缓冲区。代码只需要在初始化时开启蓝牙功能#include BluetoothSerial.h #if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BT_SPP_ENABLED) #error 请在menuconfig中开启蓝牙串口支持 #endif BluetoothSerial SerialBT; void setup() { Serial.begin(115200); SerialBT.begin(WALL-E); pinMode(PWMA, OUTPUT); // 其余引脚初始化省略 } void loop() { if (SerialBT.available()) { char cmd SerialBT.read(); switch (cmd) { case F: forward(220); break; case B: backward(220); break; case L: turnLeft(180); break; case R: turnRight(180); break; case S: stopMotors(); break; } } }这只是一个最精简的遥控器实际上把按键事件映射成单个字符、然后通过蓝牙串口发送即可。实测经典蓝牙的响应延迟在50毫秒以内手动遥控完全够用。6.2 WiFi遥控网页端和MQTT蓝牙遥控有一个限制就是距离。蓝牙有效距离大约10米想在另一个房间遥控就不太行了。ESP32另一个强项是WiFi通过WiFi我可以把瓦力接入家庭局域网用浏览器或者手机App随时控制。最简单的WiFi遥控方案是ESP32作为Web服务器在浏览器里打开控制页面点击按钮发出HTTP请求ESP32解析请求后执行对应动作。#include WiFi.h #include WebServer.h const char* ssid your_wifi; const char* password your_password; WebServer server(80); void handleRoot() { String html !DOCTYPE htmlhtmlheadmeta charsetUTF-8; html title瓦力遥控/title/headbody; html h2WALL-E Control/h2; html button onclick\fetch(/forward)\前进/button; html button onclick\fetch(/backward)\后退/button; html button onclick\fetch(/left)\左转/button; html button onclick\fetch(/right)\右转/button; html button onclick\fetch(/stop)\停止/button; html /body/html; server.send(200, text/html, html); } void setup() { WiFi.begin(ssid, password); while (WiFi.status() ! WL_CONNECTED) { delay(500); } server.on(/, handleRoot); server.on(/forward, []() { forward(220); server.send(200, text/plain, OK); }); server.on(/backward, []() { backward(220); server.send(200, text/plain, OK); }); server.on(/left, []() { turnLeft(180); server.send(200, text/plain, OK); }); server.on(/right, []() { turnRight(180); server.send(200, text/plain, OK); }); server.on(/stop, []() { stopMotors(); server.send(200, text/plain, OK); }); server.begin(); } void loop() { server.handleClient(); }WiFi方案的好处是可以用手机浏览器直接控制不需要安装任何App而且还能顺便通过HTTP接口把电池电压、温度等遥测数据传回页面。不过HTTP的开销比蓝牙串口略大如果操作频率太高浏览器页面会有一点点卡顿感。6.3 蓝牙和WiFi同时启用的坑ESP32的蓝牙和WiFi可以同时工作但有一个经典问题两者共存时蓝牙的实时性会明显下降。官方给的解释是ESP32的射频前端在2.4GHz频段上是时分复用的WiFi一旦繁忙蓝牙的时隙会被压缩表现为蓝牙遥控偶尔丢字符。我的解决办法是双模式切换WiFi模式下关闭蓝牙蓝牙模式下关闭WiFi。默认上电时先开启蓝牙当收到WiFi连接建立的指令时先关闭蓝牙服务再启动WiFi反向切换同理。这种做法的好处是电源效率更高而且不会出现两种无线接口同时抢射频的问题。7. 实测中遇到的坑和排查方法7.1 问题一电机只能前进不能后退症状按下后退键电机完全不动但如果手动反向推一下履带它又能转了。排查链路先检查驱动模块AIN1/AIN2的电平后退时AIN1应为LOW、AIN2应为HIGH。如果电平正确再测量电机端电压发现电压只有零点几伏——这说明PWM占空比虽然设置了但H桥下桥臂没有正常导通。最后发现是TB6612的GND没有和ESP32共地PWM信号没有参考回路。把两端GND接上之后后退功能立刻恢复正常。这是我踩过最蠢也最典型的坑共地问题在新手项目中出现概率非常高。7.2 问题二电机通电后只抖不转症状给了PWM信号电机发出嗡嗡声但输出轴不转动手动拨一下助转后才正常工作。这个问题的本质是电压太低导致电机启动扭矩不足。切成7.4V双节锂电池供电后问题自然消失。如果不想换电池可以在代码里做软启动PWM占空比在100毫秒内从0平滑升到目标值这样即使电压略低也能可靠启动。7.3 问题三3D打印件在螺丝孔位置开裂症状装好螺丝用了两天螺丝孔附近出现裂缝。原因有两方面一是PLA材料的层间粘接力本身有限螺丝拧的时候用力过猛会产生层间应力二是模型打印方向不对螺丝孔的轴向如果和打印层平行强度会非常低。我重新打印了开裂的零件把螺丝孔轴向改成垂直方向并换用热熔嵌铜螺母而不是直接往塑料孔里拧自攻螺丝。铜螺母嵌入后螺丝扭矩传递到金属螺纹上塑料件就再也没裂过。7.4 问题四舵机一动作ESP32就重启症状跑程序一切正常但只要让眼睛舵机转到角度极限ESP32就会重启。排查发现SG90舵机堵转时电流能到500毫安以上瞬间把5V电源拉垮ESP32内部的3.3V稳压器随之掉电复位。修复方案是在舵机电源线路上预留一个独立的低压差稳压器如AMS1117-3.3给ESP32供电舵机单独从5V供电。说得更直接一点不要让舵机和ESP32共用同一条电源路径哪怕它们在标称电压上是一样的。7.5 问题五蓝牙能连接但遥控延迟不稳定症状手机显示蓝牙已连接但按键之后瓦力要等几百毫秒才响应偶尔还会连续执行同一条指令。排除了代码层面的死循环问题后怀疑是蓝牙缓冲区里残留了历史指令。因为每次按键App端发送的字符会排队进入串口缓冲区如果上一轮循环没读完下一轮就会把积压的旧指令一起执行。我改用按行读取readStringUntil每条指令末尾加换行符并且在进入遥控模式时先把缓冲区清空。修复之后延迟稳定在几十毫秒级别。蓝牙串口看似简单但积压缓冲区的问题被很多人忽略。8. 项目的现状与二次扩展思路目前这台瓦力已经能通过手机蓝牙和局域网Web页面实现前进、后退、左右转向、原地旋转和眼睛上下左右转动。电池续航大约两小时换了高容量18650之后能跑得更久。这个项目留给我的最大经验是做DIY电子项目硬件选型的重要性不亚于代码性能。L298N并不是不能做瓦力但一个压降更小的TB6612直接让整机的动力表现提升了一个档次。同样ESP32同时集成蓝牙和WiFi的特性让遥控方案的切换变得非常丝滑这也是我后来一直推荐用ESP32做机器人主控的原因。如果你也想搭一台类似的机器人我建议你按照这篇文章的顺序来先打印、再驱动、固定位、再遥控每一步都验证透了再往下走。不要急着一次性把所有模块全部接通——模块越多问题越难排查。做下来之后你会发现真正难的不是任何单个技术点而是如何把这些环节串成一个稳定运行的系统。而这套串联能力恰恰是做任何机器人项目最值钱的部分。
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。