Making sense of FFT data

Status
Not open for further replies.

James2017

Member
I have code working that generates pink noise on the dac, plays it to a surface exciter (via an amp), and then reads it back in on an adc pin via a piezo sensor.

The purpose is to be able to tell if the structure to which the sensor is attached is touched, since that presumably alters the power distribution in the FFT-derived frequency bins. Detection ideally would occur quickly (10ms?).

This leads to two main questions:

1) Is pink (or white) noise really the way to do this, because, being random, I assume that a large number of FFT cycles must be performed to get good average power distributions?

Further, this is on a 3D printer which is going to have electrical noise and vibrations from the motors, perhaps causing false positives. I am using pink/white noise because this is what was suggested by someone else who did this project, but I'm wondering if perhaps a couple individual frequencies would have more deterministic behavior and thus deviation from the baseline signal could be more quickly and accurately recognized.

2) Regardless of the answer to #1 above, how does one determine what constitutes "different" to distinguish a "touch" from "no touch" situation? I could see applying conventional statistics to the FFT data points to get a p value, but I'm guessing this is not how it is done with sound. However, I can't find an example of just how it is done, although I know similar techniques are used for, for example, listening to motors and bearings to see if a change in the frequency amplitudes indicate problems.

This code works great as far as it goes, but I don't know how to make a reliable decision based on the data gathered:

==================================
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

// Set up input, outputs, filters, connections and FFT object

// Uncomment one noise source
// AudioSynthNoisePink noise;
AudioSynthWaveformSine noise;

AudioInputAnalog adc1(A8);
AudioOutputAnalog dac1; // only available on A14, takes no pin
AudioFilterStateVariable filter1;
AudioAnalyzeFFT1024 myFFT;

// AudioConnection parameters take form (source, sourcePort, destination, destinationPort)
// Some objects only have one port, in which case 0's can be optional
AudioConnection patchCord1(noise, 0, filter1, 0);
AudioConnection patchCord2(filter1, 0, dac1, 0);
AudioConnection patchCord3(adc1, 0, myFFT, 0);


void setup() {

// Audio memory must be allocated in blocks. A block is 128 samples, or about 2.9ms.
AudioMemory(12);

// Configure the FFT window algorithm to use (AudioWindowHanning1024 is generally advised), but
// http://www.ni.com/white-paper/4278/en/ suggests that no windowing should be used for white noise
myFFT.windowFunction(NULL);

// Set frequency corner of filter
//filter1.frequency(1000);

// For pure tone set frequency, comment if using white/pink noise
noise.frequency(200);

// Won't play until amplitude is non-zero
noise.amplitude(1);
}

void loop() {
float n;
int i;

if (myFFT.available()) {
// each time new FFT data is available, print first X bins to Serial Monitor
Serial.print("FFT: ");
for (i=0; i<30; i++) {
n = myFFT.read(i);
if (n >= 0.01) {
Serial.print(n);
Serial.print(" ");
} else {
Serial.print(" - "); // don't print "0.00"
}
}
Serial.println();
}
}
 
That is an interesting problem:
Let me try to formulate is slightly differently:
coupling wideband noise (colour is not relevant) onto a body results in the body to vibrate according to its structure, so certain Eigen frequencies are amplified and other frequencies are attenuated.
When the body is touched, these frequencies will change. How much they will change will depend on the influence of the touching on the internal vibration of the body.
You detection function is the spectral difference between 'untouched' and 'touched'. What I would do is to estimate the information, or better the spectral entropy difference between the two spectra.

I would first estimate a cross spectrogram and plot it to see if the spectrum varies while touching.

For an automatic procedure; I would then estimate a test function T for all values of a cross spectrogram and compare to a threshold.

As a start, I would try to generate a simple test function based on the cross spectral energy
Code:
T = - sum(c_i*log(c_i)))
where c_i is the i'th bin of the cross power spectrum (actual versus 'untouched') and the sum runs over all frequencies.

The threshold is found empirically by applying the test statistics to an untouched situation to have false alarm rate reduced to an acceptable level.

I would then inspect the spectra to figure out which frequencies are more sensitive to touching, so you can limit the spectral range of your summation to more responsive frequencies.
 
Thank you for the suggestions. How would you suggest actually implementing the math? I know in something like Matlab or Mathematica, cross spectrogram functions probably exist. Here, I suspect not.

Do you know of libraries to do this, or is it easy enough to write from scratch, or perhaps I could see if Mathematica can export C code that would work (serious doubts about that)?
 
Thank you for the suggestions. How would you suggest actually implementing the math? I know in something like Matlab or Mathematica, cross spectrogram functions probably exist. Here, I suspect not.

Do you know of libraries to do this, or is it easy enough to write from scratch, or perhaps I could see if Mathematica can export C code that would work (serious doubts about that)?
I do not know any ready to use library for teensy or Arduino.
But the fun of teensy is to experiment.

You already started with the audio tool so continue with that.
augment it to transfer spectra to PC and plot the spectra in Matlab.
with that you already can see what "touching" does to your data.

Complex averaging of spectra will help to reduce your data rate.

Next I would multiply the spectra with the reference spectra to see is you can see differences.

To get the reference spectrum I would average both power and (unwrapped) phase of the spectra of the untouched situation

I would use Matlab/Mathematica to develop algorithm but not to generate c-code. it is always better to develop teensy code piece by piece and adapt algorithm to what teensy can do. That is move functionality slowly from PC to teensy.
 
Status
Not open for further replies.
Back
Top