当前位置: 首页 > news >正文

ESP32-S3入门第九天:摄像头入门与应用

ESP32-S3 入门第九天:摄像头模块使用与图像采集

    • 一、今日目标
    • 二、摄像头模块选型与硬件基础
      • 1. 兼容的摄像头模块
      • 2. ESP32-S3 摄像头接口特性
    • 三、硬件连接(以 OV2640 为例)
      • 1. 引脚定义与接线图
      • 2. 接线注意事项
    • 四、开发环境配置
      • 1. 安装摄像头库
      • 2. 开发板配置
    • 五、基础实验:摄像头初始化与图像采集
      • 1. 测试摄像头是否正常工作
      • 2. 实验现象
    • 六、进阶实验:Web 服务器实时预览
      • 1. 实验原理
      • 2. 代码实现
      • 3. 实验操作与现象
    • 七、实战项目:图像捕获与 UART 传输
      • 1. 项目功能
      • 2. 硬件新增组件
      • 3. 核心代码片段
      • 4. 上位机接收
    • 八、常见问题与解决方案
    • 九、第九天总结与第十天预告
      • 1. 今日成果
      • 2. 第十天预告:图像识别基础

一、今日目标

  • 了解 ESP32-S3 支持的摄像头模块及硬件特性
  • 掌握摄像头模块的接线方法与驱动配置
  • 实现基础图像采集、本地预览与 WiFi 传输功能
  • 结合往期知识(WiFi/UART)完成图像数据应用

二、摄像头模块选型与硬件基础

1. 兼容的摄像头模块

ESP32-S3 凭借强大的处理能力和专用 DVP 接口,支持多种摄像头模块:

型号分辨率接口优势适合场景
OV2640200 万像素(1600×1200)DVP性价比高、功耗低基础图像采集
OV5640500 万像素(2592×1944)DVP高分辨率细节拍摄
GC030830 万像素(640×480)DVP体积小、帧率高实时监控

推荐新手首选: OV2640
驱动成熟、资料丰富、价格低廉(约 20 元),且对 ESP32-S3 兼容性最佳。

在这里插入图片描述

2. ESP32-S3 摄像头接口特性

  • 专用 DVP(Digital Video Port)图像接口
  • 支持 8/16 位数据宽度
  • 最高支持 500 万像素摄像头
  • 内置 JPEG 编码器,可直接输出压缩图像(节省带宽)
  • 需占用较多 GPIO(10-12 个),需避免与其他外设冲突

三、硬件连接(以 OV2640 为例)

1. 引脚定义与接线图

OV2640 与 ESP32-S3 的 DVP 接口连接(需严格对应):

OV2640 引脚功能ESP32-S3 引脚备注
VCC电源3.3V禁止接 5V,会烧毁模块
GND接地GND必须与开发板共地
SCLI2C 时钟GPIO22用于配置摄像头参数
SDAI2C 数据GPIO21用于配置摄像头参数
XCLK系统时钟GPIO15摄像头工作时钟输入
PCLK像素时钟GPIO12像素数据同步时钟
VSYS场同步GPIO14帧同步信号
HREF行同步GPIO27行同步信号
D0-D78 位数据GPIO35-39, 41-42图像数据总线(共 8 根)
RST复位GPIO13低电平复位(可选接)
PWDN电源使能GPIO16低电平使能(可选接)

2. 接线注意事项

  • 摄像头模块需 3.3V 稳定供电,建议外接电源(若开发板 USB 供电不足)
  • 数据排线尽量短(<10cm),避免信号干扰导致图像花屏
  • 确保 D0-D7 数据线顺序正确,接错会导致图像错乱
  • 先焊接排针再接线,避免引脚接触不良

四、开发环境配置

1. 安装摄像头库

  1. 打开 Arduino IDE,点击「工具」→「管理库」
  2. 搜索「ESP32 Camera」,安装「ESP32 Camera by Espressif Systems」
  3. 安装依赖库「ESP32」(确保版本≥2.0.0)

2. 开发板配置

在「工具」菜单中正确配置:

  • 开发板:ESP32S3 Dev Module
  • Camera Model:OV2640(根据实际模块选择)
  • PSRAM:Enabled(必须启用,用于图像缓存)
  • Flash Size:根据开发板选择(≥4MB)
  • USB Mode:USB-OTG (HID + MSC + CDC)

五、基础实验:摄像头初始化与图像采集

1. 测试摄像头是否正常工作

#include "esp_camera.h"
#include <WiFi.h>// WiFi配置(用于后续图像传输)
const char* ssid = "你的WiFi名称";
const char* password = "你的WiFi密码";// OV2640摄像头引脚配置
#define PWDN_GPIO_NUM 16
#define RESET_GPIO_NUM 13
#define XCLK_GPIO_NUM 15
#define SIOD_GPIO_NUM 21
#define SIOC_GPIO_NUM 22
#define Y9_GPIO_NUM 39
#define Y8_GPIO_NUM 35
#define Y7_GPIO_NUM 34
#define Y6_GPIO_NUM 5
#define Y5_GPIO_NUM 36
#define Y4_GPIO_NUM 37
#define Y3_GPIO_NUM 38
#define Y2_GPIO_NUM 42
#define VSYNC_GPIO_NUM 14
#define HREF_GPIO_NUM 27
#define PCLK_GPIO_NUM 12void setup() {Serial.begin(115200);Serial.setDebugOutput(true);Serial.println();// 摄像头配置结构体camera_config_t config;config.ledc_channel = LEDC_CHANNEL_0;config.ledc_timer = LEDC_TIMER_0;config.pin_d0 = Y2_GPIO_NUM;config.pin_d1 = Y3_GPIO_NUM;config.pin_d2 = Y4_GPIO_NUM;config.pin_d3 = Y5_GPIO_NUM;config.pin_d4 = Y6_GPIO_NUM;config.pin_d5 = Y7_GPIO_NUM;config.pin_d6 = Y8_GPIO_NUM;config.pin_d7 = Y9_GPIO_NUM;config.pin_xclk = XCLK_GPIO_NUM;config.pin_pclk = PCLK_GPIO_NUM;config.pin_vsync = VSYNC_GPIO_NUM;config.pin_href = HREF_GPIO_NUM;config.pin_sscb_sda = SIOD_GPIO_NUM;config.pin_sscb_scl = SIOC_GPIO_NUM;config.pin_pwdn = PWDN_GPIO_NUM;config.pin_reset = RESET_GPIO_NUM;config.xclk_freq_hz = 20000000;  // 20MHz时钟config.pixel_format = PIXFORMAT_JPEG;  // 输出JPEG格式// 根据PSRAM大小配置分辨率if(psramFound()){config.frame_size = FRAMESIZE_VGA;  // 640x480(带PSRAM可支持)config.jpeg_quality = 12;  // 0-63,数字越小质量越高config.fb_count = 2;  // 双缓冲(提高帧率)} else {config.frame_size = FRAMESIZE_QVGA;  // 320x240(无PSRAM)config.jpeg_quality = 12;config.fb_count = 1;}// 初始化摄像头esp_err_t err = esp_camera_init(&config);if (err != ESP_OK) {Serial.printf("摄像头初始化失败:0x%x", err);return;}Serial.println("摄像头初始化成功!");// 连接WiFiWiFi.begin(ssid, password);while (WiFi.status() != WL_CONNECTED) {delay(500);Serial.print(".");}Serial.println("");Serial.println("WiFi连接成功");Serial.println("IP地址: " + WiFi.localIP().toString());
}void loop() {// 获取一帧图像camera_fb_t * fb = esp_camera_fb_get();if (!fb) {Serial.println("获取图像失败");delay(1000);return;}// 打印图像信息Serial.printf("图像尺寸: %zu bytes, 分辨率: %dx%d\n", fb->len, fb->width, fb->height);// 释放图像缓冲区esp_camera_fb_return(fb);delay(2000);  // 每2秒拍摄一次
}

2. 实验现象

  • 若摄像头初始化成功,串口会打印 “摄像头初始化成功!”
  • 成功获取图像后,会显示图像大小和分辨率(如 “图像尺寸: 35648 bytes, 分辨率: 640x480”)
  • 若初始化失败,会输出错误代码(可查阅 ESP32 摄像头库文档排查原因)

六、进阶实验:Web 服务器实时预览

1. 实验原理

通过 ESP32-S3 创建 Web 服务器,将摄像头采集的 JPEG 图像以 MJPEG 流的形式发送到浏览器,实现实时预览(帧率约 5-10fps)。

2. 代码实现

#include "esp_camera.h"
#include <WiFi.h>
#include <WebServer.h>// WiFi配置
const char* ssid = "你的WiFi名称";
const char* password = "你的WiFi密码";// Web服务器(端口80)
WebServer server(80);// 摄像头引脚配置(同前一个实验)
#define PWDN_GPIO_NUM 16
#define RESET_GPIO_NUM 13
#define XCLK_GPIO_NUM 15
#define SIOD_GPIO_NUM 21
#define SIOC_GPIO_NUM 22
#define Y9_GPIO_NUM 39
#define Y8_GPIO_NUM 35
#define Y7_GPIO_NUM 34
#define Y6_GPIO_NUM 5
#define Y5_GPIO_NUM 36
#define Y4_GPIO_NUM 37
#define Y3_GPIO_NUM 38
#define Y2_GPIO_NUM 42
#define VSYNC_GPIO_NUM 14
#define HREF_GPIO_NUM 27
#define PCLK_GPIO_NUM 12// 生成HTML页面(用于浏览器显示)
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE html>
<html>
<head><title>ESP32-S3 Camera</title><style>body { text-align:center; }.cam-container { margin:0 auto; width:640px; }img { width:100%; }</style>
</head>
<body><h1>ESP32-S3 摄像头实时预览</h1><div class="cam-container"><img src="/stream" />  <!-- 显示MJPEG流 --></div>
</body>
</html>
)rawliteral";// 处理MJPEG流请求
void handleStream() {server.sendHeader("Access-Control-Allow-Origin", "*");server.sendHeader("Cache-Control", "no-cache");server.sendHeader("Pragma", "no-cache");server.sendHeader("Connection", "close");server.send(200, "multipart/x-mixed-replace; boundary=frame", "");while (true) {// 获取图像帧camera_fb_t * fb = esp_camera_fb_get();if (!fb) {Serial.println("获取图像失败");return;}// 发送MJPEG帧边界server.sendContent("--frame\r\n");// 发送图像类型和大小server.sendHeader("Content-Type", "image/jpeg");server.sendHeader("Content-Length", String(fb->len));server.sendContent("\r\n");// 发送图像数据server.sendContent((const char*)fb->buf, fb->len);server.sendContent("\r\n");// 释放缓冲区esp_camera_fb_return(fb);// 检查客户端是否断开连接if (!server.client().connected()) {break;}}
}// 初始化摄像头(同前)
void initCamera() {// 摄像头配置代码与基础实验相同camera_config_t config;// ... 省略配置代码 ...esp_err_t err = esp_camera_init(&config);if (err != ESP_OK) {Serial.printf("摄像头初始化失败:0x%x", err);while(1);}
}void setup() {Serial.begin(115200);initCamera();// 连接WiFiWiFi.begin(ssid, password);while (WiFi.status() != WL_CONNECTED) {delay(500);Serial.print(".");}Serial.println("");Serial.println("WiFi连接成功,IP地址: " + WiFi.localIP().toString());// 路由配置server.on("/", [](){server.send_P(200, "text/html", index_html);});server.on("/stream", handleStream);// 启动服务器server.begin();Serial.println("Web服务器已启动");
}void loop() {server.handleClient();  // 处理客户端请求
}

3. 实验操作与现象

  1. 上传代码后,在串口监视器获取 ESP32-S3 的 IP 地址(如 192.168.1.100)
  2. 在电脑或手机浏览器中输入该 IP 地址
  3. 浏览器将显示摄像头实时画面(640×480 分辨率)
  4. 移动摄像头,画面会实时更新(延迟约 0.5-1 秒)

七、实战项目:图像捕获与 UART 传输

1. 项目功能

按下按钮时拍摄一张照片,通过 UART2 将 JPEG 图像数据发送到上位机(如电脑),并在 OLED 屏幕显示拍摄状态。

2. 硬件新增组件

  • 轻触按钮(连接 GPIO04,使用 INPUT_PULLUP 模式)
  • 0.96 寸 OLED 屏幕(复用 I2C 接口,GPIO21/SDA, GPIO22/SCL)

3. 核心代码片段

#include "esp_camera.h"
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>// OLED初始化
Adafruit_SSD1306 oled(128, 64, &Wire, -1);// 按钮引脚
#define BUTTON_PIN 4void setup() {// ... 省略摄像头和WiFi初始化 ...// 初始化OLEDoled.begin(SSD1306_SWITCHCAPVCC, 0x3C);oled.clearDisplay();oled.setTextColor(SSD1306_WHITE);oled.setCursor(0, 0);oled.println("按按钮拍照");oled.display();// 初始化按钮pinMode(BUTTON_PIN, INPUT_PULLUP);
}void loop() {// 检测按钮按下(低电平)if (digitalRead(BUTTON_PIN) == LOW) {delay(50);  // 消抖if (digitalRead(BUTTON_PIN) == LOW) {oled.clearDisplay();oled.setCursor(0, 0);oled.println("正在拍照...");oled.display();// 拍摄照片camera_fb_t * fb = esp_camera_fb_get();if (fb) {oled.setCursor(0, 16);oled.println("拍照成功!");oled.setCursor(0, 32);oled.print("大小: ");oled.print(fb->len/1024);oled.println("KB");oled.display();// 通过UART2发送图像数据Serial2.write(0xFF);  // 帧头Serial2.write(0xD8);Serial2.write(fb->buf, fb->len);  // 图像数据Serial2.write(0xFF);  // 帧尾Serial2.write(0xD9);esp_camera_fb_return(fb);  // 释放缓冲区} else {oled.setCursor(0, 16);oled.println("拍照失败");oled.display();}delay(2000);  // 防止重复触发}}
}

4. 上位机接收

使用串口助手(如 SSCOM)接收图像数据:

  1. 配置波特率 115200,选择 UART2 对应的 COM 口
  2. 开启 “十六进制显示”,观察是否有 FF D8 开头、FF D9 结尾的 JPEG 数据
  3. 将接收的数据保存为 “.jpg” 文件,即可查看拍摄的照片

八、常见问题与解决方案

问题现象可能原因解决方法
摄像头初始化失败(错误代码 0x20004)PSRAM 未启用或故障1. 在开发板配置中开启 PSRAM
2. 检查 PSRAM 焊接是否良好
图像花屏或条纹1. 接线错误
2. 时钟频率过高
1. 重新核对 D0-D7 引脚顺序
2. 将 xclk_freq_hz 降低到 16MHz
无法获取图像(返回 NULL)1. 摄像头未供电
2. 复位引脚配置错误
1. 确认 VCC 接 3.3V 且 GND 连接正确
2. 检查 PWDN 和 RESET 引脚配置
Web 预览卡顿或断开1. WiFi 信号弱
2. 分辨率过高
1. 靠近路由器或降低分辨率
2. 将 frame_size 改为 FRAMESIZE_QVGA
图像偏色白平衡未校准1. 在代码中添加白平衡配置
2. 使用 esp_camera_set_whitebal () 函数

ESP32官方–摄像头应用方案

九、第九天总结与第十天预告

1. 今日成果

  • ✅ 掌握 ESP32-S3 与 OV2640 摄像头的硬件连接方法
  • ✅ 学会配置摄像头参数并实现基础图像采集
  • ✅ 实现 Web 服务器实时预览和 UART 图像传输
  • ✅ 结合按钮、OLED 等外设完成综合应用

2. 第十天预告:图像识别基础

明天将利用 ESP32-S3 的 NPU(神经网络处理单元),实现:

  • 简单的图像识别(如人脸检测、颜色识别)
  • TensorFlow Lite 模型部署
  • 识别结果与硬件联动(如检测到特定物体点亮 LED)
    通过这部分内容,你将初步了解边缘计算在微控制器上的应用,为更复杂的 AIoT 项目打下基础。
http://www.dtcms.com/a/446683.html

相关文章:

  • 泰宁县建设局网站泰达人才网招聘网
  • 桂林网站推广深圳辰硕网站优化
  • 内网 渗透
  • 企业网站的建立与维护论文做电影网站只放链接算侵权吗
  • 给人做logo的网站教育视频网站开发
  • 长春建设银行网站明星网页设计模板图片
  • Linux 进程通信——匿名管道
  • 微服务项目->在线oj系统(Java-Spring)--C端用户管理
  • 网站推广双鼎九九建筑网66kv架空线路设计视频讲座
  • 网站模板分享网站开发招投标书
  • 常州微信网站建设方案全网营销公司有哪些
  • 计算机理论学习Day10
  • 第8章:扩展边界:技术之外的视野(3)
  • 医院做网站开发做网站的主机配置
  • 做的比较好的车载嗨曲网站淘宝联盟怎么建设网站
  • 计算机网络自底向上——物理层笔记整理
  • 南京服务好建设网站哪家好网站开发项目架构说明书
  • 如何建造网站视频教程能用的免费proxy网页
  • 天津网站建设优化企业网站静态页面访问很快php页面访问非常慢
  • (2025年10月最新教程)如何用大陆护照+个人港卡注册Stripe个人账户
  • 红和蓝的企业网站设计宁波网站建设优化服务公司
  • 兴扬汽车网站谁做的three.js做的酷炫网站
  • 做炒作的网站拓者设计吧室内设计论坛
  • 佛山外贸网站建设新闻外贸seo网站推广公司
  • 10.5作业
  • C++进阶(8)——异常
  • Mybatis 主键配置错误做成查询数据丢失
  • wap自助建站排板网站维护 网站后台建设知识
  • Ubuntu中安装Nuclei教程
  • 关于旅游电子商务网站建设论文浙江联科网站建设