esp32多个例程如何组合

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了esp32多个例程如何组合相关的知识,希望对你有一定的参考价值。

参考技术A esp32多个例程组合步骤如下:
1、将所有的ESP32例程放在一个文件夹中,并确保每个例程都可以独立编译和运行。
2、针对每个例程,将其主要代码分为两部分:初始化代码和主循环代码。初始化代码负责设置ESP32的配置、引脚、WiFi等参数,并启动所需的服务和任务;主循环代码则负责执行具体的功能。
3、将所有的初始化代码放在一个初始化函数中,例如voidsetup(),并在该函数中依次调用每个例程的初始化函数。
4、将所有的主循环代码放在一个主循环函数中,例如voidloop(),并在该函数中使用条件语句或开关语句控制每个例程的执行。
5、可以在初始化函数中创建多个任务,每个任务对应一个例程,每个任务都有自己的主循环函数。使用xTaskCreate()函数创建任务,指定任务的处理函数和任务堆栈的大小。
6、可以使用信号量、消息队列等机制实现不同任务之间的通信和同步。
7、编译并上传代码到ESP32,即可实现多个例程的组合运行。

VScode+esp-idf:例程(esp32-web-camera)保存视频到sd卡(附源码)

文章目录


昨天测试了保存图片到sd卡,我就想,视频就是一帧帧图片构成的,现在离保存视频只差一步之遥。网络上使用ESP32保存视频,最多是python+openCV的方法。我想使用esp-idf原生态应该也可以做到。
于是百度到下面的文章:
1.作者:原野追逐,《 JPEG流封装AVI视频》。这篇文章将原理结合代码,讲得非常详细。 这个没有语音数据的
立马把源代码拷贝过来,几乎不用修改,直接就可以使用。非常感谢作者原野追逐的贡献。

1.移植到《esp32-web-camera》

在上一篇文章《VScode+esp-idf:安信可esp32-cam开发板测试sd卡》的工程里增加文件 “Jpeg2AVI.c” “list.c”,其他不变:

set(COMPONENT_SRCS "app_main.c" "app_wifi.c" "app_camera.c" "app_httpd.c" 
                   "app_mdns.c" "app_sd.c" "Jpeg2AVI.c" "list.c")

2. jpeg2avi使用方法

准备开始 重复写入 准备结束 fopen jpeg2avi_start jpeg2avi_add_frame jpeg2avi_end fclose

2.1 何处调用jpeg2avi_start

在我们这个工程中,在SdCard_init函数最后面调用jpeg2avi_start(这里的avi文件名应该有实时时间戳):

void SdCard_init(void)

......
    sdmmc_card_print_info(stdout, card);

    fp_avi = fopen("/sdcard/sample.avi","wb");
    if(fp_avi == NULL)
        ESP_LOGE(TAG, "Failed to open file for writing");
        return;
        
    jpeg2avi_start(fp_avi);

2.2 何处调用jpeg2avi_add_frame

这个 StartStream 按键会启动实时视频读取和传输到网页,在这里面把读取的图片写入avi文件,保存到sd卡。

StartStream 按键触发的函数是 stream_handler

2.3何处调用jpeg2avi_end

这里对函数进行简单的介绍:

void jpeg2avi_end(FILE *fp, int width, int height, int fps);

照片的宽度和高度就是像素,最高像素是由摄像头的物理参数决定的,小于最高像素就可以由软件设定。网页中也可以修改:

出于各种原因,我选了800(宽) x 600(高)的像素。这里说一下如何在初始化时设置像素:

宏定义 FRAMESIZE_SVGA(800x600)在 《$ENVIDF_PATH/examples/esp32-web-camera-master/components/esp32-camera/driver/include/sensor.h》中:

typedef enum 
    FRAMESIZE_96X96,    // 96x96
    FRAMESIZE_QQVGA,    // 160x120
    FRAMESIZE_QCIF,     // 176x144
    FRAMESIZE_HQVGA,    // 240x176
    FRAMESIZE_240X240,  // 240x240
    FRAMESIZE_QVGA,     // 320x240
    FRAMESIZE_CIF,      // 400x296
    FRAMESIZE_HVGA,     // 480x320
    FRAMESIZE_VGA,      // 640x480
    FRAMESIZE_SVGA,     // 800x600
    FRAMESIZE_XGA,      // 1024x768
    FRAMESIZE_HD,       // 1280x720
    FRAMESIZE_SXGA,     // 1280x1024
    FRAMESIZE_UXGA,     // 1600x1200
    // 3MP Sensors
    FRAMESIZE_FHD,      // 1920x1080
    FRAMESIZE_P_HD,     //  720x1280
    FRAMESIZE_P_3MP,    //  864x1536
    FRAMESIZE_QXGA,     // 2048x1536
    // 5MP Sensors
    FRAMESIZE_QHD,      // 2560x1440
    FRAMESIZE_WQXGA,    // 2560x1600
    FRAMESIZE_P_FHD,    // 1080x1920
    FRAMESIZE_QSXGA,    // 2560x1920
    FRAMESIZE_INVALID
 framesize_t;

调用 jpeg2avi_end函数,首先要停止写入,就是先停止实时视频。我借用调整LED亮度的命令调用这个函数。

有这个命令的前提是配置LED闪光灯使能:

在函数 cmd_handle中调用:

3.编译运行工程

编译,写入,运行:
1.第一次点击StartStream 按键开始录制;
2.第二次点击StartStream 按键停止录制;
3.点击 LED Intensity完成收尾工作。

I (706575) camera_httpd: MJPG: 21235B 76ms (13.2fps), AVG: 69ms (14.5fps), 0+0+0+0=0 0
I (706655) camera_httpd: MJPG: 23257B 79ms (12.7fps), AVG: 69ms (14.5fps), 0+0+0+0=0 0
I (706715) camera_httpd: MJPG: 20800B 63ms (15.9fps), AVG: 69ms (14.5fps), 0+0+0+0=0 0
I (706785) camera_httpd: MJPG: 23200B 68ms (14.7fps), AVG: 69ms (14.5fps), 0+0+0+0=0 0
I (706855) camera_httpd: MJPG: 23911B 74ms (13.5fps), AVG: 69ms (14.5fps), 0+0+0+0=0 0
I (706925) camera_httpd: MJPG: 23817B 71ms (14.1fps), AVG: 70ms (14.3fps), 0+0+0+0=0 0
I (706995) camera_httpd: MJPG: 23163B 66ms (15.2fps), AVG: 70ms (14.3fps), 0+0+0+0=0 0
I (707075) camera_httpd: MJPG: 22794B 74ms (13.5fps), AVG: 70ms (14.3fps), 0+0+0+0=0 0
I (707145) camera_httpd: MJPG: 23467B 72ms (13.9fps), AVG: 70ms (14.3fps), 0+0+0+0=0 0
W (707215) httpd_txrx: httpd_sock_err: error in send : 104
I (707215) camera_httpd: Set LED intensity to 0
W (707215) httpd_uri: httpd_uri: uri handler execution failed
I (709555) camera_httpd: led_intensity = 64
I (709585) camera_httpd: close AVI file

从打印出来的信息,写入的视频流,1秒才13-15帧,视频不是很流畅;可见要同时完成读取摄像头数据、传输到网页、写入sd卡这3个功能,对esp32来说很吃力。

4.源代码

本文为了测试保存avi视频,几乎没有什么逻辑可言,纯粹为了测试功能而实现。读者可以在这个的基础上去完善。
比如我就想做一个延时拍摄的摄像机,可以设置1秒-60秒拍一张,然后以1秒24帧的速度播放,这个esp32就能轻松胜任。用按键启动和停止拍摄。
https://gitee.com/huangweide001/esp32_test/tree/master/camera_web_server_avi

以上是关于esp32多个例程如何组合的主要内容,如果未能解决你的问题,请参考以下文章

嵌入式硬件Esp32例程Hello World Example 注释

ESP32+st7789/ili9341运行LVGL例程,依赖ESP-IDF编译lv_port_esp32官方Demo

ESP32+st7789/ili9341运行LVGL例程,依赖ESP-IDF编译lv_port_esp32官方Demo

ESP8266+微信配网smartconfig,esp32可用

VScode+esp-idf:例程(esp32-web-camera)保存视频到sd卡(附源码)

esp32 串口,蓝牙等其他方式OTA