ESP32 AUDIO OV2640摄像头 音频调试日记


前言

记录一下ESP32-DOWD芯片音频和摄像头的调试过程。
主芯片:ESP32-D0WD
摄像头:OV2640
ADF:最新
IDF环境:audio/stack_on_psram_v3.3 v3.3.1-203-g0c1859a5a-dirty
启动日志:
在这里插入图片描述


一、外部PSRAM和FLASH公用CLK引脚

为了节约IO口,把外部PSRAM的CLK和外部FLASH的CLK引脚短接,原demo板的CLK引脚为IO16,公用成IO17,需要将spiram_psram.c中关于外部psram_io.psram_clk_io相关的操作全部屏蔽。

在这里插入图片描述

二、外部PSRAM申请内存注意

为了节约内部sram,需要把尽量多的内存占用放到外部sram,需要把Maximum malloc() size, in bytes, to always put in internal memory设置到尽量小,不含摄像头的时候可以设置到128,但是有了摄像头后测试1300可以正常捕获摄像头QQVGA图像,过小会导致超时,若需要图像越大,此值应相应调大。
在这里插入图片描述

二、摄像头

1.ESP32 摄像头IO使用

ESP32外围设备包括:

18个模数转换器(ADC)通道
3个SPI接口
3个UART接口
2个I2C接口
16个脉冲宽度调制输出通道
2个数模转换器(DAC)
2个I2S接口
10个电容传感GPIO
仅输入的管脚

GPIO34到39是GPIs–仅输入的管脚。这些引脚没有内部上拉或下拉电阻。它们不能用作输出,因此只能将这些管脚用作输入,且适合用来作为摄像头数据的输入线D0-D7:

GPIO 34
GPIO 35
GPIO 36
GPIO 37
GPIO 38
GPIO 39

ESP32只有两个I2S,摄像头应用也需要I2S0,我的I2S0用于ES8388播放声音,I2S1用于从外部录入声音,所以就需要切换I2S0使用。

2.节约io pwdn reset 禁用

pwdn引脚需下拉
reset引脚需上拉
在这里插入图片描述

使用外部20M有源晶振作为XCLK的时钟
在这里插入图片描述
L13电感阻值不可太小,需100R左右

3.vsync需使能两次

不知是不是idf内部bug 有时候i2s_start_bus需要使能两次vsync中断才可以
在这里插入图片描述


三、 I2S0切换使用ES8388和摄像头

正常开机的时候只需要用到ES8388来播放声音,这个时候8388占用了I2S0,当识别到命令词需要用到摄像头的时候就需要初始化I2S0给摄像头使用,
1、播放器逆初始化 esp_audio_destroy(player);
2、初始化摄像头 init_camera();
3、获取图像 esp_camera_fb_get();
4、逆初始化摄像头 esp_camera_deinit();
5、初始化codec

audio_hal_ctrl_codec(board_handle->audio_hal,AUDIO_HAL_CODEC_MODE_DECODE, AUDIO_HAL_CTRL_START);

6、初始化播放器和i2s

	esp_audio_cfg_t cfg = DEFAULT_ESP_AUDIO_CONFIG();
	cfg.vol_handle = board_handle->audio_hal;
	cfg.vol_set = (audio_volume_set)audio_hal_set_volume;
	cfg.vol_get = (audio_volume_get)audio_hal_get_volume;
	cfg.prefer_type = ESP_AUDIO_PREFER_MEM;
	cfg.resample_rate = 44100;
	cfg.cb_func = esp_audio_play_callback;

	player = esp_audio_create(&cfg);
	if (player == NULL)
	{
		ESP_LOGE(TAG, "esp audio handle create err");
	}
	else
	{
		ESP_LOGI(TAG, "esp audio_handle create right");
	}
	esp_audio_vol_set(player, roobo_audio_volume);


	http_stream_cfg_t http_cfg = HTTP_STREAM_CFG_DEFAULT();
	http_cfg.task_core = 1;
	http_cfg.task_prio = 6;
	http_cfg.type = AUDIO_STREAM_READER;
	http_cfg.enable_playlist_parser = true;
	http_reader = http_stream_init(&http_cfg);
	esp_audio_input_stream_add(player, http_reader);

	a2dp_stream_config_t a2dp_config = {
		.type = AUDIO_STREAM_READER,
		.user_callback.user_a2d_cb = user_a2dp_sink_cb,
	};
	audio_element_handle_t bt_stream_reader = a2dp_stream_init(&a2dp_config);
	esp_audio_input_stream_add(player, bt_stream_reader);

	aac_decoder_cfg_t aac_dec_cfg = DEFAULT_AAC_DECODER_CONFIG();
	aac_dec_cfg.task_core = 1;
	aac_dec_cfg.task_prio = 6;
	aac_decoder = aac_decoder_init(&aac_dec_cfg);
	esp_audio_codec_lib_add(player, AUDIO_CODEC_TYPE_DECODER, aac_decoder);

	mp3_decoder_cfg_t mp3_dec_cfg = DEFAULT_MP3_DECODER_CONFIG();

	mp3_dec_cfg.task_core = 1;
	mp3_dec_cfg.task_prio = 6;
	mp3_decoder = mp3_decoder_init(&mp3_dec_cfg);
	esp_audio_codec_lib_add(player, AUDIO_CODEC_TYPE_DECODER, mp3_decoder);
	ESP_LOGE(TAG, "net_audio_i2s_writer_init enter");

	i2s_stream_cfg_t i2s_cfg = I2S_STREAM_CFG_DEFAULT();
	i2s_cfg.task_core = 1;
	i2s_cfg.task_prio = 6;
	i2s_cfg.type = AUDIO_STREAM_WRITER;
	i2s_cfg.i2s_config.mode = I2S_MODE_MASTER | I2S_MODE_TX;
	i2s_cfg.i2s_config.sample_rate = 44100;

	printf("net_audio_i2s_writer_init1 MEM Total:%d Bytes, Inter:%d Bytes, Dram:%d Bytes\n", esp_get_free_heap_size(), heap_caps_get_free_size(MALLOC_CAP_INTERNAL), heap_caps_get_free_size(MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT));
	i2s_writer = i2s_stream_init(&i2s_cfg);
	printf("net_audio_i2s_writer_init2 MEM Total:%d Bytes, Inter:%d Bytes, Dram:%d Bytes\n", esp_get_free_heap_size(), heap_caps_get_free_size(MALLOC_CAP_INTERNAL), heap_caps_get_free_size(MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT));
	esp_audio_output_stream_add(player, i2s_writer);
	ESP_LOGE(TAG, "net_audio_i2s_writer_init exit");
  • 不可逆初始化board 概率性空指针 audio_board_deinit(board_handle);
  • board_handle = audio_board_init(); 只可执行一次
  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值