用ESP32做一台迷你WiFi机器人,最吸引人的地方不是它有多炫酷,而是你能在手机上实时看到摄像头画面,同时通过WiFi控制它移动。这个过程会把嵌入式、WiFi通信、视频流和运动控制这几块知识串起来,非常适合想从零接触物联网和机器人开发的人。我实测下来的感受是:如果只做固定摄像头监控,难度不高;一旦加上电机控制和实时视频传输,就要认真处理供电、连接稳定性和并发访问的问题。下面按我自己的落地顺序拆一遍,尽量让新手也能跟着跑通。
先把结论放在前面:这个项目的核心价值,是让你在同一个页面里看到画面、按下按钮、看到小车动。它不是一个能自己导航避障的机器人,而是“带眼睛的遥控车”。适合用来练手,也适合做课程设计、宿舍监控、桌面巡查这类场景。如果你把它当成一个完整产品来期待,可能会失望;当成学习载体和实践项目,就很值。
1. 核心能力与适用场景:这台机器人到底解决什么问题
1.1 视频传输和遥控的关键点
迷你WiFi机器人最核心的能力有两块:一是通过ESP32-CAM等模块把摄像头采集到的画面压缩成视频流,通过WiFi推送到手机或电脑浏览器;二是接收来自手机或电脑的控制指令,驱动电机实现前进、后退、左转、右转。
这两件事看起来简单,实际落地时要注意一个矛盾点:视频流需要持续占用WiFi带宽,控制指令也需要实时性。如果同一时间大量数据拥挤在一个通道里,就会出现画面卡顿、指令延迟甚至断连。所以这个项目的难点不在于“能不能把代码跑通”,而在于“稳定性和并发处理”。
我建议先跑通单机演示,再考虑在同一个Web页面里同时显示画面和按钮。这样做的好处是,你可以在一个页面上看效果,不用来回切换窗口。
1.2 适合谁做,需要什么基础
这个项目适合三类人:嵌入式入门者、机器人爱好者和做课设/毕设的学生。你需要具备的基础不多,会一点Arduino编程、能看懂简单的电路图就够了。如果连Arduino都没写过,也不用怕,网上有大量官方示例和库,照抄后改几行参数就能跑。
不过有一点要提醒:ESP32本身支持2.4G WiFi,传输距离一般只有几十米,而且穿墙能力一般。所以它更适合室内短距离使用。如果你想要更远的控制距离,就需要换用外置天线或者加长天线,我在后面扩展部分会说到。
2. 硬件清单和组装:先把结构搭稳,再考虑功能
2.1 核心部件选择
常见的方案是使用ESP32-CAM模块作为主控和摄像头,搭配一个电机驱动板(比如L298N或TB6612)、两个直流减速电机、一个电源模块和一些结构件。
表格里列出我推荐的核心清单:
| 部件 | 作用 | 备注 |
|---|---|---|
| ESP32-CAM | 主控 + WiFi + 摄像头 | 带OV2640摄像头,性能足够 |
| 电机驱动板 | 控制两个电机正反转 | L298N便宜,TB6612更省电 |
| 直流减速电机(2个) | 驱动轮子 | 建议选带编码器的,方便调速 |
| 电源模块 | 给主控和电机供电 | 用3.7V锂电池或5V USB电源 |
| 电池盒/移动电源 | 供电 | 注意电流需求 |
| 底盘和轮子 | 机械支撑 | 可以买小车底盘套件 |
| 杜邦线若干 | 连接电路 | 尽量用母对母杜邦线 |
如果你手头没有小车底盘,也可以先拿木板、纸板临时搭一个。重点是先把电路和代码跑通,再考虑外观。
2.2 连接方式和关键约束
ESP32-CAM的引脚比较紧凑,一般把电机驱动板的PWM引脚接到ESP32的某些GPIO口,数字方向引脚接另外几个GPIO。我给你的连接建议如下:
- 电机A的IN1和IN2分别接一个GPIO,电机B的IN3和IN4接另外两个GPIO。
- 驱动板的ENA和ENB接PWM引脚,用来控制转速。
- 电源地线必须共地,否则信号会不稳定,这是新手最容易踩的坑。
具体哪个GPIO对应哪个引脚,每个板子可能不一样,所以一定要先查你的板子原理图。我一般在写代码前,会用万用表量一遍引脚电压,确保没有接错。
2.3 供电和功耗的坑
摄像头和电机是耗电大户。如果用一个电源同时给ESP32和电机供电,电机的启动电流会造成电压跌落,轻则画面闪烁,重则ESP32直接重启。
我的做法是:用两路电源。一路专给ESP32-CAM供电,保证稳定;另一路给电机驱动板和电机供电。如果你坚持用单电源,至少要在电机驱动板旁边加一个大容量电容,比如470uF,用来吸收启动瞬间的电流波动。
另外,ESP32-CAM有两个版本,带Flash和不带Flash的。带Flash的能存视频流,建议优先选带Flash和PSRAM的版本,不然在高分辨率下容易内存不足。
3. 软件环境与第一段视频流:把摄像头画面拉到手机上
3.1 开发工具准备
我推荐用Arduino IDE来开发,因为ESP32的官方板级支持包和摄像头示例代码都做得比较完善。安装过程很简单:
- 打开Arduino IDE,进入“文件->首选项”,在“附加开发板管理器网址”里填入ESP32的json下载地址。
- 在“工具->开发板->开发板管理器”里搜索ESP32,安装对应的板级支持包。
- 选择你的具体板子,比如“AI Thinker ESP32-CAM”。
这里有个容易出错的地方:安装板级支持包时,如果网络不稳定,可能会下载失败。遇到失败不要急,换个镜像源或者多试几次。安装完成后,在“示例->ESP32->Camera”里就能找到摄像头例程。
另外要注意,ESP32-CAM没有板载USB转串口,你需要外接一个USB转TTL模块来烧录程序。烧录时将模块的TX接ESP32的RX,RX接TX,还要把IO0引脚接地进入下载模式。
3.2 跑通官方摄像头Web服务器示例
打开例程“CameraWebServer”,你需要改两个地方:WiFi名称和密码。其他参数先保持默认。改完上传后,打开Arduino IDE的串口监视器,设置波特率115200,就能看到ESP32分配到的IP地址。把那个IP地址输入手机或电脑浏览器,就能看到摄像头画面和网页控制界面。
第一次跑通这个例程,你就算完成了一大半。这个示例本身就支持视频流和控制摄像头的方向,但还不支持控制电机。我们后面再加。
3.3 理解视频流地址和分辨率参数
如果浏览器能打开画面,你会发现页面里有很多参数,比如分辨率、帧率、质量。这些参数直接影响视频流畅度。我给你的建议是:
- 不要一上来就开最高分辨率,先选320x240或640x480。
- 帧率设置到15fps左右,既能看又能动的体验最舒服。
- 画质(JPEG质量)设置在80左右,太高质量数据量大,容易卡。
视频流默认地址是http://IP:81/stream,我一般还会用http://IP:80/打开控制页面。要注意的是,每刷新一次页面,都会占用一个TCP连接。同一个浏览器开多个标签页,会很快耗尽资源,导致视频卡死。
4. 运动控制:用WiFi命令驱动电机,让小车前后左右移动
4.1 电机驱动原理
电机驱动板本质上是一个H桥电路,通过控制四个开关的通断,让电机正转、反转或停止。一般用两个GPIO控制方向,用一个PWM引脚控制速度。
以TB6612为例,它有AIN1和AIN2,AN1为高、AN2为低时电机正转;反过来为反转。ENA引脚接PWM,给一个0到255的值来控制速度。两个电机分别处理,就能实现差速转向:左轮和右轮速度不同,小车就会转弯。
代码里最核心的就是定义这些引脚的输出模式,然后根据接收到的指令设置电平。我在代码里习惯封装一个motorControl()函数,接收方向参数,这样后续扩展很灵活。
4.2 设计控制指令
为了让控制指令简单稳定,我推荐用HTTP GET请求。比如用http://IP/control?cmd=forward这个地址,服务器收到后就调用前进函数。
为什么用GET而不直接用串口或TCP?因为浏览器里直接输入URL就能触发,测试方便,手机浏览器也支持。缺点是没有加密和身份验证,只适合局域网学习用途。如果你要做广域网控制,那就要加登录和权限管理,这个后面再谈。
指令设计如下:
| 指令 | 含义 |
|---|---|
forward | 前进 |
backward | 后退 |
left | 左转 |
right | 右转 |
stop | 停止 |
我还会加一个speed=150参数,用来动态调整速度,这样在转弯时能更加平滑。
4.3 代码整合:视频流加电机控制
把摄像头例程和电机控制代码整合到一个项目里,核心是修改CamerWebServer示例的setup()函数,添加引脚初始化和Web Server的URL路由。
下面是我写的一个简化版示例,只保留了关键逻辑,你可以根据自己的硬件调整引脚号:
#include "esp_camera.h" #include <WiFi.h> #include <WebServer.h> // WiFi配置(改成你自己的) const char* ssid = "你的WiFi"; const char* password = "你的密码"; // 定义电机引脚 #define AIN1 12 #define AIN2 13 #define BIN1 14 #define BIN2 15 #define PWM_A 2 #define PWM_B 4 WebServer server(80); void handleControl() { String cmd = server.arg("cmd"); int speed = server.arg("speed").toInt(); if (cmd == "forward") { /* 前进逻辑 */ } else if (cmd == "backward") { /* 后退逻辑 */ } else if (cmd == "left") { /* 左转逻辑 */ } else if (cmd == "right") { /* 右转逻辑 */ } else if (cmd == "stop") { /* 停止逻辑 */ } server.send(200, "text/plain", "OK"); } void setup() { // 初始化摄像头,使用官方示例的配置 // 初始化电机引脚为输出模式 // 连接到WiFi server.on("/control", handleControl); server.begin(); } void loop() { server.handleClient(); }这段代码里,我故意省略了摄像头初始化的细节,因为那个在你跑官方案例时已经有了。整合时,只要确保server.handleClient()不被摄像头的阻塞操作卡住就行。如果视频流一直占着CPU,HTTP响应会变慢。
5. 联调与排查:从能看画面到能稳定遥控
5.1 完整联调步骤
把小车装好后,按顺序做这几件事:
- 先不上电机,只给ESP32-CAM供电,烧录整合后的程序。
- 用浏览器访问IP地址,确认画面能正常显示。
- 在串口监视器里发送测试指令,确认电机引脚输出正常(可以用万用表看高低电平)。
- 接上电机和驱动板,给电机供电,然后通过网页按钮测试前进、后退、左转、右转。
- 开动小车,在空旷地面测试转弯半径和速度,调整PWM最大值。
每步都成功后再合在一起。我最常犯的错误就是直接全部接好后一顿操作,结果都不知道问题出在摄像头还是电机。
5.2 常见问题与排查顺序
联调时会遇到各种问题,我整理了一个排查清单,按顺序去看:
- 画面黑屏或打不开:先查供电是否稳定,再查摄像头接线和Flash设置是否正确。用串口看有没有输出“Camera init failed”。
- 电机不转:先量驱动板供电电压,再看GPIO有没有初始化成输出模式,最后用串口发送指令确认
handleControl是否触发。 - 画面卡顿或断连:降低分辨率,看WiFi信号强度,检查是不是有多个设备同时访问了视频流。最好只留一个浏览器页面。
- 控制延迟大:优先看代码里有没有
delay()阻塞,尤其是摄像头图像处理时。如果有delay(),把它去掉或改成非阻塞的millis()。 - 小车跑偏:两个电机参数不一致很常见,可以在代码里给慢的电机增加一个PWM补偿值,或者给快的那侧稍微降低速度。
如果你在排查中看到类似“Failed to install platform”的错误,那通常是Arduino板级支持包下载失败,换个网络或多试几次就行。另外,烧录时如果一直报错连接失败,检查一下IO0是否接地,以及模块的供电电流是否足够。
5.3 扩展方向与使用建议
当基础视频和遥控功能稳定后,你可以往几个方向扩展:
- 加一个电池电压检测:用ESP32的ADC引脚读电池分压,在网页上显示电量。
- 加超声波避障模块:碰到障碍物自动停车或绕行。
- 加WebSocket通信:把HTTP轮询改成WebSocket,指令延迟会更低。
- 做一个手机App:用Flutter或React Native封装一个控制页面,体验更接近商业产品。
我自己更推荐先做WebSocket控制和电压检测,因为这两个功能不需要额外硬件,纯软件就能提升实用性。等你把这些都跑通后,再去研究ROS2、Micro-ROS那些更复杂的机器人框架也不迟。
最后留几个我排查时优先看的点:输入格式、电源地线、GPIO复用、WiFi信号强度、代码里的阻塞调用。这五个点覆盖了绝大部分“为什么我的机器人不听话”的问题。踩过几次之后你会发现,很多问题都不是ESP32本身不行,而是你前置环境和硬件连接没有弄干净。
如果你只是想搭一台能跑的迷你WiFi机器人,按我上面的顺序做,一个周末就能完成。如果想把视频传输和遥控做得像商业产品一样稳定,那还需要在Web服务器架构、加密传输和硬件设计上继续下功夫。但先把第一版跑起来,比什么都重要。