Arduino 是一个原型平台,由许多硬件板和一个软件抽象层组成。对于这样的问题,考虑底层硬件的功能很有用,因为它们提供了最终限制。我假设您使用的是 Arduino Uno/Nano,Due 的情况有所不同。
根据数据表,每个 ADC 读数(除了第一个)需要 13 个 ADC 时钟周期。ADC 时钟(不同于 MCU)时钟是通过将系统时钟除以某个因子(至少为 2)得出的。因此,在 16Mhz 板上,这相当于每秒 60 万个样本。到目前为止,一切都很好。然而,事情还没有结束,您仍然需要读取数据。如果你使用中断,即使你做一些非常简单的事情,经验表明你会损失大约 100 个时钟来中断处理。现在您的采样率降至 126K 样本/秒。但这是理论上的最大值。
数据表指出,要获得 ADC 的最大精度,需要 50kHz - 200kHz ADC 时钟。在 Arduino 代码 (in wiring.c
) 中,选择了 128 的除法因子:
sbi(ADCSRA, ADPS2);
sbi(ADCSRA, ADPS1);
sbi(ADCSRA, ADPS0);
这意味着每次转换需要 128*13 = 1764 个时钟,理论上每秒最多产生 10K 个样本。考虑到该readAnalog()
函数所做的不仅仅是启动 ADC 转换并等待它完成,这比这要差一些,但应该不会差太多。这当然不涉及您的代码:您对结果进行的任何处理readAnalog()
都会使捕获更多样本变得更加困难。但是,是的,要以 4Khz 捕获,您需要确保您的代码花费少于 1.5k 时钟周期/样本,这应该是可行的。请注意,如果您像在发布的代码中那样进行五次读取,如果您的代码执行的代码很少,则最大捕获速率将为 2kHz。
至于如何捕获数据,您需要处理这样一个事实,即没有放大的麦克风不会为您提供 0-5V 读数,如果您使用analogRead()
. 事实上,麦克风输出电压从正向负摆动,但是,负电压不会被 ADC 拾取,并且仅显示为零,除非您给麦克风提供电压偏移。
我不确定您将最小幅度与最大幅度进行比较的代码应该做什么。您想将音频数字化吗?在这种情况下,您需要保存从 收集的所有幅度读数analogRead()
,然后您可以在另一台计算机上对它们运行 FFT:Arduino 很可能不够快,无法对数据进行频率分析。