#include <arduinoFFT.h>
#include <MD_MAX72xx.h>
#include <SPI.h>
#define HARDWARE MD_MAX72XX::FC16_HW
#define DISPLAYS 4 // How many 8x8 displays we have
#define SAMPLES 64
#define CS_PIN 10 // Control pin to communicate with display
#define cols 32 // Size of display matrix, must be <= SAMPLES / 2
#define rows 8
MD_MAX72XX disp = MD_MAX72XX(HARDWARE, CS_PIN, DISPLAYS); // Display object
arduinoFFT FFT = arduinoFFT(); // FFT object
double realValues[SAMPLES];
double imagValues[SAMPLES];
char avgs[cols];
int peaks[cols];
int spectralHeight[] = {0, 128, 192, 224, 240, 248, 252, 254, 255}; // Height of relative frequencies
int index, column, y, value;
void setup() {
disp.begin(); // Initialize the display
Serial.begin(9600); // Used to view analog input in Wokwi
}
void loop() {
// int sensitivity = map(analogRead(A7),0,1023,50,100);
Serial.println (analogRead(A7));
// Collect 64 samples
for (int i=0; i < SAMPLES; i++) {
realValues[i] = analogRead(A7)/8;
imagValues[i] = 0;
}
// Perform the FFT
FFT.Windowing(realValues, SAMPLES, FFT_WIN_TYP_HAMMING, FFT_FORWARD);
FFT.Compute(realValues, imagValues, SAMPLES, FFT_FORWARD);
FFT.ComplexToMagnitude(realValues, imagValues, SAMPLES);
// Rearrange the FFT result to align with the # of columns
int step = (SAMPLES / 2) / cols;
int j = 0;
for (int i = 0; i < (SAMPLES / 2); i += step) {
avgs[j] = 0;
for (int k = 0; k < step; k++) {
avgs[j] = avgs[j] + realValues[i + k];
}
avgs[j] = avgs[j] / step;
j++;
}
// Send the data to the display
for (int i=0; i < cols; i++) {
avgs[i] = constrain(avgs[i],0,80); // Min & max values for each bucket
avgs[i] = map(avgs[i],0,80,0,rows); // Map the averages to the rows
y = avgs[i];
peaks[i] = peaks[i] - 1;
if (y > peaks[i]) {
peaks[i] = y;
}
y = peaks[i];
value = spectralHeight[y];
column = 31 - i;
disp.setColumn(column, value);
}
}