Hi! I am working on a group project with an ADXL 326 accelerometer and Arduino Uno with an HC-06 Bluetooth Shield. We want to do a fourier transform analysis in real time on the x, y, and z sensor data in adruino. We have read and downloaded fft library. If anyone can help us with the code that would be great! We already know how to read the acceleration values we really just need help doing fft on the x, y, and z values. We were thinking of using a circular buffer as well to do this.
Any feedback or comments would be really appreciated!! thanks so much
We are creating a pitch counter. Our device will be worn on the wrist and will count pitches thrown. We have created a basic counter using a maximum threshold but we noticed, after doing fft in matlab, that the accuracy of capturing a pitch would be much better using fft. i know that fht is "faster"--would you recommend using this instead?
I am pretty unfamiliar with "ADMUX" and "DIDRO" etc. but would we just run the loop 3 times: so setting ADMUX = 0x40 and then another time when ADMUX = 0x41 etc?
So for example, this is the fft sample code.
/*
fft_adc_serial.pde
guest openmusiclabs.com 7.7.14
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.
*/
#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.println("start");
for (byte i = 0 ; i < FFT_N/2 ; i++) {
Serial.println(fft_log_out[i]); // send out the data
}
}
}
Where would you put the loop for getting the fft from the y and z?
Moderator edit: </mark> <mark>[code]</mark> <mark>
I would think you could detect a pitch by thresholding, look at the data and I imagine that the acceleration in 1, 2, or 3 directions exceeds a value only when the pitcher is throwing a pitch.
If you find that Fourier analysis is the better way for you to determine the pitch get one of the Teensy Boards. The Teensies are built on 32-bit ARM processors that probably run 10 times faster than the Arduino and the code you have developed will work on the Teensy using the Arduinio IDE. I know you are getting excited about the Teensy so hang on it gets even better, the Teensy can access the ARM DSP library so you can use their FFT code as it will probably run faster than that code on the Ardiuino library.
Real time is kind of soft term the way it is used by most, I prefer near real time as rarely are events captured that require much analysis displayed real time. For example you are doing a pitch counter so your system needs to be able to determine whether a pitch has happened before the next pitch occurs so you have seconds to make the calcs if you do it carefully.
Yes, it is our interpretation of the pitch but with the code we have now, it counts claps for example. We have tried various ways and our advisor thinks that by doing a fft we are the most accurate.
Wade--thank you so much for your feedback. I will look into the Teensy Boards now. Do you know off hand if you can use HC-06 bluetooth with it?
ced_project:
. . . We have created a basic counter using a maximum threshold but we noticed, after doing fft in matlab, that the accuracy of capturing a pitch would be much better using fft. . . .
I'm not seeing how a Fourier Transform is helpful in this application, generally it would be applied to periodic signal analysis. It sounds as if you have some algorithm implemented in Matlab. Perhaps it would be more clear if you could describe the pitch detection algorithm you're trying to implement or post the Matlab code.
Whether or not anyone here can provide help on specifics, it is likely to be a valuable exercise to step back and clearly describe what it is you are trying to implement without getting too wrapped up in low level implementation details.
if P1z(1,3) > thresh && P1y(1,3) > thresh %Analyzing amplitude at 1.0Hz on FFT
This is just a very computationally expensive low pass filter. Two extra lines of code on an Arduino.
I think it's actually a bandpass filter centered at 2 Hz (taking the 3rd bin only of {0 Hz, 1 Hz, 2 Hz, ..., 24 Hz}), but agree that it's not a particularly efficient way to get there.
I'm curious now what the time domain and frequency spectrum looks like for a thrown ball if the original poster has some example plots. I would expect an impulse of several G's in the time domain, but don't have a good feel for confounding signal components.
ced_project:
I have attached a graph of what one pitch looks like with the corresponding magnitude of P1as well as a graph of 5 pitches.
As you can see the y and z (yellow and red) have a similar pattern while x has a different pattern.
Thanks. I gather that the blue line (x) is oriented along the thrower's forearm?
The first thing I'd try is to take the magnitude of the y and z sensors (e.g. sqrt(y^2 + z^2)) and compare it to a threshold. A second approach might be to integrate that magnitude over some number of points and compare that against a threshold. The second approach might more reliably detect a relatively slow pitch. I'm guessing the positive then negative x at the end is "wrist flip". Whatever the mechanism, it's consistent in this sample set and you might look to recognize that feature as an additional check.
Off hand I think your FFT peak bin is mostly an artifact of the sample window size.
Hi!! I am working on a project to count the number of pitches. I am trying to get the fft of the x axis and do an fft analysis to count a pitch. the frequency of the pitch falls within the range of 1 Hz. I need to get this value and have it count as a pitch.
The 300 value in the code is arbitrary--this is the threshold i wanted to set.