主要参考资料:
ESP32-S2 Kaluga camera + lcd 示例入门: https://blog.csdn.net/Marchtwentytwo/article/details/121121028
摄像头应用方案常见问题汇总: https://docs.espressif.com/projects/esp-faq/zh_CN/latest/application-solution/camera-application.html
一、camera初始化
1.配置接线和驱动
static camera_config_t camera_config = {
.pin_pwdn = CAM_PIN_PWDN,
.pin_reset = CAM_PIN_RESET,
.pin_xclk = CAM_PIN_XCLK,
.pin_sscb_sda = CAM_PIN_SIOD,
.pin_sscb_scl = CAM_PIN_SIOC,
.pin_d7 = CAM_PIN_D7,
.pin_d6 = CAM_PIN_D6,
.pin_d5 = CAM_PIN_D5,
.pin_d4 = CAM_PIN_D4,
.pin_d3 = CAM_PIN_D3,
.pin_d2 = CAM_PIN_D2,
.pin_d1 = CAM_PIN_D1,
.pin_d0 = CAM_PIN_D0,
.pin_vsync = CAM_PIN_VSYNC,
.pin_href = CAM_PIN_HREF,
.pin_pclk = CAM_PIN_PCLK,
.xclk_freq_hz = 20000000, //XCLK 20MHz or 10MHz for OV2640 double FPS (Experimental)
.ledc_timer = LEDC_TIMER_0, //ledc定时器用于生成XCLK
.ledc_channel = LEDC_CHANNEL_0,
.pixel_format = PIXFORMAT_RGB565, //YUV422,GRAYSCALE,RGB565,JPEG
.frame_size = FRAMESIZE_QVGA, //QQVGA-UXGA Do not use sizes above QVGA when not JPEG FRAMESIZE_QVGA
.jpeg_quality = 12, //0-63 lower number means higher quality
.fb_count = 2, //控制使用 framebuffer 的个数,个数越多消耗内存越大。其值大于 2 时,获取的一帧图像可能不是实时的。仅与JPEG一起使用。
.fb_location = CAMERA_FB_IN_PSRAM,//存放在外部PSRAM中,还可选择内部DRAM
.grab_mode = CAMERA_GRAB_WHEN_EMPTY//当缓冲区为空时填充缓冲区。资源较少,但第一个'fb_count'帧可能是旧的
};
2.相机初始化 并 配置图像传感器
void app_camera_init()
{
// camera init
esp_err_t err = esp_camera_init(&camera_config);
if (err != ESP_OK)
{
ESP_LOGE(TAG, "Camera init failed with error 0x%x", err);
return;
}
//配置图像传感器
sensor_t *s = esp_camera_sensor_get();
s->set_vflip(s, 0);
s->set_hmirror(s, 1);
}
二、传输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 来方便后续重复利用。