ESP32-CAM 该买哪一块?AI-Thinker OV2640 还是 ESP32-S3 OV5640

Cartoon of a small black ESP32-CAM board with a tiny camera stacked on a grey programmer shield with a micro-USB socket, next to a longer black ESP32-S3 camera board with a larger camera and a USB-C cable plugged in

第一个摄像头项目,就买配 OV5640 摄像头的 ESP32-S3 WROOM CAM:一条 USB-C 线就能上传程序,更大、更快的内存和更新的核心,也撑得起更高的帧率和板上图像处理。配 OV2640 的经典 AI-Thinker ESP32-CAM 适合预算更低的项目,前提是它附带烧录底板,或者你手上已经有 USB 转串口模块。

本文只讲到下单为止:板子到手后,ESP32-CAM 第一条视频流教程会带你从拆箱一路做到实时画面。如果你的项目根本用不到摄像头,请看 ESP32 该买哪一款。

经典 ESP32-CAM 和 ESP32-S3 WROOM CAM 差在哪里?

经典 ESP32-CAM 和 ESP32-S3 WROOM CAM 用的是同一套摄像头驱动、同一个视频流示例。差别在于怎么烧录程序、摄像头背后的内存,以及盒子里附带的传感器。

经典 AI-Thinker ESP32-CAM ESP32-S3 WROOM CAM
芯片 ESP32,双核 Xtensa LX6,240 MHz ESP32-S3,双核 Xtensa LX7,240 MHz,带 128 位 SIMD 指令
内部 SRAM 520 KB 512 KB
PSRAM 可用 4 MB,四线(Quad)总线 8 MB,八线(Octal)总线
Flash 4 MB 16 MB
附带的摄像头 OV2640,200 万像素,出厂已装好 OV5640,500 万像素,单独包装
最大画面 1600 × 1200 传感器 2592 × 1944;经 esp32-camera 驱动为 2560 × 1920
传感器内置硬件 JPEG 有 有
摄像头板上的 USB 没有;micro-USB 在 ESP32-CAM-MB 烧录底板上,我们这款出货就附带底板 两个 USB-C(原生 USB + UART 桥接)
供电输入 5 V,经底板的 micro-USB 或 5V 引脚 5 V,经 USB-C 或 5V 引脚
排针 16 针;摄像头和 microSD 卡槽一用上,剩下能用的 GPIO 就不多了 两条长排,附排针需自行焊接

两款 ESP32-CAM 的盒子里各有什么?要配哪条线?

Parts list

ItemPriceQty
CH340G USB to TTL UART Serial Converter Download Cable for Arduino Programming ESP8266 NodeMCU Development BoardCH340G USB to TTL UART Serial Converter Download Cable for Arduino Programming ESP8266 NodeMCU Development BoardCH340USRM9.90
Data Cable Type-A Type-C MicroUSB Type-B 0.5m 1m 30cm 0.3m 100cm Data Transfer Upload Code - TYPE-A TO TYPE-C CABLE (0.5M)Data Cable Type-A Type-C MicroUSB Type-B 0.5m 1m 30cm 0.3m 100cm Data Transfer Upload Code - TYPE-A TO TYPE-C CABLE (0.5M)ATCC050RM4.90缺货
Data Cable Type-A Type-C MicroUSB Type-B 0.5m 1m 30cm 0.3m 100cm Data Transfer Upload Code - MicroUSB CABLE (0.5M)Data Cable Type-A Type-C MicroUSB Type-B 0.5m 1m 30cm 0.3m 100cm Data Transfer Upload Code - MicroUSB CABLE (0.5M)ATMC050RM4.90缺货

只买你那条路线用得上的。CH340 线是给你手上已有、但没有底板的裸 AI-Thinker 板用的:它通过五条连接烧录,上传期间要把 GPIO0 接到 GND(MB 底板用它的 IO0 按钮完成这一步)。S3 板配 USB-C 数据线,MB 底板配 micro-USB 数据线;同一页面也有 1.0 m 的长度可选。一定要是数据线:只能充电的线能让板子通电,却永远不会出现 COM 口。

ESP32-S3 WROOM CAM 是一块长条形的黑色板子,模块上标着 N16R8:16 MB Flash、8 MB PSRAM。它以套件形式出货,OV5640 接在一条橙色排线上,另附一条排针;只有要插面包板或额外接线时才需要焊上,摄像头和 USB-C 不焊也能用。经典的配 OV2640 的 ESP32-CAM 到手是上下两块板叠在一起:黑色的摄像头板插在 ESP32-CAM-MB 烧录底板上,底板带 micro-USB 插座,以及 IO0 和 RST 两个按钮。

为什么第一次买 ESP32-CAM,常常卡在上传程序这一步?

经典 AI-Thinker ESP32-CAM 板上没有 USB 插座,也没有 USB 转串口芯片。ESP32 通过 UART0 接收新固件,这是一条 3.3 V 的串口线,引脚标着 U0T 和 U0R,没有哪台笔记本电脑能直接插上去,所以中间必须有东西把 USB 转成串口。芯片还得被告知要接收固件:复位时它会读取 GPIO0,低电平表示等待新固件,高电平表示运行 Flash 里的程序。裸板的 GPIO0 是被拉高的,所以它只会一直启动旧程序。

因此,在别处买来的裸板,要先加一个 USB 转串口模块才能烧录,比如我们的 CH340 下载线,接法如下:

转接线 ESP32-CAM 引脚 说明
5 V(红) 5V 绝对不要接 3.3V 引脚:5 V 接到那里会绕过稳压器,直接打进 3.3 V 的芯片
GND(黑) GND
TX(绿) U0R(GPIO3) 转接线的发送端接板子的接收端
RX(白) U0T(GPIO1) 如果上传一直连不上,就对调 TX 和 RX;这样做不会弄坏任何东西
母对母杜邦线 GPIO0 接到一个空着的 GND 引脚 先接上,再按 RST(在板子背面),让芯片读到 GPIO0 为低电平,然后上传;完成后拔掉跳线,再按一次 RST 运行程序

跳线如果一直插着,每次复位都会回到下载模式,而且 GPIO0 同时也是摄像头的时钟线。ESP32 是 3.3 V 芯片,所以先量一下:线插在笔记本电脑上、但还没接到板子时,量 TX 线对黑线的电压。UART 线空闲时保持高电平,所以这个读数就是它的逻辑电平。如果接近 5 V,就要分压:TX 到 U0R 之间串一颗 1 kΩ 电阻,U0R 到 GND 接一颗 2 kΩ 电阻,留下 5 V 的三分之二,大约 3.3 V。

我们的 OV2640 ESP32-CAM 出货时已经插在 ESP32-CAM-MB 烧录底板上,底板补上的正是裸板缺少的东西:micro-USB 插座后面的 CH340 USB 转串口芯片,以及用来进入下载模式的 IO0 和 RST 按钮。接一条 micro-USB 数据线,上传起来就跟 DevKit 差不多。如果上传卡在「Connecting…」,按住 IO0、点一下 RST、放开 IO0,再上传一次;之后程序没有运行的话,就点一下 RST。ESP32-S3 不需要转接模块、底板或跳线:它的内置 USB Serial/JTAG 控制器直接和电脑通信,并且会自己让芯片进入下载模式。如果电脑上没有出现端口,先怀疑数据线;接着才是 MB 底板的 CH340 驱动,或者换 S3 上的另一个 USB-C 口(ESP32 无法识别)。

三格卡通图:一块没有 USB 插座的黑色裸 ESP32-CAM 板,旁边的数据线被打叉;同一块板插在灰色烧录底板上,接上 micro-USB 线并打勾;一块长条形黑色 ESP32-S3 摄像头板,接上 USB-C 线并打勾
同一件事的三种情况:裸的经典 ESP32-CAM 根本没有 USB 插座;同一块板插上烧录底板后,就能接 micro-USB 线;ESP32-S3 板则直接接 USB-C 线。

OV5640 的 500 万像素,在手机上真的更清楚吗?

OV5640 多出来的像素,只有在放大或打印时才看得出来。OV2640 的最大画面是 1600 × 1200,共 192 万像素;OV5640 是 2592 × 1944,共 504 万像素。一般手机屏幕横向约 1080 像素,所以铺满屏幕宽度时,1600 像素的画面已经缩小了三分之一,2592 像素的画面更是缩小了五分之三:两者看起来一样。放大两倍,屏幕只显示画面一半的宽度。OV2640 的是 800 像素被拉宽到 1080,看起来发糊;OV5640 的是 1296 像素,仍然比屏幕需要的多。这就是 500 万像素真正换来的:从一张静态照片里看清仪表读数,或者读出车牌。

实时视频很少以任一款的最大分辨率运行:JPEG 的大小大致随像素数增长,所以 2592 × 1944 的数据量约是 640 × 480 的十六倍,而 Wi-Fi 必须把每一帧都送出去。流畅的视频流,在两块板上都是跑 VGA 或 SVGA。

卡通图:两部手机显示同一张盆栽和时钟的画面,下方是放大视图:左边较小的 OV2640 摄像头拍出方块状的像素,右边较大的 OV5640 摄像头拍出清晰的时钟
在手机屏幕上,200 万像素和 500 万像素的画面看起来一样;只有放大某个细节时,差别才会出现。

ESP32-S3 多出来的 PSRAM 和 LX7 核心,能带来什么?

ESP32-S3 WROOM CAM 真正胜出的,是摄像头后面负责运算的那一部分。处理图像需要原始像素,例如每个像素 2 字节的 RGB565,这时一帧 640 × 480 的画面就是 640 × 480 × 2 = 614,400 字节:比两颗芯片各自 512–520 KB 的 SRAM 还多,何况 SRAM 还要放 Wi-Fi 和你的程序。所以除了小尺寸的 JPEG 画面,esp32-camera 驱动都会把画面放进 PSRAM,也就是模块里额外的一颗 RAM 芯片。

一帧 1600 × 1200 的原始画面就有 3.84 MB,几乎占满经典板的 4 MB,再也放不下第二份副本或检测模型的工作内存;在 S3 的 8 MB 上,同一帧画面还能剩下一半以上。速度则来自总线和核心。每一帧放进 PSRAM 的画面,都要由摄像头写入一次,再至少读回一次才能发送或处理,所以 PSRAM 的速度决定了芯片每秒能搬运、处理多少帧,而原始画面比 JPEG 画面重得多:一帧 VGA JPEG 只有几十 KB,同一帧换成 RGB565 却有 614,400 字节。S3 的 PSRAM 用八条数据线而不是四条,每个时钟周期搬运的位数多一倍。两颗芯片都跑 240 MHz,但 S3 的 SIMD 指令一条指令就能处理 16 字节,经典 ESP32 的 LX6 核心却只能一个字节一个字节地处理;而颜色追踪和人脸检测,正是对每一帧的每一个像素重复这些运算。所以乐鑫(Espressif)的 ESP-DL 视觉库以 S3 为目标,在经典 ESP32 上则退回到慢得多的纯 C 实现。

OV2640 还是 RHYX-M21-45:ESP32-CAM 选哪种摄像头版本?

我们的经典 ESP32-CAM 还有一个 RHYX-M21-45 版本,它的摄像头用的是格科微(GalaxyCore)GC2145 传感器,没有 JPEG 编码器。CameraWebServer 传送的是 MJPEG,也就是一连串快速送出的 JPEG 图片。OV2640 在传感器内部就把每一帧压缩好,ESP32 只需转发现成的图片;换成 GC2145,默认程序要求 JPEG,摄像头就会启动失败,直到你把它改成小尺寸画面的 RGB565 为止。

改好之后,CameraWebServer 确实能再次推流,但只能靠 ESP32 用软件压缩每一帧,帧率会因此下降。RHYX 版本真正的用途,是本来就需要原始 RGB565 的板上处理,比如颜色追踪或循线;如果要推流到手机,请选 OV2640。

怎么确认收到的是哪颗芯片、多大 PSRAM、哪种摄像头?

先装好 ESP32-S3 板的 OV5640(排线步骤在后面),再让这段程序去问硬件:它会打印芯片型号、PSRAM 容量和传感器 ID,然后拍一帧测试画面。经典板在 Tools → Board 里选 AI Thinker ESP32-CAM;S3 板选 ESP32S3 Dev Module,PSRAM 和 USB 设置照第一条视频流教程来设。

// ESP32-CAM 到货检查:哪颗芯片、多少 PSRAM、哪种摄像头传感器
// 适用于经典 AI-Thinker ESP32-CAM 和 ESP32-S3 WROOM CAM
#include "esp_camera.h"

#if defined(CONFIG_IDF_TARGET_ESP32S3)
// ESP32-S3 WROOM CAM(引脚分配与 CAMERA_MODEL_ESP32S3_EYE 相同)
#define PWDN_PIN  -1
#define RESET_PIN -1
#define XCLK_PIN  15
#define SIOD_PIN   4
#define SIOC_PIN   5
#define Y9_PIN    16
#define Y8_PIN    17
#define Y7_PIN    18
#define Y6_PIN    12
#define Y5_PIN    10
#define Y4_PIN     8
#define Y3_PIN     9
#define Y2_PIN    11
#define VSYNC_PIN  6
#define HREF_PIN   7
#define PCLK_PIN  13
#else
// 经典 AI-Thinker ESP32-CAM(引脚分配与 CAMERA_MODEL_AI_THINKER 相同)
#define PWDN_PIN  32
#define RESET_PIN -1
#define XCLK_PIN   0   // GPIO0 同时也是启动模式引脚
#define SIOD_PIN  26
#define SIOC_PIN  27
#define Y9_PIN    35
#define Y8_PIN    34
#define Y7_PIN    39
#define Y6_PIN    36
#define Y5_PIN    21
#define Y4_PIN    19
#define Y3_PIN    18
#define Y2_PIN     5
#define VSYNC_PIN 25
#define HREF_PIN  23
#define PCLK_PIN  22
#endif

void setup() {
  Serial.begin(115200);
  delay(1500);

  Serial.printf("Chip: %s, %d cores\n", ESP.getChipModel(), ESP.getChipCores());
  Serial.printf("PSRAM: %lu bytes\n", (unsigned long)ESP.getPsramSize());

  camera_config_t config = {};
  config.pin_pwdn = PWDN_PIN;
  config.pin_reset = RESET_PIN;
  config.pin_xclk = XCLK_PIN;
  config.pin_sccb_sda = SIOD_PIN;
  config.pin_sccb_scl = SIOC_PIN;
  config.pin_d7 = Y9_PIN;
  config.pin_d6 = Y8_PIN;
  config.pin_d5 = Y7_PIN;
  config.pin_d4 = Y6_PIN;
  config.pin_d3 = Y5_PIN;
  config.pin_d2 = Y4_PIN;
  config.pin_d1 = Y3_PIN;
  config.pin_d0 = Y2_PIN;
  config.pin_vsync = VSYNC_PIN;
  config.pin_href = HREF_PIN;
  config.pin_pclk = PCLK_PIN;
  config.xclk_freq_hz = 20000000;
  config.ledc_timer = LEDC_TIMER_0;
  config.ledc_channel = LEDC_CHANNEL_0;
  // 320x240 的 RGB565:这里每一款传感器都支持,不管有没有 JPEG
  config.pixel_format = PIXFORMAT_RGB565;
  config.frame_size = FRAMESIZE_QVGA;
  config.fb_count = 1;
  config.grab_mode = CAMERA_GRAB_LATEST;
  config.fb_location = psramFound() ? CAMERA_FB_IN_PSRAM : CAMERA_FB_IN_DRAM;

  esp_err_t err = esp_camera_init(&config);
  if (err != ESP_OK) {
    Serial.printf("Camera init failed: 0x%x. Power off, re-seat the ribbon, check the 5 V supply.\n", (unsigned)err);
    return;
  }

  sensor_t *s = esp_camera_sensor_get();
  camera_sensor_info_t *info = esp_camera_sensor_get_info(&s->id);
  if (info) {
    Serial.printf("Sensor: %s (PID 0x%04x)\n", info->name, (unsigned)s->id.PID);
    Serial.printf("Largest frame: %u x %u, hardware JPEG: %s\n",
                  (unsigned)resolution[info->max_size].width,
                  (unsigned)resolution[info->max_size].height,
                  info->support_jpeg ? "yes" : "NO");
  } else {
    Serial.printf("Unknown sensor, PID 0x%04x\n", (unsigned)s->id.PID);
  }

  camera_fb_t *fb = esp_camera_fb_get();
  if (fb) {
    // RGB565:320 x 240 像素 x 2 字节 = 153600 字节
    Serial.printf("Test frame: %u x %u, %u bytes\n", (unsigned)fb->width, (unsigned)fb->height, (unsigned)fb->len);
    esp_camera_fb_return(fb);
  } else {
    Serial.println("No frame captured: re-seat the ribbon and try again.");
  }
}

void loop() {
}

这项检查只在启动时打印一次,所以先把串口监视器设为 115200 波特率打开,再按 RST 重新运行。经典板会显示约 4 MB 的 PSRAM,以及 JPEG 为「yes」的 OV2640;S3 板显示约 8 MB 和 OV5640,它的最大画面会打印成 2560 × 1920,这是驱动最大的预设尺寸,刚好落在传感器的 2592 × 1944 之内;GC2145 则会打印 JPEG「NO」。在 S3 上看到「PSRAM: 0 bytes」,表示 Tools → PSRAM 没有设成 OPI PSRAM,并不是芯片缺了 PSRAM。测试画面应该是 153,600 字节:320 × 240 × 2,跟前面 RGB565 的算法一样。出现「Camera init failed」,第一个要查的就是排线。

OV7670 摄像头模块能代替 ESP32-CAM 的摄像头吗?

不能。在摄像头搜索结果里常常冒出来的 OV7670 模块,是一颗装在蓝色板子上的裸 VGA 传感器,带 18 针双排公排针。两款 ESP32 摄像头板都是通过 24 针扁平排线(FPC)插座连接摄像头,所以它插不上去,用杜邦线也绕不过去:在经典板上,摄像头的数据线和同步线是从插座直接连到 ESP32 的,根本没有引到排针上。就算用一大把杜邦线把 OV7670 接到普通 ESP32 板上,它也没有 JPEG 编码器,最高只有 640 × 480,ESP32 得先用软件把每一帧压缩好才能推流。

OV7670 真正适合的,是在 Uno 这类板子上学习并行摄像头接口的原理:Uno 只有 2 KB RAM,装不下 614,400 字节的 VGA 画面,所以像素只能经串口一行一行慢慢送出去。它的引脚是 3.3 V,所以 Uno 的 5 V 输出要先经过电阻分压或电平转换模块,才能接到它身上。

ESP32-CAM 的排线怎么插才不会弄坏?

S3 套件的 OV5640 是单独包装的,所以第一天就要打开连接器;经典板的 OV2640 出厂已经装好,但每次重新插拔,规则都一样。FPC 连接器靠它的翻盖锁扣压紧接触:合上时,锁扣把排线的 24 根金手指压在插座的弹片触点上;打开时,排线只是搁在槽里。锁扣只合上一半,或者排线没有插到底,有些线路就会接不通,驱动找不到传感器,日志就会报「Camera init failed」。

  1. 先拔掉 USB 线:排线在带电的触点上滑过,可能把相邻的引脚短接,电源引脚也不例外。
  2. 用指甲勾住深色锁扣的边缘,把它掀到大约竖直的位置。它是铰链结构,拆不下来;再用力往后掰,铰链就会断。
  3. 往槽里看:金属触点在其中一侧。让金手指朝着触点,把排线笔直插进去,直到金手指几乎完全没入槽里。
  4. 扶正排线,把锁扣压平。

把摄像头折到位置时,要弯成柔和的弧度,绝对不要折出折痕:铜走线在急弯处会裂开,而走线裂了之后,外表可能看起来完好无损,其中一条信号却已经断了。

三步卡通图:黑色板子上的白色排线连接器,先是锁扣掀起、槽里是空的,接着一条橙色摄像头排线笔直插入,最后锁扣压平,旁边一个绿色勾号
压紧排线的是锁扣:掀起锁扣,把排线笔直插到底,再把锁扣压平,全程都要在断电状态下操作。

ESP32-CAM 需要多少电压?

两款 ESP32 摄像头板都用 5 V 供电,经 USB 插座或 5V 引脚输入,再由板上的稳压器产生芯片用的 3.3 V。经典板还有一个 3.3V 引脚,但它绕过了这颗稳压器,所以接到这里的电源,必须靠自己在每一次电流尖峰中都稳住 3.3 V。

电源够不够力,摄像头启动时最容易露馅。传感器上电时,多数程序也正好在启动 Wi-Fi,而 Wi-Fi 发射时的突发电流有几百毫安。细线的电阻会把每一次电流突发变成电压降,老化的 USB 口还会再往下掉;一旦压降传到芯片,欠压检测器(brownout detector)就会让板子复位,复位又重新启动摄像头,电压再掉一次:于是形成重启循环,日志里出现「Brownout detector was triggered」。请用短的数据线,直接插电脑的 USB 口,或者用一个靠谱的 5 V 适配器;ESP32 供电方案讲了电池供电和完整的解决办法。

到底该买哪一款 ESP32-CAM?

第一个摄像头项目、手边没有 USB 转串口模块,或者截止日期快到了:选 ESP32-S3 WROOM CAM。要做板上处理,它也是更好的选择。

已经有转接模块,或者想走最省钱的路线:配 OV2640 的经典 AI-Thinker 板依然没问题。我们这款附带烧录底板,所以转接模块可有可无。

我们常见的错误

买了裸的 ESP32-CAM,以为上面有 USB 口。数据线没地方插,项目只能停下来等转接模块。下单前确认商品写明附烧录底板或 MB,或者直接买 S3。

因为在「摄像头模块」的搜索结果里看到,就买了 OV7670。它是另一类零件:用排针而不是排线,也没有 JPEG。

板子一到摄像头启动就复位,却一直在改代码。这是电源问题;先把数据线和电源搞定。

常见问题

哪一款 ESP32-CAM 板最适合新手?

ESP32-S3 WROOM CAM:一条 USB-C 线就行,不需要转接模块或启动跳线,8 MB PSRAM 还能应付更大的画面和板上处理。

没有烧录器,可以给 ESP32-CAM 烧录程序吗?

经典 AI-Thinker 板不行,它没有 USB。请用 ESP32-CAM-MB 底板(我们这款就附带),或者用 USB 转串口模块,再加一条把 GPIO0 接到 GND 的跳线。S3 有原生 USB。

OV2640 和 OV5640 有什么区别?

1600 × 1200(200 万像素)对 2592 × 1944(500 万像素),两者都有硬件 JPEG。在手机上看起来一样,放大之后才看得出差别。

ESP32-CAM 的工作电压是多少?

5 V 接到 USB 插座或 5V 引脚;稳压器会产生 3.3 V。

OV7670 可以用在 ESP32-CAM 上吗?

不可以:它用的是排针,不是 24 针排线,也没有 JPEG 编码器。

最后更新:2026年10月。有问题?WhatsApp 联系我们。

Leave a Reply

Your email address will not be published. Required fields are marked *