There is a Pure Data patch for visualising the data.
The serial output of the example code is intended to be used as input to Pure Data (http://puredata.info/). It doesn't say where/what the patch is. I have never used Pure Data so I can't help with it other than to say that it runs on your PC and provides visualization of the data from the FFT.
At the end of the example code:
Serial.write(255); // send a start byte
Serial.write(fft_log_out, 128); // send out the data
this sends the data out the serial port. You could replace it with your own code. The magnitudes (amplitudes) of the result of the FFT are the 128 values in the fft_log_out array.
g_u_e_s_t:
So I tried FHT's example code and replaced that line with:
for (int i = 0; i< FHT_N/2; i++)
{
Serial.println(fht_log_out[i]);
}
Now it outputs 103 numbers in serial port monitor ONCE and after that it starts outputting weird characters again...
Here's full code:
/*
fht_adc.pde
guest openmusiclabs.com 9.5.12
example sketch for testing the fht library.
it takes in data on ADC0 (Analog0) and processes them
with the fht. 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 FHT_N 256 // set to 256 point fht
#include <FHT.h> // include the library
void setup() {
Serial.begin(115200); // use the serial port
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 loop() {
while(1) { // reduces jitter
cli(); // UDRE interrupt slows this way down on arduino1.0
for (int i = 0 ; i < FHT_N ; i++) { // save 256 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
fht_input[i] = k; // put real data into bins
}
fht_window(); // window the data for better frequency response
fht_reorder(); // reorder the data before doing the fht
fht_run(); // process the data in the fht
fht_mag_log(); // take the output of the fht
sei();
//Serial.write(255); // send a start byte
//Serial.write(fht_log_out, FHT_N/2); // send out the data
for (int i = 0; i< FHT_N/2; i++)
{
Serial.println(fht_log_out[i]);
}
}
}
So you're saying it constantly outputs numbers for you? Because it doesn't for me on UNO, it keeps repeating weird characters and displays numbers only in the beginning
each number you output is associate with a frequency (indexed by the integer i in this case). so for i = 0 you get the 0th frequency, and for i = 128 you get the 128th frequency. these are linearly spaced and depend upon your sampling frequency. the sample rate is set by ADCSRA and the CPU clock frequency. in this case its 16MHz/32/13 = ~38kHz. 16MHz is the arduino clock frequency, the last 3 bits in ADCSRA are set to 5, which means /32, and its in free running mode, so it takes 13 clock cycles to get a sample.
for FHT_N = 256, you have 256 bins to cover the full frequency range, so each bin is 38kHz/256 = 150Hz. but, half of the bins repeat, so you really only have FHT_N/2 bins covering half the frequency range. in this case 128 bins, from 0Hz to 19kHz, with a step size of 150Hz.
Thank you so much for everyone contributing to this thread I basically had the exact same issue as OP, and this thread finally helped me yield numeric outputs.
I only have one question remaining; as I understand it, 128 frequencies will be displayed in the serial monitor, in which the 0th frequency is the most dominant, and the 128th frequency is the least dominant. Since the values scroll so quickly, does anyone have a simple approach to see which values are first in this list, i.e. the ranking such that I may view the most dominant frequencies? seems like something easy but I am honestly confused how to approach this.
Thank you very much to anyone willing to drop some knowledge
the 0th frequency is the most dominant, and the 128th frequency is the least dominant
No, that's not it at all. As g_u_e_s_t has explained, each bin represents a range of frequencies. The 0th bin has the amplitude of the zero frequency (DC) component of the signal. The next bin will have the amplitude of frequencies around 150Hz, then 300Hz etc. up to the 127th bin with the amplitude of frequencies around 19050Hz.
If you want to know the frequency with the highest amplitude you would have to search the array to find the highest amplitude and then the index of that entry multiplied by 150 gives its frequency.