I need some guidance on how to implement a digital low-pass filter that has a cutoff frequency of around 50Hz.
Also, i really need help to know how to plot a running fft plot on a LCD from accelerometer data for vibration readings. I tried using the fft library from openmusiclabs: ArduinoFFT - Open Music Labs Wiki but to be honest I dont really understand how to use the library, or whether it can even be used for accelerometer data.
Some info on hardware I'm using:
accelerometer is LSM303DLHC from ST which interfaces with Arduino Uno by i2c, as such the raw data is not from 0-1023 like ADC but actually from -32000 to 32000 (+/- 2g)
the data rate from the accelerometer is 100Hz, and the baud rate i need it set at 9600
I intend to plot a fft from 1-50Hz, with each bin representing 1Hz. May i know the steps i can take to do this?
What plot? The FFT example just outputs numbers to the serial monitor.
You will probably have to understand how the low pass filter examples work, and modify them to fit your needs.
If your input data are in the form of a time series, then the result of an FFT calculation is a list of number pairs representing the amplitudes and phases of frequency components that make up that time series.
If you don't know how to interpret the output, you will need to read about the theory of Fourier transforms. The ArduinoFFT site gives some links.
the output is in binary, not ascii characters, which is why it looks like gibberish. you can change serial.write to serial.print and it should be readable, although you might have to go through and output each number, one at a time, rather than the batch operation shown.
you should also take a look at the equations for calculating the number of bands, band width, and sampling rate.
finally, the FHT on that site is a lower overhead program that does the same thing
The library contains instructions on how to run the programs, please read them!
What you did above should have worked, but of course everything will be run together.
To print each value on a separate line, use Serial.println(fft_log_out[j]); // send out the data
Note that there are only N/2 unique values, where N is the number of samples input to the FFT operation.
fft_mag_log() - This gives the magnitude of each bin in the FFT. It sums the squares of the imaginary and real, and then takes the square root, and then takes the log base 2 of that value. Therefore, the output is compressed in a logarithmic fashion, and is essentially in decibels (times a scaling factor). It takes no variables, and returns no variables. It uses a lookup table to calculate the log of the square root, and scales the output over the full 8b range {the equation is 16*(log2((img2 + real2)1/2))}. It is only an 8b value, and the values are taken from fft_input[], and returned in fft_log_out[]. The output values are in sequential order of FFT frequency bins, and there are only N/2 total bins, as the second half of the FFT result is redundant for real inputs.
Thanks, after reading through the website I have a good idea on how to use the library.
However, using Serial.println does not help too. The problem is that after 13 numbers, the rest are gibberish, not that there were numbers in running order, which i do find weird.
/*
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 256 // set to 256 point fft
#include <FFT.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 < 512 ; i += 2) { // 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
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
sei();
//Serial.write(255); // send a start byte
//Serial.write(fft_log_out,128);
for (int j=0;j<128;j++){
Serial.println(fft_log_out[j]); // send out the data
}
}
}
Basically i added in the last two lines and commented off the Serial.write commands which were originally in the code, thanks.
This is just an example code from the openmusiclabs website. It intends to take input from the adc(0) pin and output fft values. I intend to use my accelerometer to detect vibrations, hence the need for a FFT plot.
Post an example of the output that you consider to be gibberish.
If you don't have anything connected to the ADC, you might expect random nonsense in the FFT output, or mostly zeros.
Doesn't it make sense to test the program with a known signal, to see if it produces the expected output?
Anyway I was using a 50k pot to simulate a ADC input signal but it didn't matter. What went wrong was that the baud rate was at 115200. Once i set it to 9600 i was able to read numerical output from the serial monitor, although i have no idea why that is the case.