跳转到主要内容
杨月昌的硬件博客
返回

ESP32-CAM实战:低成本定时延时摄影系统完整指南(附低功耗Deep Sleep代码)

引言

ESP32-CAM以极低成本(<50元)集成了OV2640摄像头、Wi-Fi和MicroSD卡槽,成为DIY延时摄影(Time-Lapse)、监控和视觉项目的首选。

但实际使用中,SD卡挂载失败、Brownout重启、功耗过高、照片覆盖等问题极易卡住新手。本文一次性给你完整可落地方案:优化硬件电源、现代化代码(Deep Sleep版)、全避坑清单,让你从零到可量产级延时摄影系统。


1. 项目概述与硬件准备

核心目标:每隔固定时间(或Deep Sleep唤醒)自动拍照,照片以pic_0001.jpg递增命名,保存至SD卡。

1.1 物料清单

1.2 烧录模式接线表

ESP32-CAM引脚USB转TTL备注
5V5V推荐5V供电
GNDGND共地
U0R (GPIO3)TXD接收
U0T (GPIO1)RXD发送
GPIO0GND必须短接进入下载模式

烧录完成后务必拔掉GPIO0跳线,否则SD卡无法正常挂载。


2. 软件环境与核心代码实现

推荐开发环境:Arduino IDE 2.x + esp32 by Espressif 3.x 板卡包。

完整优化代码(推荐Deep Sleep低功耗版)

#include "esp_camera.h"
#include "Arduino.h"
#include "FS.h"
#include "SD_MMC.h"
#include "soc/soc.h"
#include "soc/rtc_cntl_reg.h"
#include <Preferences.h>   // 推荐替代EEPROM,更稳定

Preferences prefs;
#define PWDN_GPIO_NUM     32
#define RESET_GPIO_NUM    -1
#define XCLK_GPIO_NUM      0
#define SIOD_GPIO_NUM     26
#define SIOC_GPIO_NUM     27
#define Y9_GPIO_NUM       35
#define Y8_GPIO_NUM       34
#define Y7_GPIO_NUM       39
#define Y6_GPIO_NUM       36
#define Y5_GPIO_NUM       21
#define Y4_GPIO_NUM       19
#define Y3_GPIO_NUM       18
#define Y2_GPIO_NUM        5
#define VSYNC_GPIO_NUM    25
#define HREF_GPIO_NUM     23
#define PCLK_GPIO_NUM     22

void setup() {
  WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0);  // 关闭Brownout检测
  Serial.begin(115200);

  // 摄像头配置
  camera_config_t config;
  config.ledc_channel = LEDC_CHANNEL_0;
  config.ledc_timer = LEDC_TIMER_0;
  config.pin_d0 = Y2_GPIO_NUM;
  // ...(其余引脚定义同上,省略以节省篇幅)
  config.xclk_freq_hz = 20000000;
  config.pixel_format = PIXFORMAT_JPEG;

  if (psramFound()) {
    config.frame_size = FRAMESIZE_UXGA;   // 1600x1200
    config.jpeg_quality = 10;
    config.fb_count = 2;
  } else {
    config.frame_size = FRAMESIZE_SVGA;
    config.jpeg_quality = 12;
    config.fb_count = 1;
  }

  esp_err_t err = esp_camera_init(&config);
  if (err != ESP_OK) {
    Serial.printf("Camera init failed 0x%x\n", err);
    return;
  }

  // SD卡初始化(1-bit模式节省功耗和引脚)
  if (!SD_MMC.begin("/sdcard", true)) {
    Serial.println("SD Card Mount Failed");
    return;
  }

  takePicture();  // 首次拍照
  goToDeepSleep(); // 进入低功耗睡眠
}

void takePicture() {
  camera_fb_t * fb = esp_camera_fb_get();
  if (!fb) {
    Serial.println("Camera capture failed");
    return;
  }

  prefs.begin("photo", false);
  int pictureNumber = prefs.getInt("picNum", 0) + 1;
  prefs.putInt("picNum", pictureNumber);
  prefs.end();

  String path = "/pic_" + String(pictureNumber) + ".jpg";
  File file = SD_MMC.open(path.c_str(), FILE_WRITE);
  if (file) {
    file.write(fb->buf, fb->len);
    Serial.printf("Picture saved: %s (%d bytes)\n", path.c_str(), fb->len);
    file.close();
  }
  esp_camera_fb_return(fb);
}

void goToDeepSleep() {
  Serial.println("Going to deep sleep for 10 seconds...");
  esp_sleep_enable_timer_wakeup(10 * 1000000ULL);  // 10秒唤醒
  esp_deep_sleep_start();
}

void loop() {}  // Deep Sleep模式下loop不会执行

3. 电源与硬件优化建议


4. 项目CheckList(上手必查)

  1. SD卡已格式化为FAT32 + MBR?
  2. GPIO0跳线在烧录后已拔掉?
  3. 电源端并联了大电容?
  4. 代码中psramFound()判断是否正确?
  5. Deep Sleep唤醒时间是否已按需求调整?
  6. 照片编号是否使用Preferences持久化?

5. 常见避坑指南


6. 后续进阶方向

  1. NTP时间戳命名:照片带日期时间(pic_20260224_143022.jpg)。
  2. Wi-Fi实时预览:集成CameraWebServer异步服务器。
  3. PIR/光敏触发:GPIO13接人体红外,仅在需要时唤醒拍照。
  4. OTA升级:方便野外远程更新固件。
  5. 升级ESP32-S3-CAM:更高分辨率 + 更大PSRAM(2026推荐)。

7. 总结

ESP32-CAM是性价比最高的摄像头方案之一。掌握电源大电容 + Deep Sleep + Preferences持久化三大核心,就能轻松做出稳定可靠的延时摄影系统。

“先加电容保稳定,再用Deep Sleep省电量,最后用Preferences保数据”是这个项目成功的铁律。

多实测、多留余量,你就能从玩具级快速升级到可商用级产品。



上一篇
C# 进阶指南:构建稳健的 Windows HID 通信框架(生产级)
下一篇
进阶实战:ESP32-CAM 开启 SD 卡 1位模式,释放关键 GPIO 资源