Hi guys! I need help with a school project. I need to collect the frequency of lung sounds using an electret and FFT microphone, only the frequencies I can pick up are wrong. Any suggestion?
This is my code:
#include "arduinoFFT.h"
#define SAMPLES 512 //Must be a power of 2
#define SAMPLING_FREQUENCY 20000 //Hz, must be less than 10000 due to ADC //Frequencia mais alta esperada dobrada
arduinoFFT FFT = arduinoFFT();
unsigned int sampling_period_us;
unsigned long microseconds;
double vReal[SAMPLES];
double vImag[SAMPLES];
void setup() {
Serial.begin(115200);
sampling_period_us = round(1000000*(1.0/SAMPLING_FREQUENCY));
}
void loop() {
/*SAMPLING*/
for(int i=0; i<SAMPLES; i++)
{
microseconds = micros(); //Overflows after around 70 minutes!
vReal[i] = analogRead(A1);
vImag[i] = 0;
while(micros() < (microseconds + sampling_period_us)){
}
}
/*FFT*/
FFT.Windowing(vReal, SAMPLES, FFT_WIN_TYP_HAMMING, FFT_FORWARD);
FFT.Compute(vReal, vImag, SAMPLES, FFT_FORWARD);
FFT.ComplexToMagnitude(vReal, vImag, SAMPLES);
double peak = FFT.MajorPeak(vReal, SAMPLES, SAMPLING_FREQUENCY) - 300;
/*PRINT RESULTS*/
Serial.print("xp - "); Serial.println(peak); //Print out what frequency is the most dominant.
//for(int i=0; i<(SAMPLES/2); i++)
// {
/*View all these three lines in serial terminal to see which frequencies has which amplitudes*/
// Serial.print("ff - "); Serial.println((i * 1.0 * SAMPLING_FREQUENCY) / SAMPLES, 1);
// Serial.print("xa");
// Serial.println(vReal[i]); //View only this line in serial plotter to visualize the bins
//}
//Serial.println("-");
//delay(100);
delayMicroseconds(sampling_period_us);
}
What is the aim of the project? If it is a futility exercise in using Nano and its ADC for pretended FFT analysis, is one thing. If however you need proper signal processing with good quality FFT analysis, look no further than ArduinoSound - Arduino Reference, I2S microphone and MKR board
Please edit your post to add code tags ("</>" post editor button), and tell us which Arduino you are using. Also, post a link to the microphone module.
You won't be able to sample at 20kHz using that code, on the Mega2560. If you try, the results will be complete nonsense.
Did you not see the comment in this line of code?
#define SAMPLING_FREQUENCY 20000 //Hz, must be less than 10000 due to ADC
The default analog sample rate on AVR based Arduinos like the Mega is about 9.6 kHz, which is fine for your purpose. However, you must have a low pass filter to make sure that audio signals with frequencies no higher than 4 kHz reach the analog input, or you will have severe artifacts from aliasing.
Please post a link to where you obtained the "Module MAX9814"
During pulmonary auscultation, the sounds will generally in the range of 60 Hz to 1000 Hz. So the default ADC sample rate of just under 10 kHz is fine. A low pass filter is needed, though.
In subjects with healthy lungs, the frequency range of the vesicular breathing sounds extends to 1,000 Hz, whereas the majority of the power within this range is found between 60 Hz and 600 Hz (7, 11). Other sounds, such as wheezing or stridor, can sometimes appear at frequencies above 2,000 Hz (7).
I was thinking about using INMP441, it has a low pass filter, what do you think? Of course, I would have to use esp32. The MAX9814 module has only one amplifier.
I would probably use a Sallen-Key active low pass filter and a microphone like you have. Such filters are really simple to make, using about six inexpensive components on a piece of perfboard.
Personally I'd prefer the MAX9814 electret module (link above) - the adafruit looks to be in a convenient form for auscultation and the amp should be able to give good output to feed to a s&k filter.
The LM358 op amp is a poor choice. I'd suggest the mcp6002 which will run happily from a single supply from 5V or even 3.6V.
You could consider using an 8266 NODE or ESP32 for better processing power and storage - the DREADFUL adc would not be an issue as you would be using it in the middle of its range.
That board has only 8k of RAM, this might be a show-stopper if you want good frequency resolution.
For instance if you want 5Hz resolution and are sampling at 20kHz, you'll need a 4096 point FFT. And in fact as you'll need to apply a spectral window the resolution will be even lower as windows widen the peaks.