【问题标题】:Syncing of buffer-transmission with ESP32, I2S MEMS-mic and SD-card (FreeRTOS, PlatformIO, ESP-PROG)与 ESP32、I2S MEMS-mic 和 SD 卡(FreeRTOS、PlatformIO、ESP-PROG)同步缓冲传输
【发布时间】:2021-02-04 09:56:23
【问题描述】:

我知道这个论坛不喜欢这样的“开放式”问题,但我希望有人能帮我解开我的心结,非常感谢。

目标很简单:

  • 从 2 个 adafruit sph0645 麦克风读取立体声 32 位 44100 S/s I2S 信号
  • 创建一个 wav-header 并将数据存储到 SD 卡上

我已经在这里工作了几天,我知道这将比我最初想象的要复杂得多。主要原因:信号质量。像大多数关于这个主题的教程一样,这些麦克风最简单的“hello world”是对 I2S 样本的循环轮询。轮询、填充缓冲区、通过串行输出或写入 SD 卡。这会返回一个断断续续、嘈杂、加速的 RL 音频版本。内部 DMA 缓冲区的填充可以看作是恒定的,但其余大部分是混乱的,所以

如何将这些 DMA 缓冲区与我的其余代码同步?

根据 STM32 HAL 的经验,我想一些寄存器可以设置为在缓冲区满时引发中断,或者可以通过队列在任务之间发送事件。关于这个主题的例子要么在一个主循环中轮询单声道一个糟糕的采样率和位深度,要么使用过度杀伤代码的页面并且从不解决它的作用,“只需复制它就可以工作”,不好。 ESP32-Arduino 框架是否提供了一些正确的方法? espressif 文档并不值得期待,因为它们的一些 I2S 接口函数甚至不起作用(如果您也在研究这个主题,您也可能已经注意到 i2s_read 只返回零)。只是对正确方向的提示会有所帮助,无论如何我正在编写自己的代码。中断?事件?计时器?轮询完整缓冲区?只有你可能知道。

祝你好运,谢谢

【问题讨论】:

  • 请发布您拥有的代码。另外请注意,虽然 ESP IDF 文档可能并不完美,但其源代码是 available

标签: sd-card esp32 i2s


【解决方案1】:

感谢https://github.com/atomic14/,我现在有了一个运行良好的同步方法的答案。 https://esp32.com/viewtopic.php?t=12546 已经尝试过这种方法,他也没有完全理解发生了什么:espressif i2s-interface 提供了一个存储在事件中的标志,该标志每次 one 指定的 dma 时都会触发-buffers 收到了全套数据,ergo,已经满了。它看起来像这样:

while(<your condition>){

i2s_event_t evt;
if (xQueueReceive(<your queue>, &evt, portMAX_DELAY) == pdPASS){
  if (evt.type == I2S_EVENT_RX_DONE){
    size_t bytesRead = 0;
    do{

      //read data via i2s_read or i2s_read_bytes


    } while (bytesRead > 0);

此队列中没有存储数据,而是一个标志,可用于同步 dma 填充和进一步缓冲/计算/发送读取的数据。

但是这仅在您在特定设置中安装 i2s 驱动程序时才有效。而不是使用

i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL);

在您的设置中,您可以通过传递队列句柄和长度来激活事件的“关联性”:

i2s_driver_install(I2S_NUM_0, &i2s_config, 4, &<your queue>);

希望这有助于入门,它确实对我有所帮助。

【讨论】:

    猜你喜欢
    • 2022-07-22
    • 2021-11-23
    • 2023-03-03
    • 2022-07-04
    • 2011-05-01
    • 1970-01-01
    • 2019-02-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多