Hi everyone,
It seems this project is much more complicated that what I expected it to be originally, so I'm in need of any help possible.
Im trying to set up code to listen for a whirring sound (say the sound of a power drill being used right next to a microphone (spw2430)). I've tried to use FFT that hasn't been reliable due to not having a good enough resolution. Im not trying to identify the frequency, I'm trying to pick out when a sound begins, and for how long it lasts, as compared to ambient noise.
To start off I'm trying to use running average based off an example to set a baseline (code below) but am having trouble getting any meaningful reading from my microphone. Would anyone have any insight here?
#include "RunningAverage.h"
#define CHANNEL A0
RunningAverage ambientSound(32);
int samples = 0;
void setup(void)
{
Serial.begin(115200);
ambientSound.clear();
}
void loop(void)
{
long sound = analogRead(CHANNEL);
ambientSound.addValue(sound * 0.001);
samples++;
Serial.print(samples);
Serial.print("\t Current sample: ");
Serial.print(sound);
Serial.print("\t Running Average: ");
Serial.println(ambientSound.getAverage(), 3);
if (samples == 200)
{
samples = 0;
ambientSound.clear();
Serial.println();
}
delay(300);
}
As to the overall project, am I approaching it completely wrong? is there a better way to do this?
Thank you
Did you ever look at the signal on an oscilloscope to see what it is you want to examine? A good microphone and amplifier with it's output connected to a resistor will provide the signal for any scope.
Paul
Paul_KD7HB:
Did you ever look at the signal on an oscilloscope to see what it is you want to examine?
Unfortunately I don't have one available.
With regards to the code, I misspoke, I should say that the output isnt giving reacting to any kind of noise happening- which leads me to believe that I set up the code wrong, but I dont know where I went wrong.
The SPW2430 has two outputs, a ground-centered AC signal (labeled "AC") and a 0.67 V centered AC signal (labeled "DC"). You should be using the "DC" version since the Arduino ADC input is 0 to 5 Volts.
With no sound, this should give a nominal ADC reading of 0.67 V/5.0 V * 1024 = 137. If you do a running average on the signal with DC offset, you'll always get something like that number on average regardless of the sound level which isn't particularly informative.
A more sensible approach is to measure the AC power of the audio signal. This is done by subtracting the DC offset and averaging the square of the residual signal.
ambientSound.addValue((sound - 137) ** 2) ;
In the absence of an oscilloscope, a good way to check out the microphone is to use the "AnalogReadSerial" sketch from the examples and the Serial Plotter feature of the Arduino IDE. This will display a waveform and you can see it wiggle around when you talk if everything is wired correctly.
MrMark:
With no sound, this should give a nominal ADC reading of 0.67 V/5.0 V * 1024 = 137. If you do a running average on the signal with DC offset, you'll always get something like that number on average regardless of the sound level which isn't particularly informative.
I get values that rest around 430 without any sound, and have very little reactions to loud noises. When I loudly talk into the microphone it'll go up to maybe 450.
Ive been using the AC output (I think there might by a typo in your first paragraph).
The AC output is zero centered, that is, it will have voltages go below ground potential which is out of the Arduino ADC's range. So you need an external bias network or you need to use the DC output of the microphone module. You haven't described how the microphone is hooked up, so we can't really comment on whether it is done correctly.
Whatever the "no sound" level might be should be the DC offset and should be subtracted as per the previous post. The bigger point is that the ADC output will contain a DC and an AC component and one typically wants to do away with the DC portion before any computations evaluating the amplitude of the AC portion.
MrMark:
You haven't described how the microphone is hooked up, so we can't really comment on whether it is done correctly.
I have (Arduino - SPW2430)
3.3V - 3V
GND - GND
A0 - AC
In using the DC bias of the microphone, are you recommending I take in readings from DC ( ie D2 - DC) and subtract that value from my AC value before I put it into the running average?