ESP32-S3模组上跑通esp32-camera(3)

接前一篇文章:ESP32-S3模组上跑通esp32-camera(2)

 

本文内容参考:

esp32-camera入门(基于ESP-IDF)_esp32 camera-CSDN博客

OV5640手册解读-CSDN博客

OV5640 自动对焦成像模组应用指南_ov5640中strobe-CSDN博客

特此致谢!

 

一、OV5640初始化

1. 配置接线和驱动

#include "esp_camera.h"
 
//WROVER-KIT PIN Map
#define CAM_PIN_PWDN    -1 //power down is not used
#define CAM_PIN_RESET   -1 //software reset will be performed
#define CAM_PIN_XCLK    21
#define CAM_PIN_SIOD    26
#define CAM_PIN_SIOC    27
 
#define CAM_PIN_D7      35
#define CAM_PIN_D6      34
#define CAM_PIN_D5      39
#define CAM_PIN_D4      36
#define CAM_PIN_D3      19
#define CAM_PIN_D2      18
#define CAM_PIN_D1       5
#define CAM_PIN_D0       4
#define CAM_PIN_VSYNC   25
#define CAM_PIN_HREF    23
#define CAM_PIN_PCLK    22
 
static camera_config_t camera_config = {
    .pin_pwdn  = CAM_PIN_PWDN,
    .pin_reset = CAM_PIN_RESET,
    .pin_xclk = CAM_PIN_XCLK,
    .pin_sccb_sda = CAM_PIN_SIOD,
    .pin_sccb_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,//EXPERIMENTAL: Set to 16MHz on ESP32-S2 or ESP32-S3 to enable EDMA mode
    .ledc_timer = LEDC_TIMER_0,
    .ledc_channel = LEDC_CHANNEL_0,
 
    .pixel_format = PIXFORMAT_JPEG,//YUV422,GRAYSCALE,RGB565,JPEG
    .frame_size = FRAMESIZE_UXGA,//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//CAMERA_GRAB_LATEST. Sets when buffers should be filled
};
 
esp_err_t camera_init(){
    //power up the camera if PWDN pin is defined
    if(CAM_PIN_PWDN != -1){
        pinMode(CAM_PIN_PWDN, OUTPUT);
        digitalWrite(CAM_PIN_PWDN, LOW);
    }
 
    //initialize the camera
    esp_err_t err = esp_camera_init(&camera_config);
    if (err != ESP_OK) {
        ESP_LOGE(TAG, "Camera Init Failed");
        return err;
    }
 
    return ESP_OK;
}
 
esp_err_t camera_capture(){
    //acquire a frame
    camera_fb_t * fb = esp_camera_fb_get();
    if (!fb) {
        ESP_LOGE(TAG, "Camera Capture Failed");
        return ESP_FAIL;
    }
    //replace this with your own function
    process_image(fb->width, fb->height, fb->format, fb->buf, fb->len);
  
    //return the frame buffer back to the driver for reuse
    esp_camera_fb_return(fb);
    return ESP_OK;
}

上一回讲解了camera_config_t结构一开始的第4、5两个成员,本回继续解析后续成员。为了便于理解和回顾,再次贴出camera_config_t的定义,在components\esp32-camera\driver\include\esp_camera.h中,如下:

/**
 * @brief Configuration structure for camera initialization
 */
typedef struct {
    int pin_pwdn;                   /*!< GPIO pin for camera power down line */
    int pin_reset;                  /*!< GPIO pin for camera reset line */
    int pin_xclk;                   /*!< GPIO pin for camera XCLK line */
    union {
        int pin_sccb_sda;           /*!< GPIO pin for camera SDA line */
        int pin_sscb_sda __attribute__((deprecated("please use pin_sccb_sda instead")));           /*!< GPIO pin for camera SDA line (legacy name) */
    };
    union {
        int pin_sccb_scl;           /*!< GPIO pin for camera SCL line */
        int pin_sscb_scl __attribute__((deprecated("please use pin_sccb_scl instead")));           /*!< GPIO pin for camera SCL line (legacy name) */
    };
    int pin_d7;                     /*!< GPIO pin for camera D7 line */
    int pin_d6;                     /*!< GPIO pin for camera D6 line */
    int pin_d5;                     /*!< GPIO pin for camera D5 line */
    int pin_d4;                     /*!< GPIO pin for camera D4 line */
    int pin_d3;                     /*!< GPIO pin for camera D3 line */
    int pin_d2;                     /*!< GPIO pin for camera D2 line */
    int pin_d1;                     /*!< GPIO pin for camera D1 line */
    int pin_d0;                     /*!< GPIO pin for camera D0 line */
    int pin_vsync;                  /*!< GPIO pin for camera VSYNC line */
    int pin_href;                   /*!< GPIO pin for camera HREF line */
    int pin_pclk;                   /*!< GPIO pin for camera PCLK line */
 
    int xclk_freq_hz;               /*!< Frequency of XCLK signal, in Hz. EXPERIMENTAL: Set to 16MHz on ESP32-S2 or ESP32-S3 to enable EDMA mode */
 
    ledc_timer_t ledc_timer;        /*!< LEDC timer to be used for generating XCLK  */
    ledc_channel_t ledc_channel;    /*!< LEDC channel to be used for generating XCLK  */
 
    pixformat_t pixel_format;       /*!< Format of the pixel data: PIXFORMAT_ + YUV422|GRAYSCALE|RGB565|JPEG  */
    framesize_t frame_size;         /*!< Size of the output image: FRAMESIZE_ + QVGA|CIF|VGA|SVGA|XGA|SXGA|UXGA  */
 
    int jpeg_quality;               /*!< Quality of JPEG output. 0-63 lower means higher quality  */
    size_t fb_count;                /*!< Number of frame buffers to be allocated. If more than one, then each frame will be acquired (double speed)  */
    camera_fb_location_t fb_location; /*!< The location where the frame buffer will be allocated */
    camera_grab_mode_t grab_mode;   /*!< When buffers should be filled */
#if CONFIG_CAMERA_CONVERTER_ENABLED
    camera_conv_mode_t conv_mode;   /*!< RGB<->YUV Conversion mode */
#endif
 
    int sccb_i2c_port;              /*!< If pin_sccb_sda is -1, use the already configured I2C bus by number */
} camera_config_t;

接下来关注以下成员:

typedef struct {
    ……
    int pin_d7;                     /*!< GPIO pin for camera D7 line */
    int pin_d6;                     /*!< GPIO pin for camera D6 line */
    int pin_d5;                     /*!< GPIO pin for camera D5 line */
    int pin_d4;                     /*!< GPIO pin for camera D4 line */
    int pin_d3;                     /*!< GPIO pin for camera D3 line */
    int pin_d2;                     /*!< GPIO pin for camera D2 line */
    int pin_d1;                     /*!< GPIO pin for camera D1 line */
    int pin_d0;                     /*!< GPIO pin for camera D0 line */
    ……
} camera_config_t; 

这些成员分别对应了OV5640的DVP接口的8位数据输出,数据的内容根据不同的模式设置有所不同。如下图所示:

0b1fe466d53a4bf2b61888bbe500c249.png

3635172fbc46413ca3ae10ecc58395c8.png

cb1077cfe8c846df9fd03d3458925e56.png

507811d88901400cacde77cd1fee0d23.png

有人会问了,不是D[9:0]吗?怎么代码中只用了D[7:0]?上边又说是8位数据输出?其实是这样:OV5640的视频输出接口共有10位,为D[9:0]。当输出为10-bit RGB raw格式时,使用D[9:0];当输出格式为8-bit YCbCr或8-bit RGB raw以及8-bit RGB 565时, 使用 D[9:2]。

回到示例代码中。camera_config_t结构的这几个输出数据成员已经弄清楚了,但是具体赋的是什么值,还要弄清楚。参见上边代码片段:

dc541dcd2a9249929d8143a4fa25801b.png

CAM_PIN_D7~CAM_PIN_D0都是宏,就在代码开头处。定义如下:

68dd08d7516a47db89cbfbcb5bfc18ea.png

实际上这几个数据输出引脚的具体定义是视具体硬件而定的。看ESP32(或ESP32-S3)主芯片使用的哪个引脚,这里就定义为哪个。

这样,camera_config_t结构及其实例camera_config的第3段代码就解析完了,下一回继续往下解析。

 

### 使用 ESP32-S3 驱动 MPU6050 传感器 对于使用 ESP32-S3 来驱动 MPU6050 传感器,硬件连接方式遵循 I²C 协议标准配置[^2]。具体来说: - **电源连接**:VCC 引脚应与 ESP32-S3 模块的 3.3V 输出相接以提供电力支持;GND 引脚需同 ESP32-S3 地线相连确保电路稳定工作。 - **I²C 数据线连接**:SCL 和 SDA 是 MPU6050 上用于信的主要引脚。这些应该分别对应到 ESP32-S3 开发板上的 GPIO 管脚,默认情况下分别是 GPIO 22 (SCL) 和 GPIO 21 (SDA)。 为了实现上述功能,在软件方面推荐采用 Arduino IDE 平台进行编程开发。下面给出一段简单的代码示例来初始化并读取来自 MPU6050 的数据: ```cpp #include <Wire.h> #include "I2Cdev.h" #include "MPU6050_6Axis_MotionApps20.h" // 设备地址定义 #define MPU6050_ADDRESS 0x68 MPU6050 mpu; void setup() { Serial.begin(115200); Wire.begin(); Wire.setClock(400000); // 初始化 MPU6050 mpu.initialize(); if (!mpu.testConnection()) { Serial.println("MPU6050 connection failed"); while (true) {} } else { Serial.println("MPU6050 connected successfully!"); } // 加载 DMP 设置 devStatus = mpu.dmpInitialize(); } void loop() { // 获取新的传感器数据包大小 int packetSize = mpu.dmpGetFIFOPacketSize(); // 如果有足够的 FIFO 缓冲区空间,则尝试获取新数据 if (fifoCount >= packetSize) { mpu.getFIFOBytes(fifoBuffer, packetSize); // 解析原始加速度计和陀螺仪数据 mpu.dmpGetQuaternion(&q, fifoBuffer); mpu.dmpGetGravity(&gravity, &q); mpu.dmpGetYawPitchRoll(ypr, &q, &gravity); // 打印角度信息 Serial.print("yaw: "); Serial.print(ypr[0] * 180/M_PI); Serial.print(", pitch: "); Serial.print(ypr[1] * 180/M_PI); Serial.print(", roll: "); Serial.println(ypr[2] * 180/M_PI); } } ``` 这段程序实现了基本的数据采集流程,包括设置串口讯波特率、启动 IIC 总线以及完成 MPU6050 芯片初始化操作等步骤。之后进入主循环部分不断从设备中提取最新的姿态角信息并过串行端口打印出来供进一步处理分析之用。 需要注意的是,尽管 ESP32-S3 提供了相对充裕的内部 SRAM 容量(约 512KB),但在运行复杂应用时仍可能面临资源紧张的情况,因此建议优化算法结构减少不必要的开销[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蓝天居士

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值