1051浏览
查看: 1051|回复: 0

[ESP8266/ESP32] ESP32 S3 虚拟摄像头播放 SD 卡内容

[复制链接]
前面介绍了使用 ESP32 S3 播放 SPINOR 中的内容,美中不足的是 SPI 容量有限无法播放长视频。这次的作品能够实现读取和发送SD卡中的JPG 图片,从而实现长时间的播放。
实验是基于DFRobotESP32-S3-WROOM-1-N4模组(DFR0896)【参考1】来实现的,需要注意的是:这个模组没有 PSRAM,项目中需要关闭PSRAM。为了读取 SD 卡,需要使用上一次设计的 OV2640 Shield【参考2】,其中的 SD 卡是4线模式。

ESP32 S3 虚拟摄像头播放 SD 卡内容图1

插入SD卡,板子堆叠起来即可工作。接下来着手代码设计。
和之前相比,代码改动较大,主要修改有:

1.     去掉了LVGL模块和OneButton 模块,这样帮助减小代码体积和内存的占用;
2.     添加了SD卡初始化代码:

  1.     // By default, SD card frequency is initialized to SDMMC_FREQ_DEFAULT (20MHz)
  2.     // For setting a specific frequency, use host.max_freq_khz (range 400kHz - 40MHz for SDMMC)
  3.     // Example: for fixed frequency of 10MHz, use host.max_freq_khz = 10000;
  4.     sdmmc_host_t host = SDMMC_HOST_DEFAULT();
  5.         host.max_freq_khz = 20000;
  6.     // This initializes the slot without card detect (CD) and write protect (WP) signals.
  7.     // Modify slot_config.gpio_cd and slot_config.gpio_wp if your board has these signals.
  8.     sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT();
  9.     slot_config.width = 4;
  10.     // On chips where the GPIOs used for SD card can be configured, set them in
  11.     // the slot_config structure:
  12.         //ZivDebug_Start
  13.         slot_config.clk = 48;
  14.         slot_config.cmd = 37;
  15.         slot_config.d0 = 10;
  16.         slot_config.d1 = 14;
  17.         slot_config.d2 = 35;
  18.         slot_config.d3 = 36;
  19.         //ZivDebug_End
复制代码

主要是指定工作频率为 20Mhz (如果你发现读取的时候会出错,不妨尝试降低这个频率);工作模式为4线;另外指定了使用的SD信号控制线和数据线。

1.     接下来,我们修改之前 camera_fb_get_cb() 函数中访问 SPI 的代码,修改为访问SD卡

  1. char buffer[64];
  2.         struct stat file_stat;
  3.         int  filesize;
  4.         FILE *fd = NULL;
  5.         sprintf(buffer,MOUNT_POINT"/m/%04d.jpg",PicIndex);
  6.         ESP_LOGI(TAG, "p1 %s %d",buffer,PicIndex);
  7.                
  8.         if (stat(buffer, &file_stat) == -1) {
  9.                 ESP_LOGI(TAG, "%d frame in %llums",
  10.                                 PicIndex,
  11.                                 (esp_timer_get_time()/1000-Elsp));
  12.                 Elsp=esp_timer_get_time()/1000;
  13.                 PicIndex=0;
  14.                 sprintf(buffer,MOUNT_POINT"/m/%04d.jpg",PicIndex);
  15.         } else {PicIndex++;}
  16.         fd = fopen(buffer, "r");
  17.        
  18.     fseek(fd, 0, SEEK_END);  
  19.     filesize = ftell(fd);  
  20.     rewind(fd);
  21.         ESP_LOGI(TAG, "send %d",filesize);
  22.         fread(&PicBuffer, 1, filesize, fd);
  23.         s_fb.uvc_fb.buf = PicBuffer;
  24.         s_fb.uvc_fb.len=filesize;
  25.         fclose(fd);
复制代码

基本思路是:尝试访问 m\NNNN.jpg 这样的文件,如果文件存在,那么取得他的大小,如果该文件不存在,说明最后一帧处理完成需要从第一张再开始。之后将文件内容读取到PicBuffer作为返回值返回给调用者。
目前测试的是 320X240 的内容,速度上完全没有问题。

完整的代码下载:



参考:


2.https://mc.dfrobot.com.cn/thread-317339-1-1.html


您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4

© 2013-2024 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail