前言

这期作品是通过 Arduino 和四块LED点阵模块,实现32分频的音频频谱可视化显示,让LED随音乐跳动!

主要特点

1、使用简易安装的库 ArduinoFFT 和 MD_MAX72xx。2、支持五种不同的显示模式,可通过按钮切换。3、音频信号的左右声道都是混合的,不会错过节拍。4、使用 32×8 LED 点阵,可以随意改变。5、音频可以从耳机输入或播放设备的Line-Out输入。

材料

Arduino Nano × 1电阻10k欧 × 1电阻4.75k欧 × 3电容100nF × 2电阻100K欧 × 2轻触开关12mm × 1LED显示器32X8 × 15V电源(用于USB供电) × 1

步骤

流程图

原理图

系统原理描述

Arduino 内置数模转换器(ADC),可以将输入音频信号转换为数字样本。ADC 设置为38.46kHz的输入信号。

为了显示音频信号的频谱,左右两个声道混合并反馈到 ADC 的 A0 口,如果有必要,也可以使用一分为二的音频线将信号同时输送到频谱分析仪和另一个放大器上。

在这个作品中,ADC使用Arduino 的 3.3V 电源。当模拟信号在零电压附近震荡时,则需要在 ADC 的模拟输入端配置一个直流偏置,确保 ADC 输出不会截断输入信号的负周期。3.3V稳定电压由两个电阻 R1 和 R2 分压,然后反馈到模拟输入以进行直流偏置。使用此直流偏置,即使输入信号断开,ADC 也会在输出中产生 512 。稍后在代码中这个 512 将由 DC 偏置抹掉,从而读数代表实际的输入信号的变化。

ArduinoFFT 库的作用是将模拟信号转换为频谱,易于使用,输出准确。 该例子生成 64 个样本并进行 FFT ,而ArduinoFFT 库可以对 16 到 128 之间的样本进行 FFT ,根据需求在程序中配置。但ArduinoFFT库对 128 个样本的计算速度很慢,因此建议最高值为64个,效果最好。

该作品使用32×8点阵LED。MD_MAX72xx 库可以轻松控制LED点阵的显示。该库提供打开/关闭该程序中正在使用的任意数量的 LED 功能。每个频带的幅度被映射在 0 到 8 之间,具体多少则取决于每列 LED 接通的数量。

提供的程序中包含五种显示模式(可以按照需求修改或创建不同模式),该作品通过按钮来切换不同模式。

频率响应

实验证明系统能够响应高达18.6Khz 的频率。

连接输入

你可以通过多种方式将音频输入到频谱显示仪。你可以从音乐播放器/功放的 Line-Out 输入。其他选项是从手机/音乐系统的耳机输出获取音频。我不建议使用另一个麦克风接收音频,因为信号水平和频率响应将包含许多的因素。

以下是将音乐播放器/功放连接到频谱显示仪的示例图。

以下是将手机的耳机输出连接到频谱显示仪的示例图。

将电缆连接到耳机输出时,手机/音乐系统不会出声。如果你想听到音频并可显示,你必须分离音频并使用另一个功放。

代码

#include #include #include  #define SAMPLES 64            //Must be a power of 2#define HARDWARE_TYPE MD_MAX72XX::FC16_HW   // Set display type  so that  MD_MAX72xx library treets it properly#define MAX_DEVICES  4   // Total number display modules#define CLK_PIN   13  // Clock pin to communicate with display#define DATA_PIN  11  // Data pin to communicate with display#define CS_PIN    10  // Control pin to communicate with display#define  xres 32      // Total number of  columns in the display, must be <= SAMPLES/2#define  yres 8       // Total number of  rows in the display int MY_ARRAY[]={0, 128, 192, 224, 240, 248, 252, 254, 255}; // default = standard patternint MY_MODE_1[]={0, 128, 192, 224, 240, 248, 252, 254, 255}; // standard patternint MY_MODE_2[]={0, 128, 64, 32, 16, 8, 4, 2, 1}; // only peak patternint MY_MODE_3[]={0, 128, 192, 160, 144, 136, 132, 130, 129}; // only peak +  bottom pointint MY_MODE_4[]={0, 128, 192, 160, 208, 232, 244, 250, 253}; // one gap in the top , 3rd light onwardsint MY_MODE_5[]={0, 1, 3, 7, 15, 31, 63, 127, 255}; // standard pattern, mirrored vertically  double vReal[SAMPLES];double vImag[SAMPLES];char data_avgs[xres]; int yvalue;int displaycolumn , displayvalue;int peaks[xres];const int buttonPin = 5;    // the number of the pushbutton pinint state = HIGH;             // the current reading from the input pinint previousState = LOW;   // the previous reading from the input pinint displaymode = 1;unsigned long lastDebounceTime = 0;  // the last time the output pin was toggledunsigned long debounceDelay = 50;    // the debounce time; increase if the output flickers MD_MAX72XX mx = MD_MAX72XX(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);   // display objectarduinoFFT FFT = arduinoFFT();                                    // FFT object void setup() {    ADCSRA = 0b11100101;      // set ADC to free running mode and set pre-scalar to 32 (0xe5)    ADMUX = 0b00000000;       // use pin A0 and external voltage reference    pinMode(buttonPin, INPUT);    mx.begin();           // initialize display    delay(50);            // wait to get reference voltage stabilized}  void loop() {   // ++ Sampling   for(int i=0; i    {      while(!(ADCSRA & 0x10));        // wait for ADC to complete current conversion ie ADIF bit set      ADCSRA = 0b11110101 ;               // clear ADIF bit so that ADC can do next operation (0xf5)      int value = ADC - 512 ;                 // Read from ADC and subtract DC offset caused value      vReal[i]= value/8;                      // Copy to bins after compressing      vImag[i] = 0;                             }    // -- Sampling     // ++ FFT    FFT.Windowing(vReal, SAMPLES, FFT_WIN_TYP_HAMMING, FFT_FORWARD);    FFT.Compute(vReal, vImag, SAMPLES, FFT_FORWARD);    FFT.ComplexToMagnitude(vReal, vImag, SAMPLES);    // -- FFT         // ++ re-arrange FFT result to match with no. of columns on display ( xres )    int step = (SAMPLES/2)/xres;     int c=0;    for(int i=0; i2); i+=step)      {      data_avgs = 0;      for (int k=0 ; k< step ; k++) {          data_avgs = data_avgs + vReal[i+k];      }      data_avgs = data_avgs/step;       c++;    }    // -- re-arrange FFT result to match with no. of columns on display ( xres )         // ++ send to display according measured value     for(int i=0; i    {      data_avgs[i] = constrain(data_avgs[i],0,80);            // set max & min values for buckets      data_avgs[i] = map(data_avgs[i], 0, 80, 0, yres);        // remap averaged values to yres      yvalue=data_avgs[i];       peaks[i] = peaks[i]-1;    // decay by one light      if (yvalue > peaks[i])           peaks[i] = yvalue ;      yvalue = peaks[i];          displayvalue=MY_ARRAY[yvalue];      displaycolumn=31-i;      mx.setColumn(displaycolumn, displayvalue);              // for left to right     }     // -- send to display according measured value           displayModeChange ();         // check if button pressed to change display mode}  void displayModeChange() {  int reading = digitalRead(buttonPin);  if (reading == HIGH && previousState == LOW && millis() - lastDebounceTime > debounceDelay) // works only when pressed  {   switch (displaymode) {    case 1:    //       move from mode 1 to 2      displaymode = 2;      for (int i=0 ; i<=8 ; i++ ) {        MY_ARRAY[i]=MY_MODE_2[i];      }      break;    case 2:    //       move from mode 2 to 3      displaymode = 3;      for (int i=0 ; i<=8 ; i++ ) {        MY_ARRAY[i]=MY_MODE_3[i];      }      break;    case 3:    //     move from mode 3 to 4      displaymode = 4;      for (int i=0 ; i<=8 ; i++ ) {        MY_ARRAY[i]=MY_MODE_4[i];      }      break;    case 4:    //     move from mode 4 to 5      displaymode = 5;      for (int i=0 ; i<=8 ; i++ ) {        MY_ARRAY[i]=MY_MODE_5[i];      }      break;    case 5:    //      move from mode 5 to 1      displaymode = 1;            for (int i=0 ; i<=8 ; i++ ) {        MY_ARRAY[i]=MY_MODE_1[i];      }      break;  }     lastDebounceTime = millis();  }  previousState = reading;}

MAKER:Shajeeb/译:趣无尽 Cherry

arduino点阵声音频谱_创客实战 | 制作一个随音乐跳动的32分频音频频谱显示器相关推荐

  1. arduino点阵声音频谱_音频跳动:制造32分频音频频谱点阵

    MAKER:Shajeeb/ 译:趣无尽 该项目通过 Arduino 和四块点阵屏,实现32分频的音频(音乐)频谱可视化显示. 这里用了大量篇幅对其原理做了解释(初学者理解起来开可能稍有难度),并且提 ...

  2. arduino点阵声音频谱_Arduino实现32分频音频频谱显示器

    MAKER:Shajeeb/译:趣无尽 Cherry(转载请注明出处) 该项目通过 Arduino 和四块点阵屏,实现32分频的音频(音乐)频谱可视化显示. 这里用了大量篇幅对其原理做了解释(初学者理 ...

  3. arduino点阵声音频谱_参赛-使用Arduino制作32频段音频(音乐)频谱分析仪

    该项目用于使用Arduino制作32频段音频(音乐)频谱分析仪/可视化器. 硬件组件: Arduino Nano R3× 1 电阻10k欧姆× 1 电阻4.75k欧姆× 3 电容器100 nF× 2 ...

  4. arduino点阵声音频谱_基于Arduino和频谱分析的LED音乐课节拍器

    摘要: 音乐课上,学习乐器或者唱歌的学生都需要节拍器来练习稳定速度和节奏.而传统的节拍器主要是机械构造,只拥有稳定的速度,发出"嘀嗒嘀嗒"的节拍声.但是,人类最敏锐的感官是视觉,设 ...

  5. python制作解压工具_使用python制作一个解压缩软件

    python实现解压缩的重要模块就是--zipfile,其次是os 安装zipfile模块 首先得安装zipfile模块,打开cmd输入一下命令即可安装 pip install zipfile os是 ...

  6. android socket 简易聊天室 java服务器_利用Socket制作一个简易的Android聊天室

    首先制作一个客户端,界面如下: 使用方法:启动后,首先在登录编辑框输入一个昵称,然后点击登录,上面灰色区域是聊天窗,其中会显示你的登录提示,显示其他人发的消息.在的登录成功后,可以在下面的发送编辑框内 ...

  7. 如何用excel制作xy曲线图_用Excel制作一个简易抽奖小程序,可一次抽取多人

    抽奖程序在很多场合都能派上用场,比如商场开业促销.课堂点名.抽取幸运观众等.我们今天就用Excel来制作一个简单的抽奖小程序,仅做参考. 抽奖小程序是下图这个样子的.我们按一下键盘上的F9键,即可完成 ...

  8. python连连看小游戏_利用Python制作一个连连看小游戏,边学边玩!

    导语 今天我们将制作一个连连看小游戏,让我们愉快地开始吧~ 开发工具 Python版本:3.6.4 相关模块: pygame模块: 以及一些Python自带的模块 环境搭建 安装Python并添加到环 ...

  9. python如何制作一个工程软件_使用python制作一个解压缩软件

    python实现解压缩的重要模块就是--zipfile,其次是os 安装zipfile模块 首先得安装zipfile模块,打开cmd输入一下命令即可安装 pip install zipfile os是 ...

最新文章

  1. 2019年「自然语言处理NLP」的“高光时刻” --- 28篇标志性论文
  2. 未来的数据中心(一)
  3. 进虚拟ftp服务器跳网页,ftp服务器总是自动跳到网页
  4. C++, C#, Java, VB.NET,到底该选择哪一门语言?
  5. mysql 5.6.23 源码包安装报错_Ubuntu 14.10下编译安装MySQL 5.6.23
  6. 两个精彩的比喻:吞吐量和延迟、信号量和互斥锁
  7. 4 月 10 截止 | 南开大学百名青年学科带头人孙宝发课题组招生
  8. Network 第九篇 - 双机热备-HSRP
  9. git init github
  10. 数据挖掘常用的基本技术,主要有哪些?
  11. Qt使用libmodbus
  12. 提高github下载速度的方法
  13. 红警3命令与征服注册激活启动cdkey联机问题
  14. 企业邮箱发送出去的邮件找不到了
  15. Web前端——登录界面hover效果
  16. azure databricks 时区设置
  17. 为什么要做汽车电子检测?国标检测及其目的
  18. PMP项目管理 考试题型,六大解题原则定要牢牢记住!
  19. OpenCV-Python 中文教程10——图像阈值
  20. 分布式锁-Redisson

热门文章

  1. 佳能打印机删掉又会自动加载的原因及解决方案
  2. 转正 自我鉴定 模板
  3. 关于c语言在循环赋值字符时出现乱码情况
  4. [计网:原理与实践] 第五章:端到端协议(课后习题整理)
  5. 浅谈计算机视觉、机器视觉、图像处理
  6. 中秋之夜 一个感人的flash动画小故事
  7. 简单易用的运动控制卡(十一):运动的暂停恢复和速度倍率设置
  8. 电信机顶盒怎么连接鸿蒙系统电视,「天翼高清电视」电信高清机顶盒怎么连接电视 - 鲲鹏装修网...
  9. H5 实现自定义video播放器,快来点我吧
  10. 循环卷积的时域DFT性质推导