Gabriel Covalski
Published © GPL3+

Audio Spectrum in a LED matrix - Wokwi

Project made for my Digital Circuits course at university, with the purpose of having something cool to put on your desk.

BeginnerShowcase (no instructions)5 hours279
Audio Spectrum in a LED matrix - Wokwi

Things used in this project

Story

Read more

Schematics

Schematic in Wokwi

Schematic of the connections from the Arduino UNO to the potentiometer and the MAX7219 LED Matrix.

Code

Audio Spectrum code

C/C++
Code to make the LED matrix turn on and display the sound based on the FFT of the frequency input device.
#include <SPI.h>
#include "fix_fft.h"


#define CLK_PIN   13
#define DATA_PIN  11
#define CS_PIN    10

#define inAudio A0
#define inPot A1

char re[128], im[128];





void modLine(int line, int val1, int val2, int val3, int val4){
  digitalWrite(CS_PIN, LOW);
  
  /* The standard LED matrix is 8x8;
  For some reason, Wokwi uses an 8x32 matrix, so it's as if there are 4 modules connected together.
  Therefore, for every 8 columns, a new HEX value must be sent to control the next module.
  It's not possible to use a loop or skip modules; each module must be updated every frame, 
  or the last modules will be treated as non-existent.*/
  
  SPI.transfer(line);
  SPI.transfer(val4);       // Last 8x8 module

  SPI.transfer(line);
  SPI.transfer(val3);

  SPI.transfer(line);
  SPI.transfer(val2);

  SPI.transfer(line);
  SPI.transfer(val1);       // First 8x8 module
  
  digitalWrite(CS_PIN, HIGH);
}





void setup(){
  Serial.begin(6900);
  pinMode(CS_PIN, OUTPUT);
  SPI.begin();
}

void loop(){
  int i=0, j=0;

  /*This is a conversion of the values I have to apply to the FFT;
  FFT: "Fast Fourier Transform";
  Basically, it's mathematics (i.e., magic) that converts a signal into sound frequency.*/

  //Serial.println(analogRead(inAudio));        //Uncomment accordantly to visualize the frequency input
  //Serial.println(analogRead(inPot));        //Uncomment accordantly to visualize the frequency input
  for (i = 0; i < 128; i++){
    int mic1 = analogRead(inPot);       //Potentiometer so we can emulate a microphone
    
    re[i] = mic1 / 4 - 128;       // AnalogRead returns  value from 0 to 1023, here, we convert it to go from -128 to 127
    im[i] = 0;        // Imaginary part of the FFT
  }

  /* Eu vou dar um BEIJO em quem criou essa bib.h*/
  fix_fft(re, im, 7, 0);
  
  int height[4] = {0, 0, 0, 0};       //Height for every column
  static int prevHeight[4] = {0, 0, 0, 0};       //This for the climb/drop animation of the column of LEDS
  int magnitude=0;

  for (j = i * 16; j < (i + 1) * 16; j++){        //Considers only the first 64 frequencies
    magnitude = magnitude + sqrt(re[j] * re[j] + im[i] * im[i]);
  }
  //Serial.println(magnitude);    //Uncomment to see the resulting magnitude
  
  for (i = 0; i < 4; i++) {
    height[i] = map(magnitude * (i + 1) / 4, 0, 2080, 0, 8);        //Divides and maps the frequency into 4 major groups that go from 0 to 8 each
    height[i] = constrain(height[i], 0, 8);       // Guarantees that the value is between 0 e 8
    //Serial.println(height[i]);        //Uncomment to see the height of each column
  }


 
  

  for (int i = 0; i < 4; i++) {       //Here were doing the animation previously mentioned
    while (prevHeight[i] != height[i]) {
        if (prevHeight[i] < height[i]) {
            prevHeight[i]++;
        } else {
            prevHeight[i]--;
        }

        for (int j = 0; j < 8; j++) {
            int line = 8 - j;
            int val1 = (j < prevHeight[0]) ? 0x7E : 0x00;
            int val2 = (j < prevHeight[1]) ? 0x7E : 0x00;
            int val3 = (j < prevHeight[2]) ? 0x7E : 0x00;
            int val4 = (j < prevHeight[3]) ? 0x7E : 0x00;

            modLine(line, val1, val2, val3, val4);
        }
        delay(10);        //Slows down the process so that the animation is smoother
    }
}
}

Credits

Gabriel Covalski
1 project • 1 follower
Currently enrolled in computer science major, at the Federal University of Technology of Paraná.
Thanks to .

Comments