Hi everyone, i tried to redo a project i found on the internet. The goal is to make a spectrum sound analyzer using FFT. In the project i found, the person used 4 in 1 display. I have the same exact components except i have 2 Max712 instead of 4. I thought it was only a matter of coding as i just have to half certain values to match it.
Here's the code
#include <arduinoFFT.h>
#include <MD_MAX72xx.h>
#include <SPI.h>
#include <EEPROM.h>
#define SAMPLES 32 // 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 2 // 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 16 // Total number of columns in the display, must be <= SAMPLES/2
#define yres 8 // Total number of rows in the display
int audio_response = 12; // put a value between 10 and 80. Smaller the number, higher the audio response
int MY_ARRAY[]={0, 128, 192, 224, 240, 248, 252, 254, 255}; // default = standard pattern
int MY_MODE_1[]={0, 128, 192, 224, 240, 248, 252, 255, 255}; // standard pattern
int MY_MODE_2[]={0, 128, 64, 32, 16, 8, 4, 2, 1}; // only peak pattern
int MY_MODE_3[]={0, 128, 192, 160, 144, 136, 132, 130, 129}; // only peak + bottom point
int MY_MODE_4[]={0, 128, 192, 160, 208, 232, 244, 250, 253}; // one gap in the top , 3rd light onwards
int 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 pin
int state = HIGH; // the current reading from the input pin
int previousState = LOW; // the previous reading from the input pin
int displaymode = 1;
unsigned long lastDebounceTime = 0; // the last time the output pin was toggled
unsigned long debounceDelay = 50; // the debounce time; increase if the output flickers
MD_MAX72XX mx = MD_MAX72XX(HARDWARE_TYPE, CS_PIN, MAX_DEVICES); // display object
arduinoFFT FFT = arduinoFFT(); // FFT object
void setup() {
EEPROM.update(1,1); //(memory address, value), RUN THIS FOR THE FIRST TIME
displaymode = EEPROM.read(1);
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<SAMPLES; 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 - 256 ; // Read from ADC and subtract DC offset caused value(ADC - SAMPLES x 8)
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; i<(SAMPLES/2); i+=step)
{
data_avgs[c] = 0;
for (int k=0 ; k< step ; k++) {
data_avgs[c] = data_avgs[c] + vReal[i+k];
}
data_avgs[c] = data_avgs[c]/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<xres; 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;
EEPROM.update(1,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;
EEPROM.update(1,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;
EEPROM.update(1,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;
EEPROM.update(1,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;
EEPROM.update(1,1);
for (int i=0 ; i<=8 ; i++ ) {
MY_ARRAY[i]=MY_MODE_1[i];
}
break;
}
lastDebounceTime = millis();
}
previousState = reading;
}
But it is not really working, the leds matrix do not even light up.
I tested separately all my components and they work. Tested the microphone while adjusting the potentiometer with a simple led using the clapping project(where you make a sound and see if the led light on and off).
I do not see where the problem is, could you help me along the way please ?