回到首页 返回首页
回到顶部 回到顶部
返回上一页 返回上一页

【花雕学编程】Arduino动手做(230)---使用ESP32摄像头模块捕获图像并将其保存到SD卡上 简单

头像 驴友花雕 2024.09.07 20 0

01.jpg

ESP32-Cam 是一款运行在 ESP32-S 芯片上并使用 OV2640 摄像头的小型摄像头模块。ESP32_Cam 也可以 OV7670 摄像头,但 OV2640 更好(更高的分辨率和内置的 JPEG 编码,这消除了 ESP32-S 的处理任务)。
ESP-32 Cam 规格ESP-32 系列
它支持 Wi-Fi (802.11b/g/n)
支持蓝牙 (4.2 带 BLE)
内置 LED 闪光灯
9 个 IO 端口
支持 UART、SPI、I2C 和 PWM
内置 micro SD 读卡器
输入电源:3.3V / 5V(据报道,5V 供电比 3.3V 更稳定)
OV2640 摄像头
2 百万像素
阵列尺寸:UXGA (1600 x 1200)
镜头尺寸:1/4 英寸(6.35 毫米)
最大图像传输速率:15 帧/秒

 

10.jpg

  【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
 实验二百三十:ESP32 CAM开发板 带OV2640摄像头模块 WIFI+蓝牙模块
 项目实验之六:ESP32-CAM拍照片并存储到SD卡上

实验开源代码
 

代码
/*
  【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
  实验二百三十:ESP32 CAM开发板 带OV2640摄像头模块 WIFI+蓝牙模块
  项目实验之六:ESP32-CAM拍照片并存储到SD卡上
*/

#include "esp_camera.h"  // 引入ESP32摄像头库
#include "FS.h"  // 引入文件系统库
#include "SD_MMC.h"  // 引入SD卡库

// 摄像头引脚配置
camera_config_t config = {
  .pin_pwdn  = 32,  // 电源引脚
  .pin_reset = -1,  // 复位引脚(未使用)
  .pin_xclk = 0,  // XCLK引脚
  .pin_sscb_sda = 26,  // SCCB SDA引脚
  .pin_sscb_scl = 27,  // SCCB SCL引脚
  .pin_d7 = 35,  // 数据引脚D7
  .pin_d6 = 34,  // 数据引脚D6
  .pin_d5 = 39,  // 数据引脚D5
  .pin_d4 = 36,  // 数据引脚D4
  .pin_d3 = 21,  // 数据引脚D3
  .pin_d2 = 19,  // 数据引脚D2
  .pin_d1 = 18,  // 数据引脚D1
  .pin_d0 = 5,   // 数据引脚D0
  .pin_vsync = 25,  // VSYNC引脚
  .pin_href = 23,  // HREF引脚
  .pin_pclk = 22,  // PCLK引脚
  .xclk_freq_hz = 20000000,  // XCLK频率(20MHz)
  .ledc_timer = LEDC_TIMER_0,  // LEDC定时器
  .ledc_channel = LEDC_CHANNEL_0,  // LEDC通道
  .pixel_format = PIXFORMAT_JPEG,  // 像素格式为JPEG
  .frame_size = FRAMESIZE_UXGA,  // 帧大小为UXGA
  .jpeg_quality = 12,  // JPEG质量
  .fb_count = 1  // 帧缓冲区数量
};

void setup() {
  Serial.begin(115200);  // 初始化串口通信,波特率为115200
  Serial.println();

  // 初始化摄像头
  esp_err_t err = esp_camera_init(&config);
  if (err != ESP_OK) {
    Serial.printf("摄像头初始化失败,出现错误 0x%x", err);  // 输出初始化失败的错误信息
    return;
  }
  Serial.println("摄像头初始化成功!");

  // 初始化SD卡
  if (!SD_MMC.begin()) {
    Serial.println("SD卡挂载失败");
    return;
  }
  Serial.println("SD卡已挂载");
}

void loop() {
  // 获取摄像头的帧缓冲区
  camera_fb_t * fb = esp_camera_fb_get();
  if (!fb) {
    Serial.println("摄像头捕捉失败");
    return;
  }

  // 创建文件路径
  String path = "/picture.jpg";
  Serial.printf("保存文件: %s\n", path.c_str());

  // 打开文件
  File file = SD_MMC.open(path, FILE_WRITE);
  if (!file) {
    Serial.println("打开文件失败");
  } else {
    // 写入文件
    file.write(fb->buf, fb->len);  // 写入图像数据
    Serial.println("文件保存成功");
  }
  file.close();

  // 释放帧缓冲区
  esp_camera_fb_return(fb);

  delay(5000);  // 等待5秒再次捕获
}

实验串口返回情况

 

26.jpg

存储在SD卡上的拍摄照片

 

25.jpg

这段代码的主要功能是使用ESP32摄像头模块捕获图像并将其保存到SD卡上。以下是详细说明和解释:

 

1、引入库文件

```cpp
#include "esp_camera.h"  // 引入ESP32摄像头库
#include "FS.h"  // 引入文件系统库
#include "SD_MMC.h"  // 引入SD卡库
```

这些库文件提供了摄像头和SD卡操作所需的函数和定义。

 

2、摄像头引脚配置

```cpp
camera_config_t config = {
 .pin_pwdn  = 32,  // 电源引脚
 .pin_reset = -1,  // 复位引脚(未使用)
 .pin_xclk = 0,  // XCLK引脚
 .pin_sscb_sda = 26,  // SCCB SDA引脚
 .pin_sscb_scl = 27,  // SCCB SCL引脚
 .pin_d7 = 35,  // 数据引脚D7
 .pin_d6 = 34,  // 数据引脚D6
 .pin_d5 = 39,  // 数据引脚D5
 .pin_d4 = 36,  // 数据引脚D4
 .pin_d3 = 21,  // 数据引脚D3
 .pin_d2 = 19,  // 数据引脚D2
 .pin_d1 = 18,  // 数据引脚D1
 .pin_d0 = 5,   // 数据引脚D0
 .pin_vsync = 25,  // VSYNC引脚
 .pin_href = 23,  // HREF引脚
 .pin_pclk = 22,  // PCLK引脚
 .xclk_freq_hz = 20000000,  // XCLK频率(20MHz)
 .ledc_timer = LEDC_TIMER_0,  // LEDC定时器
 .ledc_channel = LEDC_CHANNEL_0,  // LEDC通道
 .pixel_format = PIXFORMAT_JPEG,  // 像素格式为JPEG
 .frame_size = FRAMESIZE_UXGA,  // 帧大小为UXGA
 .jpeg_quality = 12,  // JPEG质量
 .fb_count = 1  // 帧缓冲区数量
};
```

这部分代码配置了摄像头的各个引脚和参数,包括电源引脚、数据引脚、时钟频率、像素格式、帧大小等。

 

3、初始化设置

```cpp
void setup() {
 Serial.begin(115200);  // 初始化串口通信,波特率为115200
 Serial.println();

 // 初始化摄像头
 esp_err_t err = esp_camera_init(&config);
 if (err != ESP_OK) {
   Serial.printf("摄像头初始化失败,出现错误 0x%x", err);  // 输出初始化失败的错误信息
   return;
 }
 Serial.println("摄像头初始化成功!");

 // 初始化SD卡
 if (!SD_MMC.begin()) {
   Serial.println("SD卡挂载失败");
   return;
 }
 Serial.println("SD卡已挂载");
}
```

setup函数在程序开始时运行,初始化串口通信、摄像头和SD卡。如果初始化失败,会输出错误信息。

 

4、主循环

```cpp
void loop() {
 // 获取摄像头的帧缓冲区
 camera_fb_t * fb = esp_camera_fb_get();
 if (!fb) {
   Serial.println("摄像头捕捉失败");
   return;
 }

 // 创建文件路径
 String path = "/picture.jpg";
 Serial.printf("保存文件: %s\n", path.c_str());

 // 打开文件
 File file = SD_MMC.open(path, FILE_WRITE);
 if (!file) {
   Serial.println("打开文件失败");
 } else {
   // 写入文件
   file.write(fb->buf, fb->len);  // 写入图像数据
   Serial.println("文件保存成功");
 }
 file.close();

 // 释放帧缓冲区
 esp_camera_fb_return(fb);

 delay(5000);  // 等待5秒再次捕获
}
```

loop函数是主循环,持续运行。它从摄像头获取图像帧,将其保存到SD卡上的文件中,然后释放帧缓冲区。每次捕获图像后,等待5秒钟再进行下一次捕获。
 

实验场景图

 

19.jpg

评论

user-avatar
icon 他的勋章
    展开更多