【问题标题】:ESP8266 analogRead() microphone Input into playable audioESP8266 analogRead() 麦克风输入可播放音频
【发布时间】:2023-01-10 03:20:53
【问题描述】:

我的目标是使用连接到 esp8266 (12E) 模拟引脚的驻极体麦克风录制音频,然后能够在另一台设备上播放该音频。我的电路是: 为了检查麦克风的输出,我将电路连接到示波器并得到:

在上面的“gif”中,您可以看到我对着麦克风说话时声音发出的波浪。 这是我在 esp8266 上的代码:

void loop() {
  sensorValue = analogRead(sensorPin);
  Serial.print(sensorValue);
  Serial.print(" ");
}

我想在“Audacity”软件上播放音频以了解结果。因此,我从串行监视器复制了数字并将其粘贴到将数据映射到 (-1,1) 区间的 python 代码中:

def mapPoint(value, currentMin, currentMax, targetMin, targetMax):
    currentInterval = currentMax - currentMin
    targetInterval = targetMax - targetMin

    valueScaled = float(value - currentMin) / float(currentInterval)

    return round(targetMin + (valueScaled * targetInterval),5)

class mapper():
    def __init__(self,raws):
        self.raws=raws.split(" ")
        self.raws=[float(i) for i in self.raws]

    def mapAll(self):
        self.mappeds=[mapPoint(i,min(self.raws),max(self.raws),-1,1) for i in self.raws ]
        self.strmappeds=str(self.mappeds).replace(",","").replace("]","").replace("[","")
        return self.strmappeds

它采用数字字符串,将它们映射到目标区间 (-1 ,+1) 并返回以空格 (" ") 分隔的数据字符串,准备导入 Audacity 软件。 (Tools>Sample Data Import 然后选择包含数据的文本文件)。将近5秒的语音导入数据的结果:

大约半秒钟,当我演奏时,我听到难以理解的噪音。我也尝试了较低的频率,但那里也只有噪音。

问题的可疑原因是:

1- Esp8266 无法足够快地读取模拟引脚以返回有意义的数据(这可能不是这种情况,因为它的时钟速度约为 100MHz)。

2- 软件收集数据和输出数据的方式不是最优化的方式(在循环中,Serial.print 等)

3-麦​​克风电路输出太吵。 (这可能是,但从示波器测试中观察到,我的声音必须对输出音频产生影响。这在大胆的情况下是听不到的)

4- 我为 Audacity 映射和准备数据的方式。

  • 还有什么我可以尝试的吗?
  • 那里有类似的项目吗? (令我惊讶的是,我找不到任何透明完成的东西!)
  • 执行此操作的正确方法是什么? (因为它是一种非常有用且经济的录音、传输和分析音频的方法。)

【问题讨论】:

  • 这可能与 Electronics 更相关,因为问题不是完全编程。分解你的问题清单。 1. 100MHz应该足够快,但要记住你在草图中做的任何其他事情。微型蟒蛇可能对于这种工作来说有点太慢了。 2. 串行通信对于音频而言不是最佳选择,您将受到波特率的限制。通常,音频接口至少是双缓冲的,因此当设备填充一个内存空间时,连接的机器会读取另一个内存空间。
  • 从技术上讲,您需要 2 个 ESP 才能实现这一目标。一个循环写入一些外部存储器,另一个发送数据。3.输入将非常嘈杂。它不太可能是一个宽容的麦克风,但你应该能够得到一些可以理解的东西。你只是不会很快赢得格莱美奖。4.也许,您需要确保您正在编写原始字节。 ESP8266 ADC 引脚只有 10 位分辨率。您将浪费大量周期转换为 32 位浮点数并缩放为 -1.0f1.0f
  • 如果你想录制,然后回放,你可以离线做很多这样的事情。您只需要将数据保存到一些内存中,稍后再读回即可。然后,您可以执行任何需要的后期处理,将原始字节缩放到合适的音频范围。 10 位不是标准,因此您可以扩展到 16 位并保持分辨率,或者缩小到 8 位以节省空间。 16 位可能最有意义
  • 您现在遇到了数据存储问题。 SD 卡速度很慢,因此如果没有双缓冲(即 x2 ESP 和共享内存),您将在音频信号中出现不连续性。您可以写入 FRAM。您将需要大约 512KB 的 FRAM 来播放约 5 秒的音频。然后您需要编写 2 个程序或编写一些功能1个将信号记录到 RAM2个例如,按下按钮停止录制并开始将 RAM 的内容转储到 SD 卡或通过串行连接。
  • 许多现代音频设备(如智能手机上的麦克风)不会像使用 ESP 模拟芯片那样读取 PCM 数据,而是使用某种 sigma delta modulator converter 电路。确保您的期望不会太离谱,这样您就不会对最终结果感到失望

标签: audio arduino esp8266 microphone adc


【解决方案1】:

你的项目有很多问题:

您没有在 A0 上设置偏置电压。 ADC 只能测量接地和 VCC 之间的电压。当从电路中移除麦克风时,A0 处的电压应接近 VCC/2。这通常是通过在 VCC 和 GND 之间添加一个分压器来实现的,该分压器由 2 个电阻组成,并直接连接到 A0。在上限和 A0 之间。

您没有调整输入速度,这意味着您没有恒定的采样率。这是一个非常重要的问题。我建议您为自己设定一个切合实际的目标,该目标完全在 ADC 和串行端口的限制范围内。串行端口的传输速率(以字节/秒为单位)通常等于波特率/8。对于 9600 波特,这大约只有 1200 字节/秒,这意味着一旦转换为文本,您最多转移速率下降到每秒约 400 个样本。需要解决此问题并计算最大值你开始,因为最大可达到的采样率是来自 ADC 的采样率和串行端口的传输率的最大值。

获取样本的方式在很大程度上取决于您的需求和您尝试对这个项目做什么,您对应用程序的音频带宽、分辨率和音频质量要求以及您可以投入的工作量。像现在一样从循环中读取可能使用足够快的串行端口,但质量总是很差。

通常完成的方法是使用定时器中断启动 ADC 测量,ADC 中断获取结果并将其存储在 FIFO 中,而主循环从这个 ADC fifo 传输到串行端口,以及分配给芯片。这不能直接使用 Arduino 库来完成,因为您需要直接控制 ADC 才能做到这一点。

这是要做的事情的简短清单:

  1. 从 Expressif 获取完整的 ESP8266 数据表。查看 DAC 的实际规格,主要是:振荡器可用的采样率和分辨率,以及它的电气限制,至少是它的输入电压范围和输入阻抗。
  2. 知道这些数字后,为自己设定一些目标,成功项目所需的数学需要输入数字。你的应用是什么?您想录制音频还是只检测难以形容的噪音?什么是最低限度工作所需的要求?
  3. 在 Arduino 文档中查找有关如何设置定时器中断和 ADC 中断的内容。
  4. 在数据表中查找您需要访问哪些寄存器来配置和运行 ADC。
  5. 修复了 ADC 输入上的电压偏置问​​题。在此之前什么都不能工作,而且您不想毁坏您的处理器。
  6. 确保输入交流电压(“摆动”电压)足够大,可以提供您想要的结果。仅仅为了阻抗匹配而不得不放大麦克风信号(使用运算放大器或晶体管)的情况并不少见。
  7. 然后就可以开始写代码了。

    对于这么小的任务来说,这听起来可能非常复杂,但这就是嵌入式程序员的日常工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-01-01
    • 2018-06-18
    • 2014-10-21
    • 2018-02-14
    • 2019-09-25
    • 2022-01-05
    • 2016-10-13
    相关资源
    最近更新 更多