【ESP32S3学习笔记】增加Camera外设 OV2640

【ESP32S3学习笔记】

提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加
例如:第一章 Python 机器学习入门之pandas的使用


提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

提示:这里可以添加本文要记录的大概内容:

之前ESP32驱动单液晶屏的方案已经完成,从整个过程来看,底层来说相对还是比较简单,基本是以模块的形式集成到一起。无论是LVGL还是对应的ESP32驱动都是成熟模组,配合GUI-GUIDER软件的支持,实现一个简单的Demo是比较容易的。当然更复杂一点和深入的就是理解GUI-GUIDER的编程逻辑,熟练掌握GUI-Guider之后再结合自己的应用进行设计。再深入的话可以再熟悉一下底层,对整体的速度进行一个优化。

有了屏幕之后,又尝试增加了Camera功能。这里用了Github上的开源库,也可以根据ESP32-CAM开发套件对应的资料进行设计。代码部分应该相差不大,驱动层会有一些微调。
GITHUB


提示:以下是本篇文章正文内容,下面案例可供参考

一、建立工程

注:在之前的工程基础上,大家自己可以根据自己的工程目录情况自行调整。
1、将esp32-camera放置到components目录下,CMakeLists.txt也都是现成的,不需要再进行调整;
2、从esp32-camera的examples里,提取了一些接口函数做成了bsp_camera.h和bsp_camera.c;
添加完文件之后,就可以编译一下。编译成功后,进入SDK配置编辑器能看到一些Camera的相关配置。
在这里插入图片描述

二、SPIRAM配置

因为camera的接口函数里用到了SPIRAM,所以还要对SPIRAM进行配置。所以大家要注意自己手中的模块是否支持SPIRAM,以及SPIRAM使用的SPI接口类型。如果没有配置的话,串口打印的log会提示malloc失败的相关信息。
在SDK配置编辑器里搜索SPI找到其配置项,如下图:
在这里插入图片描述
点击小方框,使能这部分配置。配置使用默认即可,除了下图中的这个,要根据使用的模块来进行选择。
在这里插入图片描述

三、Camera配置

1.I/O配置

#define CAM_PIN_PWDN -1
#define CAM_PIN_RESET 9 //software reset will be performed
#define CAM_PIN_XCLK 5
#define CAM_PIN_SIOD 48
#define CAM_PIN_SIOC 47

#define CAM_PIN_D7 4
#define CAM_PIN_D6 6
#define CAM_PIN_D5 7
#define CAM_PIN_D4 15
#define CAM_PIN_D3 17
#define CAM_PIN_D2 8
#define CAM_PIN_D1 18
#define CAM_PIN_D0 16
#define CAM_PIN_VSYNC 46
#define CAM_PIN_HREF 3
#define CAM_PIN_PCLK 45

这里面PWDN引脚可以不使用。不过需要注意的是,我一开始以为PCLK不需要,本身是XCLK(mclk)的一个分频信号,但是实际试的时候发现还不行。

2.模式配置

跟使用相关比较大的几项,一个是输出格式和像素大小。也就是pixel_format和frame_size。这个要根据你的LED屏来进行配置。我这用的是一个320*240的屏幕。

    .pixel_format = PIXFORMAT_RGB565, //YUV422,GRAYSCALE,RGB565,JPEG
    .frame_size = FRAMESIZE_QVGA,    //QQVGA-UXGA, For ESP32, do not use sizes above QVGA when not JPEG. The performance of the ESP32-S series has improved a lot, but JPEG mode always gives better frame rates.

    .jpeg_quality = 12, //0-63, for OV series camera sensors, lower number means higher quality
    .fb_count = 1,       //When jpeg mode is used, if fb_count more than one, the driver will work in continuous mode.
    .grab_mode = CAMERA_GRAB_WHEN_EMPTY,

3.添加任务

这里在原来工程的基础上,增加了一个camera工程,

xTaskCreatePinnedToCore(cameraTask, "camera", 4096 * 8, NULL, 0, NULL, 1);

static void cameraTask(void *pvParameter)
{
    
    
    ESP_LOGI(MYTAG, "Taking picture...");
    if(ESP_OK != init_camera()) {
    
    
        ESP_LOGI(MYTAG, "Fail");
    }
    while(1)
    {
    
    

        ESP_LOGI(MYTAG, "Taking picture...");
        pic = esp_camera_fb_get();
        _a376d2b2e20a7039615bff477fe3aaa9_320x240.data = pic->buf;
        // use pic->buf to access the image
        ESP_LOGI(MYTAG, "Picture taken! Its size was: %zu bytes", pic->len);
        ESP_LOGI(MYTAG, "W: %d H:%d format:%d", pic->width,pic->height,pic->format);
        esp_camera_fb_return(pic);

        vTaskDelay(5000 / portTICK_RATE_MS);
    }
}

任务也比较简单,每隔5s拍一张图片,其中为了让图片在屏幕上显示,我将pic数据的缓冲区指针赋给了原来工程中的一张图片的缓冲区变量。
到现在已经已基本完成了,实际测试却发现图像显示有点混乱。这是由于原来工程里面,图片定义的数据类型与现在的不符。

4.调整图片的参数配置

这里是Gui-Guider生成的存储图片的结构体,

lv_img_dsc_t _a376d2b2e20a7039615bff477fe3aaa9_320x240 = {
    
    
  .header.always_zero = 0,
  .header.w = 320,
  .header.h = 240,
  .data_size = 76800 * LV_COLOR_SIZE / 8,
  .header.cf = LV_IMG_CF_TRUE_COLOR,
  .data = _a376d2b2e20a7039615bff477fe3aaa9_320x240_map,
};

其中header.cf的原配置是,是带了ALPHA通道的:

  .header.cf = LV_IMG_CF_TRUE_COLOR_ALPHA,

按照上面的模式更改一下,去掉ALPHA通道,这样显示就正常了。


总结

提示:这里对文章进行总结:

猜你喜欢

转载自blog.csdn.net/lunzilx/article/details/128591118