21浏览
查看: 21|回复: 2

[项目] 【Arduino 动手做】32 频段 LED 音频频谱分析仪 MAX 7219

[复制链接]
在这里,我向您介绍一个由 Arduino Nano 和 MAX 7219 4x LED 点阵面板制成的 32 频段 LED 音频频谱分析仪。包括 4 种模式,您可以使用按钮在这些模式之间循环。关机内存用于在电源重启时将所选模式保留在内存中。特别感谢“Shajeeb”,他是这个项目的原始制作者。

零件清单
Arduino Nano x 1
MAX 7219 4x LED 点阵 x 1
瞬时按钮 x 1
4.7K 欧姆电阻 x 3
100K 欧姆电阻器 x 1
10K 欧姆电阻器 x 1
1uF 电容器 x 2
3.5mm 立体声母插孔 x 2

【Arduino 动手做】32 频段 LED 音频频谱分析仪 MAX 7219图1

【Arduino 动手做】32 频段 LED 音频频谱分析仪 MAX 7219图2

【Arduino 动手做】32 频段 LED 音频频谱分析仪 MAX 7219图3

【Arduino 动手做】32 频段 LED 音频频谱分析仪 MAX 7219图4

驴友花雕  中级技神
 楼主|

发表于 昨天 16:24

【Arduino 动手做】32 频段 LED 音频频谱分析仪

项目代码

  1. // Copyright (c) 2019 Shajeeb TM
  2. // HAZI TECH
  3. // Updated by Hasitha Jayasundara
  4. // Visit my YouTube Channel - http://www.youtube.com/c/HAZITECH?sub_confirmation=1
  5. #include <arduinoFFT.h>
  6. #include <MD_MAX72xx.h>
  7. #include <SPI.h>
  8. #include <EEPROM.h>
  9. #define SAMPLES 64                                            //Must be a power of 2
  10. #define HARDWARE_TYPE MD_MAX72XX::FC16_HW                     // Set display type  so that  MD_MAX72xx library treets it properly
  11. #define MAX_DEVICES  4                                        // Total number display modules
  12. #define CLK_PIN   13                                          // Clock pin to communicate with display
  13. #define DATA_PIN  11                                          // Data pin to communicate with display
  14. #define CS_PIN    10                                          // Control pin to communicate with display
  15. #define  xres 32                                              // Total number of  columns in the display, must be <= SAMPLES/2
  16. #define  yres 8                                               // Total number of  rows in the display
  17. int audio_response = 20;                                      // put a value between 10 and 80. Smaller the number, higher the audio response
  18. int MY_ARRAY[]={0, 128, 192, 224, 240, 248, 252, 254, 255};   // default = standard pattern
  19. int MY_MODE_1[]={0, 128, 192, 224, 240, 248, 252, 254, 255};  // standard pattern
  20. int MY_MODE_2[]={0, 128, 64, 32, 16, 8, 4, 2, 1};             // only peak pattern
  21. int MY_MODE_3[]={0, 128, 192, 160, 144, 136, 132, 130, 129};  // only peak +  bottom point
  22. int MY_MODE_4[]={0, 128, 192, 160, 208, 232, 244, 250, 253};  // one gap in the top , 3rd light onwards
  23. double vReal[SAMPLES];
  24. double vImag[SAMPLES];
  25. char data_avgs[xres];
  26. int yvalue;
  27. int displaycolumn , displayvalue;
  28. int peaks[xres];
  29. const int buttonPin = 6;                                      // the number of the pushbutton pin
  30. int state = HIGH;                                             // the current reading from the input pin
  31. int previousState = LOW;                                      // the previous reading from the input pin
  32. int displaymode;
  33. unsigned long lastDebounceTime = 0;                           // the last time the output pin was toggled
  34. unsigned long debounceDelay = 50;                             // the debounce time; increase if the output flickers
  35. MD_MAX72XX mx = MD_MAX72XX(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);   // display object
  36. arduinoFFT FFT = arduinoFFT();                                    // FFT object
  37. void setup() {
  38.     EEPROM.update(1,1);                                           //(memory address, value), RUN THIS FOR THE FIRST TIME
  39.     displaymode = EEPROM.read(1);
  40.     ADCSRA = 0b11100101;                                          // set ADC to free running mode and set pre-scalar to 32 (0xe5)
  41.     ADMUX = 0b00000000;                                           // use pin A0 and external voltage reference
  42.     pinMode(buttonPin, INPUT);
  43.     mx.begin();                                                   // initialize display
  44.     delay(50);                                                    // wait to get reference voltage stabilized
  45. }
  46. void loop() {
  47.    // ++ Sampling
  48.    for(int i=0; i<SAMPLES; i++)
  49.     {
  50.       while(!(ADCSRA & 0x10));                                    // wait for ADC to complete current conversion ie ADIF bit set
  51.       ADCSRA = 0b11110101 ;                                       // clear ADIF bit so that ADC can do next operation (0xf5)
  52.       int value = ADC - 512 ;                                     // Read from ADC and subtract DC offset caused value
  53.       vReal[i]= value/8;                                          // Copy to bins after compressing
  54.       vImag[i] = 0;                        
  55.     }
  56.     // -- Sampling
  57.     // ++ FFT
  58.     FFT.Windowing(vReal, SAMPLES, FFT_WIN_TYP_HAMMING, FFT_FORWARD);
  59.     FFT.Compute(vReal, vImag, SAMPLES, FFT_FORWARD);
  60.     FFT.ComplexToMagnitude(vReal, vImag, SAMPLES);
  61.     // -- FFT
  62.    
  63.     // ++ re-arrange FFT result to match with no. of columns on display ( xres )
  64.     int step = (SAMPLES/2)/xres;
  65.     int c=0;
  66.     for(int i=0; i<(SAMPLES/2); i+=step)  
  67.     {
  68.       data_avgs[c] = 0;
  69.       for (int k=0 ; k< step ; k++) {
  70.           data_avgs[c] = data_avgs[c] + vReal[i+k];
  71.       }
  72.       data_avgs[c] = data_avgs[c]/step;
  73.       c++;
  74.     }
  75.     // -- re-arrange FFT result to match with no. of columns on display ( xres )
  76.    
  77.     // ++ send to display according measured value
  78.     for(int i=0; i<xres; i++)
  79.     {
  80.       data_avgs[i] = constrain(data_avgs[i],0,audio_response);              // set max & min values for buckets
  81.       data_avgs[i] = map(data_avgs[i], 0, audio_response, 0, yres);         // remap averaged values to yres
  82.       yvalue=data_avgs[i];
  83.       peaks[i] = peaks[i]-1;    // decay by one light
  84.       if (yvalue > peaks[i])
  85.           peaks[i] = yvalue ;
  86.       yvalue = peaks[i];   
  87.       displayvalue=MY_ARRAY[yvalue];
  88.       displaycolumn=31-i;
  89.       mx.setColumn(displaycolumn, displayvalue);                // for left to right
  90.      }
  91.      // -- send to display according measured value
  92.      
  93.     displayModeChange ();                                       // check if button pressed to change display mode
  94.     int reading = digitalRead(buttonPin);
  95.     if (reading == LOW)
  96.     {
  97.       switch (displaymode)
  98.       {
  99.       case 1:    //       move from mode 1 to 2
  100.       for (int i=0 ; i<=8 ; i++ ) {
  101.         MY_ARRAY[i]=MY_MODE_2[i];
  102.       }
  103.       break;
  104.       case 2:    //       move from mode 2 to 3
  105.       for (int i=0 ; i<=8 ; i++ ) {
  106.         MY_ARRAY[i]=MY_MODE_3[i];
  107.       }
  108.       break;
  109.       case 3:    //     move from mode 3 to 4
  110.       for (int i=0 ; i<=8 ; i++ ) {
  111.         MY_ARRAY[i]=MY_MODE_4[i];
  112.       }
  113.       break;
  114.       case 4:    //      move from mode 4 to 1      
  115.       for (int i=0 ; i<=8 ; i++ ) {
  116.         MY_ARRAY[i]=MY_MODE_1[i];
  117.       }
  118.       break;
  119.       }
  120.     }
  121. }
  122. void displayModeChange() {
  123.   int reading = digitalRead(buttonPin);
  124.   if (reading == HIGH && previousState == LOW && millis() - lastDebounceTime > debounceDelay) // works only when pressed
  125.   {
  126.    switch (displaymode)
  127.    {
  128.     case 1:    //       move from mode 1 to 2
  129.       displaymode = 2;
  130.       EEPROM.update(1,2);
  131.       for (int i=0 ; i<=8 ; i++ ) {
  132.         MY_ARRAY[i]=MY_MODE_2[i];
  133.       }
  134.       break;
  135.     case 2:    //       move from mode 2 to 3
  136.       displaymode = 3;
  137.       EEPROM.update(1,3);
  138.       for (int i=0 ; i<=8 ; i++ ) {
  139.         MY_ARRAY[i]=MY_MODE_3[i];
  140.       }
  141.       break;
  142.     case 3:    //     move from mode 3 to 4
  143.       displaymode = 4;
  144.       EEPROM.update(1,4);
  145.       for (int i=0 ; i<=8 ; i++ ) {
  146.         MY_ARRAY[i]=MY_MODE_4[i];
  147.       }
  148.       break;
  149.     case 4:    //      move from mode 4 to 1
  150.       displaymode = 1;
  151.       EEPROM.update(1,1);      
  152.       for (int i=0 ; i<=8 ; i++ ) {
  153.         MY_ARRAY[i]=MY_MODE_1[i];
  154.       }
  155.       break;
  156.   }
  157.     lastDebounceTime = millis();
  158.   }
  159.   previousState = reading;
  160. }
复制代码


回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 昨天 16:28

【Arduino 动手做】32 频段 LED 音频频谱分析仪

【Arduino 动手做】32 频段 LED 音频频谱分析仪 |Arduino Nano + MAX 7219
项目链接:https://github.com/HAZI-TECH/32- ... ?tab=readme-ov-file
项目作者:HAZI TECH

项目视频 :https://www.youtube.com/watch?v=QE2wv7v7q1U
项目代码:https://github.com/HAZI-TECH/32- ... D_Spectrum_Analyzer

【Arduino 动手做】32 频段 LED 音频频谱分析仪 MAX 7219图1

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4 备案 沪公网安备31011502402448

© 2013-2025 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail