ESP32-S2 Kaluga camera + lcd 示例入门

此篇博客用来讲简单记录 ESP32-S2 Kaluga 对应示例里的 API 使用。以 camera 示例 作为参考,主要分为以下三个部分:

  • lcd 初始化
  • camera 初始化
  • camera 数据传输到 lcd

1 lcd 初始化

可以看到 camera 示例 里对应的代码如下;

   lcd_config_t lcd_config = {
        .clk_fre         = 40 * 1000 * 1000,
        .pin_clk         = LCD_CLK,
        .pin_mosi        = LCD_MOSI,
        .pin_dc          = LCD_DC,
        .pin_cs          = LCD_CS,
        .pin_rst         = LCD_RST,
        .pin_bk          = LCD_BK,
        .max_buffer_size = 2 * 1024,
        .horizontal      = 2, /*!< 2: UP, 3: DOWN */
#ifdef CONFIG_CAMERA_JPEG_MODE
        .swap_data       = 1,
#else
        .swap_data       = 0,
#endif
    };

    lcd_init(&lcd_config);

lcd_config_t 可以配置 lcd 的管脚等参数,具体如下:

typedef struct {
    uint32_t clk_fre;
    uint8_t pin_clk;
    uint8_t pin_mosi;
    uint8_t pin_dc;
    uint8_t pin_cs;
    uint8_t pin_rst;
    uint8_t pin_bk;
    uint8_t horizontal;
    uint32_t max_buffer_size; // DMA used
    bool swap_data;
} lcd_config_t;

参数对应细节如下:

  • clk_fre 时钟
  • pin_clk 时钟线对应的 GPIO 脚
  • pin_mosi 数据(主机发送从机接收)线对应的 GPIO 脚
  • pin_dc 数据/命令线对应的 GPIO 脚
  • pin_cs 屏幕片选线对应的 GPIO 脚
  • pin_rst 复位线对应的 GPIO 脚
  • pin_bk 背光线对应的 GPIO 脚,背光设定了默认值,用户不用连接背光引脚也可点亮;此外,连接背光引脚,输入高电平(1)是将背光亮度调到最大,输入低电平(0)是关闭背光
  • max_buffer_size 申请的 DMA Buffer
  • swap_data 大部分屏幕是大端模式,而 ESP32 是小端模式,因此可在使用的接口驱动中根据 swap_data 配置可选择进行大小端转换。请注意: 当使用 SPI 接口时,由于 IDF 的 SPI 驱动内部没有提供该功能,接口驱动将会对传入数据进行转换,这要求传入的数据是可写的,因此数据 必须 存放在 RAM 中

2 camera 初始化

可以看到 camera 示例 里对应的代码如下;

    camera_config_t camera_config = {
        .pin_pwdn = -1,
        .pin_reset = -1,
        .pin_xclk = CAM_XCLK,
        .pin_sscb_sda = CAM_SDA,
        .pin_sscb_scl = CAM_SCL,

        .pin_d7 = CAM_D7,
        .pin_d6 = CAM_D6,
        .pin_d5 = CAM_D5,
        .pin_d4 = CAM_D4,
        .pin_d3 = CAM_D3,
        .pin_d2 = CAM_D2,
        .pin_d1 = CAM_D1,
        .pin_d0 = CAM_D0,
        .pin_vsync = CAM_VSYNC,
        .pin_href = CAM_HSYNC,
        .pin_pclk = CAM_PCLK,

        //XCLK 20MHz or 10MHz for OV2640 double FPS (Experimental)
        .xclk_freq_hz = 20000000,
        .ledc_timer = LEDC_TIMER_0,
        .ledc_channel = LEDC_CHANNEL_0,
#ifdef CONFIG_CAMERA_JPEG_MODE
        .pixel_format = PIXFORMAT_JPEG, //YUV422,GRAYSCALE,RGB565,JPEG
#else
        .pixel_format = PIXFORMAT_RGB565,
#endif
        .frame_size = FRAMESIZE_QVGA,    //QQVGA-UXGA Do not use sizes above QVGA when not JPEG
        .jpeg_quality = 12, //0-63 lower number means higher quality
        .fb_count = 2       //if more than one, i2s runs in continuous mode. Use only with JPEG
    };
    //initialize the camera
    esp_err_t err = esp_camera_init(&camera_config);
    if (err != ESP_OK) {
        ESP_LOGE(TAG, "Camera Init Failed");
        return;
    }
    sensor_t *s = esp_camera_sensor_get();
    s->set_vflip(s, 1);//flip it back
    //initial sensors are flipped vertically and colors are a bit saturated
    if (s->id.PID == OV3660_PID) {
        s->set_brightness(s, 1);//up the blightness just a bit
        s->set_saturation(s, -2);//lower the saturation
    }
    //drop down frame size for higher initial frame rate
    s->set_framesize(s, FRAMESIZE_240X240); //FRAMESIZE_240X240
    ESP_LOGI(TAG, "Camera Init done");

#ifdef CONFIG_CAMERA_JPEG_MODE
    ESP_LOGI(TAG, "Camera jpeg mode");
    uint8_t *rgb565 = malloc(240 * 320 * 2);
    if (NULL == rgb565) {
        ESP_LOGE(TAG, "can't alloc memory for rgb565 buffer");
        return;
    }
#endif

//...do something
#ifdef CONFIG_CAMERA_JPEG_MODE
    free(rgb565);
#endif

这部分需要注意的参数如下:

  • fb_count 控制使用 framebuffer 的个数,个数越多消耗内存越大。其值大于 2 时,获取的一帧图像可能不是实时的
  • fb_location 控制 framebuffer 存放的位置,当内部内存不足时,必须设置为 CAMERA_FB_IN_PSRAM
  • xclk_freq_hz 此大小直接影响了帧率,这个值必须是一个能被 80 MHz 整数分频的频率,一般设置为 20 MHz

注:s->set_framesize(s, FRAMESIZE_240X240); //FRAMESIZE_240X240 这一行在使用第二版 ILI9341 时由于 90 度的旋转,需要将默认的 FRAMESIZE_QVGA 改成 FRAMESIZE_240X240

3 camera 数据传输到 lcd

可以看到 camera 示例 里对应的代码如下;

    while (1) {
        camera_fb_t *pic = esp_camera_fb_get();
        if (pic) {
            ESP_LOGI(TAG, "picture: %d x %d %dbyte", pic->width, pic->height, pic->len);
            lcd_set_index(0, 0, pic->width - 1, pic->height - 1);
#ifdef CONFIG_CAMERA_JPEG_MODE
            jpg2rgb565(pic->buf, pic->len, rgb565, JPG_SCALE_NONE);
            lcd_write_data(rgb565, 2 * (pic->width * pic->height));
#else
            lcd_write_data(pic->buf, pic->len);
#endif
            esp_camera_fb_return(pic);
        } else {
            ESP_LOGE(TAG, "Get frame failed");
        }
    }

这部分就是经过封装的 API 调用。先调用 esp_camera_fb_get 获取 camera 拍摄的数据,然后通过 lcd_set_index 设置 lcd 的起始和结束地址。之后将 camera 拍摄到的数据通过 lcd_write_data 来让 lcd 显示出来,最后使用 esp_camera_fb_return 释放 camera 使用的 buffer 来方便后续重复利用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值