前言
之前我将爱智官方的代码移植到了 arduino 上,详细可见arduino 天下第一(暴论) -- 智能猫眼与 SDDC 连接器移植到 arduino 上
在这过程中我踩了一些坑,在这里和大家分享一下。
arduino 操作接口
arduino 官方提供demo已经封装很好了,只用调用一个函数就能完成拍摄上传等一系列操作,但是如果这个接口不符合我们的需求,就只能自己同时改改了。
通过下面的连接可以看到 ESP32-CAM 底层的东西一些接口
https://github.com/espressif/...或者你已经安装了 ESP32-CAM 相关库后可以去:
C:\Users\123456\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.5\tools\sdk\include\esp32-camera可以看到一个 esp_camera.h 文件,里面有一些可以用到的接口和结构体。
/**
* @brief Data structure of camera frame buffer
*/
typedef struct {
uint8_t * buf;
/*!< Pointer to the pixel data */// 这就是摄像头拍下来的数据
size_t len;
/*!< Length of the buffer in bytes */
size_t width;
/*!< Width of the buffer in pixels */
size_t height;
/*!< Height of the buffer in pixels */
pixformat_t format;
/*!< Format of the pixel data */
struct timeval timestamp;
/*!< Timestamp since boot of the first DMA buffer of the frame */
} camera_fb_t;
#define ESP_ERR_CAMERA_BASE 0x20000
#define ESP_ERR_CAMERA_NOT_DETECTED(ESP_ERR_CAMERA_BASE + 1)
#define ESP_ERR_CAMERA_FAILED_TO_SET_FRAME_SIZE (ESP_ERR_CAMERA_BASE + 2)
#define ESP_ERR_CAMERA_FAILED_TO_SET_OUT_FORMAT (ESP_ERR_CAMERA_BASE + 3)
#define ESP_ERR_CAMERA_NOT_SUPPORTED(ESP_ERR_CAMERA_BASE + 4)
/**
* @brief Initialize the camera driver
*
* @note call camera_probe before calling this function
*
* This function detects and configures camera over I2C interface,
* allocates framebuffer and DMA buffers,
* initializes parallel I2S input, and sets up DMA descriptors.
*
* Currently this function can only be called once and there is
* no way to de-initialize this module.
*
* @param configCamera configuration parameters
*
* @return ESP_OK on success
*/
esp_err_t esp_camera_init(const camera_config_t* config);
/**
* @brief Deinitialize the camera driver
*
* @return
*- ESP_OK on success
*- ESP_ERR_INVALID_STATE if the driver hasn't been initialized yet
*/
esp_err_t esp_camera_deinit();
/**
* @brief Obtain pointer to a frame buffer.
*
* @return pointer to the frame buffer
*/
camera_fb_t* esp_camera_fb_get();
/**
* @brief Return the frame buffer to be reused again.
*
* @param fbPointer to the frame buffer
*/
void esp_camera_fb_return(camera_fb_t * fb);
/**
* @brief Get a pointer to the image sensor control structure
*
* @return pointer to the sensor
*/
sensor_t * esp_camera_sensor_get();
/**
* @brief Save camera settings to non-volatile-storage (NVS)
*
* @param keyA unique nvs key name for the camera settings
*/
esp_err_t esp_camera_save_to_nvs(const char *key);
/**
* @brief Load camera settings from non-volatile-storage (NVS)
*
* @param keyA unique nvs key name for the camera settings
*/
esp_err_t esp_camera_load_from_nvs(const char *key);
代码解析和注意事项 摄像头拍下来的数据和图像属性都保存在 camera_fb_t 结构体中,其中 buf 就是图像数据,其他的都是相关属性
uint8_t * buf;
/*!< Pointer to the pixel data */// 这就是摄像头拍下来的数据
size_t len;
/*!< Length of the buffer in bytes */
size_t width;
/*!< Width of the buffer in pixels */
size_t height;
/*!< Height of the buffer in pixels */
pixformat_t format;
/*!< Format of the pixel data */
struct timeval timestamp;
/*!< Timestamp since boot of the first DMA buffer of the frame */
} camera_fb_t;
然后通过 esp_camera_fb_get 可以拍摄一帧画面,并且返回 camera_fb_t 结构体指针。
没错,这个接口不仅是注释中描述那样返回一个指针,他在返回之前会先拍摄一帧画面,然后才返回指针,所以大家不用去找专门的拍摄函数了,也不用担心直接调用这个函数会返回空指针。
/**
* @brief Obtain pointer to a frame buffer.
*
* @return pointer to the frame buffer
*/
camera_fb_t* esp_camera_fb_get();
另外每使用完一帧画面后一定要调用 esp_camera_fb_return 释放掉不用的数据,否则没办法拍摄下一帧。
/**
* @brief Return the frame buffer to be reused again.
*
* @param fbPointer to the frame buffer
*/
void esp_camera_fb_return(camera_fb_t * fb);
另外这些接口都是比较底层原始的接口,没有 IDF 平台封装的 camera_run(), camera_get_data_size 等函数这么安全,所以无法使用官方代码中那种通过判断时间间隔控制拍照的方法,只能在应用端控制拍摄频率
总结 【ESP32-CAM移植和使用经验分享】这玩意现在只能说勉强能用,因为这玩意很容易过热,持续拍摄一段时间后,信号会逐渐不稳定,直到彻底掉线。
推荐阅读
- 从理论到实战,带你全面解读智能物联网技术!
- 阿里云物联网平台: Android 连接阿里云物联网平台
- 玩转OneNET物联网平台之MQTT服务④ —— 远程控制LED(设备自注册)+ Android App控制
- 智能家居|深入了解开源智能家居平台,解决品牌割裂的终极利器()
- android|android-19_如何在Android上关闭COVID-19曝光跟踪和通知
- 树莓派4B|树莓派4B:(内涵相关所有系统及软件文件)初始化配置、烧录镜像系统、配置wifi、PC端显示等
- 使用物联网的作物监控和智能农业