Hi,
I just finished a sketch for my Arduino to do FFT of some music. I think I understand the FFT and the Arduino seems to be doing what its supposed to be doing, but I just want to make sure I have this right. However, my code seems way too simple based on how other people did this and other people's code is way more complicated than this. I'll post a video link and my code here. I just have the output of a mixer going into the Arduino's analog pin via a diode, so it protects my mixer. A speaker is connected to the other channel so that it doesn't interfere with the FFT codework.
// FFT Sketch for Arduino
const int FFTSIZE = 128;
const int ROWS = 8;
const int latchPin = 8;
const int clkPin = 11;
const int dataPin = 12;
const int Sinewave[FFTSIZE] = {
+0, +1608, +3212, +4808, +6393, +7962, +9512, +11039,
+12539, +14010, +15446, +16846, +18204, +19519, +20787, +22005,
+23170, +24279, +25329, +26319, +27245, +28105, +28898, +29621,
+30273, +30852, +31356, +31785, +32137, +32412, +32609, +32728,
+32767, +32728, +32609, +32412, +32137, +31785, +31356, +30852,
+30273, +29621, +28898, +28105, +27245, +26319, +25329, +24279,
+23170, +22005, +20787, +19519, +18204, +16846, +15446, +14010,
+12539, +11039, +9512, +7962, +6393, +4808, +3212, +1608,
+0, -1608, -3212, -4808, -6393, -7962, -9512, -11039,
-12539, -14010, -15446, -16846, -18204, -19519, -20787, -22005,
-23170, -24279, -25329, -26319, -27245, -28105, -28898, -29621,
-30273, -30852, -31356, -31785, -32137, -32412, -32609, -32728,
-32767, -32728, -32609, -32412, -32137, -31785, -31356, -30852,
-30273, -29621, -28898, -28105, -27245, -26319, -25329, -24279,
-23170, -22005, -20787, -19519, -18204, -16846, -15446, -14010,
-12539 -11039, -9512, -7962, -6393, -4808, -3212, -1608
};
int input[FFTSIZE];
int output[FFTSIZE];
long int sum;
int threshold;
int freeRam() {
extern int __heap_start, *__brkval;
int v;
return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
}
void setup() {
pinMode(13, OUTPUT);
pinMode(latchPin, OUTPUT);
pinMode(clkPin, OUTPUT);
pinMode(dataPin, OUTPUT);
calibAudio();
}
void loop() {
for(byte counter = 0; counter < FFTSIZE; counter++) {
input[counter] = analogRead(A0) - threshold;
if(input[counter] < 5 && input[counter] > -5) {
input[counter] = 0;
}
}
fftExecute(4);
ledDisplay(sum, 8);
fftExecute(7);
ledDisplay(sum, 7);
fftExecute(10);
ledDisplay(sum, 6);
fftExecute(20);
ledDisplay(sum, 5);
fftExecute(30);
ledDisplay(sum, 4);
fftExecute(40);
ledDisplay(sum, 3);
fftExecute(50);
ledDisplay(sum, 2);
fftExecute(60);
ledDisplay(sum, 1);
}
void calibAudio() {
digitalWrite(13, HIGH);
delay(2000);
for(byte counter = 0; counter < 25; counter++) {
sum += analogRead(A0);
delay(1);
}
sum /= 25;
threshold = sum;
delay(2000);
digitalWrite(13, LOW);
}
int fftExecute(byte SinewaveNumber) {
sum = 0;
long int SinewaveCounter = -1;
for(byte counter = 0; counter < FFTSIZE; counter++) {
SinewaveCounter = (SinewaveCounter++) * SinewaveNumber;
if(SinewaveCounter >= FFTSIZE) {
SinewaveCounter = 0;
}
output[counter] = input[counter] * (Sinewave[SinewaveCounter] / 1024);
}
for(byte counter = 0; counter < FFTSIZE; counter++) {
sum += output[counter];
}
if(sum < 0) {
sum = 0;
}
sum = map(sum, 0, 63000, 0, 1024);
if(sum < 9) {
sum = 0;
}
}
void ledDisplay(int sum, int row) {
// row = (map(row, 0, FFTSIZE / 2, 0, ROWS) + 1);
sum = map(sum, 0, 1024, 0, 8);
if(row == 0) {
row = B00000000;
}
else if(row == 1) {
row = B00000001;
}
else if(row == 2) {
row = B00000010;
}
else if(row == 3) {
row = B00000100;
}
else if(row == 4) {
row = B00001000;
}
else if(row == 5) {
row = B00010000;
}
else if(row == 6) {
row = B00100000;
}
else if(row == 7) {
row = B01000000;
}
else if(row == 8) {
row = B10000000;
}
if(sum == 0) {
sum = B00000000;
}
else if(sum == 1) {
sum = B00000001;
}
else if(sum == 2) {
sum = B00000011;
}
else if(sum == 3) {
sum = B00000111;
}
else if(sum == 4) {
sum = B00001111;
}
else if(sum == 5) {
sum = B00011111;
}
else if(sum == 6) {
sum = B00111111;
}
else if(sum == 7) {
sum = B01111111;
}
else if(sum >= 8) {
sum = B11111111;
}
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clkPin, MSBFIRST, row);
shiftOut(dataPin, clkPin, MSBFIRST, (255 - sum));
shiftOut(dataPin, clkPin, MSBFIRST, (255 - sum));
shiftOut(dataPin, clkPin, MSBFIRST, 255);
digitalWrite(latchPin, HIGH);
}
https://docs.google.com/file/d/0B2zuATFj02CVZE1oQm1uRF9XRE0/edit?usp=drive_web
I thought that my analogRead function was sampling at 10KHz, but the FFT seems to be running really slowly on my Arduino. The FFT should have been able to pick up frequencies up to 5Khz, but it seems that when I turn the LOW section on my EQ entirely off on my mixer, the entire display just shuts off, no matter how high I crank up the MID and HIGH. This leads me to believe that my FFT sketch isn't doing any analysis on frequencies above around 500Hz. What's going on there? I also have another question about why the third light in from the left on my LED matrix never lights up. The LED and circuitry works just fine, its just in the code, when I use fftExecute(eight) <--- (the #8 would have made smiley-cool) all the way up to fftExecute(12) it doesn't light up any LED's on the display.
Thanks,
Judd