关于使用MSGEQ7音频频谱分析仪芯片的所有您想知道(但又害怕问到)的信息。
多年来,我已经在几栏中讨论过使用MSGEQ7频谱分析仪芯片的问题,但是我仍然收到问题,因此我认为将所有相关信息集中到一个位置可能是个好主意。
音频响应项目
首先,让我们进行场景设置。假设我们想创建一些对声音有反应的东西,例如我当前的Audio-Reactive Box项目。您可能还记得,这涉及到一个装有假真空管的小假古董手提箱。这些灯管将使用三色LED聚宝盆从下面照亮。下图反映了刚安装完电子管后盒子的状态-下一步是在电子设备上工作(我将在以后的专栏中进行讨论)。
如果我们希望我们的项目(在这种情况下为盒子)对外部声音做出反应,那么我们将需要一个麦克风。此类项目的一个很好的解决方案是MEMS驻极体麦克风(一种基于静电电容的麦克风),并在分线板(BOB)上配有一个小型放大器。
选项1:将音频输入到MCU中(不进行FFT)
一种选择是将麦克风BOB的输出直接输入到微控制器(MCU)上的模拟输入。对于我的大多数项目,我喜欢使用廉价而快乐的Arduino Nano,Uno或Mega MCU开发板。尽管这些在性能上都受到一些限制(8位数据总线,16MHz时钟,各种内存以及不同数量的输入/输出引脚),但我真的很喜欢这些小技巧。
将音频信号直接馈送到MCU(来源:Max Maxfield)
观察到我已经显示了七个从MCU发出的LED(或LED串)。实际上,由于我们将要使用基于WS2812的NeoPixels,它们可以菊花链连接在一起并且可以单独控制,因此我们可以用单个引脚驱动所有LED,但是显示7串字符串将使事情变得更加清晰。
理想情况下,对于此设置,麦克风BOB的输出应具有2.5V的DC偏置和5V的pp(峰峰值)摆幅,这与Arduino Nano / Uno / Mega的电源匹配(一个选项这是来自Adafruit的具有可调增益的MAX4466)。Arduino使用10位模数转换器(ADC)。这意味着当我们对音频信号执行AnalogRead()函数时,Arduino会将0至5V之间的输入电压映射为0至1023之间的整数值。
现在,您可能在想,由于我们的LED要求控制值的范围是0到255,所以这意味着我们需要将ADC的0到1023的值映射到LED的0到255的等效值,但是还不止这些这很复杂。假设我们从5Vpp正弦波开始,如下图(a)所示:
处理正弦波(来源:Max Maxfield)
在这种情况下,如果我们在一定数量的读数上对样本取平均值,则最终的平均值为511。问题是,如果我们要对4Vpp信号中的多个样本取平均值,我们将获得相同的511值。一个3Vpp信号,或者…您明白了。
因此,我们需要做的第一件事就是校正信号,如上面的(b)所示。我们可以使用一个简单的公式来做到这一点,如下所示:如果数字样本的值等于或大于512,我们将其保持原样。如果它的值为511或更低,则将其从1,023中减去。接下来,我们需要消除直流偏置,这是通过从每个值中减去511来实现的,如上面的(c)所示。
最后,我们需要将0到511的值映射到LED所需的0到255的值,如上面的(d)所示。我们可以使用Arduino的map()函数来实现这一点。另外,我们可以简单地将0到511的值除以2,或者将它们向右移一位,这两者将具有相同的效果。(如果BOB的输出具有不同的DC偏置和/或较小的pp摆幅-例如1.25V的DC偏置和2Vpp摆幅,则可以在软件中适当地重新缩放/预处理信号。)
使用上述基本设置,每次采样时,我们可以从音频信号中收集到的唯一信息就是其当前幅度。关于驱动我们的LED,我们可以利用这些信息做几件事。例如,我们可以用相同的颜色驱动所有LED,同时根据音频信号的幅度改变它们的强度。或者,我们可以将所有LED完全驱动,同时根据音频信号的幅度改变它们的颜色。而且,当然,我们可以结合使用这些技术。
记住我们正在设想七串(组)LED,另一种可能性是将音频信号分成七个“振幅带”。每次采样信号时,我们都会决定要点亮哪些LED。如果信号落入最低振幅带,我们可以简单地点亮第一串LED。如果信号落入下一个振幅带,我们可以仅驱动第二串LED,或者我们可以决定同时驱动第一串和第二串LED。依此类推,直到信号落入最高振幅带,此时我们只能驱动第七串LED,或者我们可以决定驱动所有的LED。而且,当然,我们还可以尝试各种琴弦的振幅和颜色。
选项2:使用FFT软件将音频输入到MCU中
如果我们决定将音频信号分成单独的频段,事情将变得越来越有趣。例如,在这种情况下,我们可以使用底鼓的节拍来控制一组LED,而另一组可以响应较高的频率,例如一分钱的汽笛声。
尽管随着年龄的增长,我们听到较高频率的能力会下降,但是人类的正常听力范围会覆盖20到20,000Hz之间的频率。假设我们将0到20,000Hz的范围分成以63Hz,160Hz,400Hz,1,000Hz,2,500Hz,6,250Hz和16,000Hz为中心的七个重叠频段,如下所示:
将音频信号划分为七个频段(来源:Max Maxfield)
在这种情况下,我们可以使用七个频带的幅度来控制七组LED的强度和/或颜色,但是如何从麦克风BOB的音频信号中提取该频带信息呢?
不错,一种选择是使用在MCU上运行的软件算法来实现FFT(快速傅立叶变换)功能。此功能可用于将我们的信号从其原始时域形式转换为频域中的相应表示形式。
将音频信号直接馈送到运行SW FFT的MCU(来源:Max Maxfield)
软件(SW)FFT可能需要计算,但是如果您真的想走这条路,可以使用许多Arduino FFT库(有关更多信息,请参见Adafruit的Piccolo Music Visualizer项目)。
说实话,如果我想使用软件FFT的,我可能会使用一个32位Teensy 3.2(72MHz的的Cortex-M4型)或Teensy 3.6(基于的Cortex-M4F-180MHz的)单片机开发板从PJRC,以及出色的音频FFT库。但是,我个人更喜欢使用硬件(HW)FFT替代方案,如下所述。
选项#3:通过MSGEQ7音频频谱分析仪提供音频
让我们从建议的系统的高级视图开始。在这种情况下,来自麦克风BOB的输出被馈入一个名为MSGEQ7的漂亮的8针小芯片,该芯片由一家名为Mixed Signal Integration的公司创建。该音频频谱分析仪芯片可与3.3V和5V MCU配合使用,将音频信号划分为前面讨论的七个频段,并以一种易于我们的MCU轻松访问的形式显示与这些频段相关的幅度数据。稍后)。
通过MSGEQ7硬件FFT馈送音频信号(来源:Max Maxfield)
这种方法的最好之处在于,它可以消除您(和您的MCU)的所有辛苦工作。您要做的就是从MSGEQ7访问频带幅度数据,然后决定如何使用它来驱动LED。
非常重要:该MSGEQ7数据表是不是很有益,因为人们可能希望,但它意味着该装置预计有0.3Vpp(即300mVpp)摆动的音频输入。这意味着您必须相应地选择麦克风。我将在以后的专栏中讨论不同的麦克风替代品。就目前而言,我只是注意到我的好友史蒂夫·曼利(Steve Manley)已成功将MSGEQ7与来自SparkFun的男生和女歌手的INMP401 MEMS麦克风BOB配合使用(该视频的链接在本专栏的稍后部分将展示史蒂夫的解决方案)。据说该BOB“在话筒保持臂长并以正常的对话音量进行通话时,具有约200mV的峰峰值输出。”
介绍MSGEQ7
因此,我们来介绍一下MSGEQ7本身。通孔(LTH)和表面贴装技术(SMT)封装都提供这种小流氓。LTH版本可从SparkFun获得,价格仅为4.95美元(也提供MSGEQ7 BOB;我们将在短期内返回这些内容)
8针MSGEQ7频谱分析仪芯片和引脚排列(来源:Max Maxfield)
观察到只有一个DATA_OUT信号,那么我们如何使用它来访问与七个频段关联的数据?为了回答这个问题,我们需要考虑一下MSGEQ7内部的框图,如下所示:
MSGEQ7框图(来源:Max Maxfield)
这种工作方式是,我们使用来自MCU的两个数字输出来驱动RESET和STROBE信号,并且使用MCU上的模拟输入来从DATA_OUT信号中读取值。首先,我们在RESET信号上使用一个正向脉冲来告知MSGEQ7,我们正在准备访问其数据,然后在STROBE信号上使用一系列的七个负向脉冲来读取与这七个频率相关的数据乐队。此数据表示为0V至5V之间的模拟电压(对于3.3V供电的MCU /系统,则为0V至3.3V),如果是Arduino及其10位ADC,则将转换为0到1023之间的整数值。
MSGEQ7时序图(来源:Max Maxfield)
当然,我们会反复进行此操作,从MSGEQ7读取数据,然后使用此数据来决定我们希望如何驱动LED。下面是一个示例Arduino函数,用于访问此数据并将其存储在7个元素的整数数组中,这些整数称为bands []:
观察到我并没有费心在两个对RESET信号进行脉冲的digitalWrite()语句之间添加延迟,因为它被指定为最小值为100ns(0.1us),该最小值很小,以至于它被固有的延迟所淹没。函数调用自己。
MSGEQ7电路图和分支电路板
如果计划使用单个MSGEQ7处理单个(单声道)音频流,则要使用的电路图如下所示:
具有单声道输入的单个MSGEQ7(来源:Max Maxfield)
观察到C2显示为0.1uF(该电容器可消除输入音频信号中的任何DC偏置)。官方MSGEQ7数据手册中的等效电容器显示为0.01uF,但这是不正确的。
如果您希望使用单个MSGEQ7来处理双(立体声)音频流,则可以通过添加一个额外的22KΩ电阻来修改上图的输入,如下所示:
支持立体声输入的单个MSGEQ7(来源:Max Maxfield)
与自己进行接线相反,您可以从eBay购买MSGEQ7 BOB。售价$ 15.95加上运费,这虽然有点贵,但这确实意味着您可以实地工作。需要注意的一点是,默认情况下,它将附带5针接头连接器和立体声插孔。如果您愿意,卖方将保留这些附件,但您下订单时必须要求。
正如您在本视频中看到的那样,在Cunning Chronograph中实现音乐模式时,我使用了一个带有双输入的MSGEQ7。
在这种情况下,与使用麦克风不同,我直接从iPod的耳塞/耳机插孔中喂入了MSGEQ7。相比之下,正如您在本视频中看到的那样,我的好友史蒂夫·曼利(Steve Manley)使用我们之前简要提到的SparkFun的INMP401 MEMS麦克风BOB在他的狡猾计时码表中驾驶了MSGEQ7。
当然,对于某些事情(例如我的BADASS显示器),您想要实现真正的立体声功能。在这种情况下,您可以使用两个MSGEQ7芯片来处理左右声道的音频流(您可以使用MCU的单个输出来驱动两个MSGEQ7上的RESET引脚;类似地,您可以使用单个输出来驱动STROBE引脚)。
通过观看BADASS显示器早期原型的视频,您可以更好地了解所有这些工作原理。