Liebes Forum,
Ich versuche schon seit einer Weile eine FFT von einem Stereo Line Eingang auf einer RGB LED Matrix (Adafruit 16x32) anzzeugen.
Dabei gibt es 2 Probleme:
-
Es gibt einen konstanten tieffrequenten Anteil, den ich nicht aus dem Signal bekomme.
-
Außerdem zeigt meine Matrix nicht die volle Amplitude des Signals an.
Das Bild FFT1.jpg zeigt die Matrix ohne Input. FFT2.jpg zeigt die Matrix mit einem 10 kHZ Sinus bei voller Lautstärke. Es sollte eigentlich in 8b (max 256) ausgegeben werden
Ich habe auch meinen Schaltplan hinzugefügt.
In der .txt Datei ist info zur FFT Bibliothek.
Code auf dem Arduino:
/*
fft_adc.pde
guest openmusiclabs.com 8.18.12
example sketch for testing the fft library.
it takes in data on ADC0 (Analog0) and processes them
with the fft. the data is sent out over the serial
port at 115.2kb. there is a pure data patch for
visualizing the data.
*/
#define LOG_OUT 1 // use the log output function
#define FFT_N 64 // set to 64 point fft
#include <Adafruit_GFX.h> // Core graphics library
#include <RGBmatrixPanel.h> // Hardware-specific library
#include <FFT.h> // include the library
#define CLK 8 // MUST be on PORTB!
#define LAT A3
#define OE 9
#define A A4
#define B A1
#define C A2
int freq_array[36];
RGBmatrixPanel matrix(A, B, C, CLK, LAT, OE, false);
void setup() {
matrix.begin();
TIMSK0 = 0; // turn off timer0 for lower jitter
ADCSRA = 0xe5; // set the adc to free running mode
ADMUX = 0x40; // use adc0
DIDR0 = 0x01; // turn off the digital input for adc0
}
void lightcolumns(int rownum, int amplitude)
{
if(amplitude>15) // <-O-> set the threshold for the band to turn red
{
for( int y = 0; y < amplitude; y++){
matrix.drawPixel(rownum, y, matrix.Color333(7, 0, 0));
}
for(int y = amplitude; y <16; y++)
{
matrix.drawPixel(rownum, y, matrix.Color333(0, 0, 0));
}
}
else if(amplitude>13) // <-O-> set the threshold for the band to turn yellow
{
for( int y = 0; y < amplitude; y++){
matrix.drawPixel(rownum, y, matrix.Color333(4, 4, 0));
}
for(int y = amplitude; y < 16; y++)
{
matrix.drawPixel(rownum, y, matrix.Color333(0, 0, 0));
}
}
else if(amplitude>9) // <-O-> set the threshold for the band to turn green
{
for( int y = 0; y < amplitude; y++){
matrix.drawPixel(rownum, y, matrix.Color333(0, 5, 0));
}
for(int y = amplitude; y < 16; y++)
{
matrix.drawPixel(rownum, y, matrix.Color333(0, 0, 0));
}
}
else
{
for( int y = 0; y < amplitude; y++){
matrix.drawPixel(rownum, y, matrix.Color333(0, 0, 7));
}
for(int y = amplitude; y < 16; y++)
{
matrix.drawPixel(rownum, y, matrix.Color333(0, 0, 0));
}
}
}
void loop() {
while (1) { // reduces jitter
for (int i = 0 ; i < 128 ; i += 2) { // save 64 samples
while (!(ADCSRA & 0x10)); // wait for adc to be ready
ADCSRA = 0xf5; // restart adc
byte m = ADCL; // fetch adc data
byte j = ADCH;
int k = (j << 8) | m; // form into an int
k -= 0x0200; // form into a signed int
k <<= 6; // form into a 16b signed int
fft_input[i] = k; // put real data into even bins
fft_input[i + 1] = 0; // set odd bins to 0
}
fft_window(); // window the data for better frequency response
fft_reorder(); // reorder the data before doing the fft
fft_run(); // process the data in the fft
fft_mag_log(); // take the output of the fft
for (int j = 0; j < 32; j++) {
if (fft_log_out[j] < 2000 && fft_log_out[j] > 255) {
freq_array[j] = 16;
}
else {
if (fft_log_out[j] <= 255 && fft_log_out[j] > 240) {
freq_array[j] = 15;
}
else {
if (fft_log_out[j] <= 240 && fft_log_out[j] > 225) {
freq_array[j] = 14;
}
else {
if (fft_log_out[j] <= 225 && fft_log_out[j] > 210) {
freq_array[j] = 13;
}
else {
if (fft_log_out[j] <= 210 && fft_log_out[j] > 195) {
freq_array[j] = 12;
}
else {
if (fft_log_out[j] <= 195 && fft_log_out[j] > 180) {
freq_array[j] = 11;
}
else {
if (fft_log_out[j] <= 180 && fft_log_out[j] > 165 ) {
freq_array[j] = 10;
}
else {
if (fft_log_out[j] <= 165 && fft_log_out[j] > 150) {
freq_array[j] = 9;
}
else {
if (fft_log_out[j] <= 150 && fft_log_out[j] > 135){
freq_array[j] = 8;
}
else {
if (fft_log_out[j] <= 135 && fft_log_out[j] > 120) {
freq_array[j] = 7;
}
else {
if (fft_log_out[j] <= 120 && fft_log_out[j] > 105) {
freq_array[j] = 6;
}
else {
if (fft_log_out[j] <= 105 && fft_log_out[j] > 90) {
freq_array[j] = 5;
}
else {
if (fft_log_out[j] <= 90 && fft_log_out[j] > 75) {
freq_array[j] = 4;
}
else {
if (fft_log_out[j] <= 75 && fft_log_out[j] > 60) {
freq_array[j] = 3;
}
else {
if (fft_log_out[j] <= 60 && fft_log_out[j] > 45) {
freq_array[j] = 2;
}
else {
if (fft_log_out[j] <= 45 && fft_log_out[j] > 15) {
freq_array[j] = 1;
}
else {
if (fft_log_out[j] <= 15 && fft_log_out[j] >= 0) {
freq_array[j] = 0;
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
lightcolumns(31, freq_array[0]);
lightcolumns(30, freq_array[1]);
lightcolumns(29, freq_array[2]);
lightcolumns(28, freq_array[3]);
lightcolumns(27, freq_array[4]);
lightcolumns(26, freq_array[5]);
lightcolumns(25, freq_array[6]);
lightcolumns(24, freq_array[7]);
lightcolumns(23, freq_array[8]);
lightcolumns(22, freq_array[9]);
lightcolumns(21, freq_array[10]);
lightcolumns(20, freq_array[11]);
lightcolumns(19, freq_array[12]);
lightcolumns(18, freq_array[13]);
lightcolumns(17, freq_array[14]);
lightcolumns(16, freq_array[15]);
lightcolumns(15, freq_array[16]);
lightcolumns(14, freq_array[17]);
lightcolumns(13, freq_array[18]);
lightcolumns(12, freq_array[19]);
lightcolumns(11, freq_array[20]);
lightcolumns(10, freq_array[21]);
lightcolumns(9, freq_array[22]);
lightcolumns(8, freq_array[23]);
lightcolumns(7, freq_array[24]);
lightcolumns(6, freq_array[25]);
lightcolumns(5, freq_array[26]);
lightcolumns(4, freq_array[27]);
lightcolumns(3, freq_array[28]);
lightcolumns(2, freq_array[29]);
lightcolumns(1, freq_array[30]);
lightcolumns(0, freq_array[31]);
matrix.swapBuffers(false);
}
}
Danke!
Grüße, Flitschi
fft_read_me.txt (12.7 KB)