Hello!
I am currently working on a project using an Arduino and trying to get it to recognize certain sounds. I originally started with the ADC in free running mode and just pulled the value at the max frequency allowed. This worked decently well but the input was noisey (using elecret mic) so I constructed a sallen key band pass filter to block out most frequencies above 1.3KHz and below 50Hz. This gave an extremely clean input, and using a processing sketch to visualize the data, a snore could easily be picked out. The 200Hz resolution was far from optimal though so instead brought the sampling rate down to ~4KHz. However after changing the sampling rate the graph no longer responds to snore samples and seems to be very unreliable.
My code currently looks like this:
#define LIN_OUT8 1
#define SCALE 256
#define FHT_N 256 // set to 256 point fht
#include <FHT.h> // include the library
#include <TimerOne.h>
int fht_mine[FHT_N];
short ADCcount;
byte handshakeComplete;
void setup()
{
ADCcount = 0;
handshakeComplete = 0;
Timer1.initialize(250); //create timmer with period of 250us
Timer1.attachInterrupt(pingADC); //attach function pingADC() to timer1
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
Serial.begin(115200); // use the serial port
establishConnection(); //run the function to create a connection with host program
}
void loop(){//nothing to see here
}
void establishConnection()
{
while (Serial.available() <= 0) //wait for incoming byte (in this crude handshake we don't care what that byte is)
{
Serial.write('A'); // send a capital A
delay(300);
}
Serial.flush();
handshakeComplete = 1;
}
void pingADC()
{
if (handshakeComplete == 0) //if no connection to host software has been made, just exit
{
return;
}
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
fht_mine[ADCcount] = k; // put real data into bins
if (ADCcount == (FHT_N - 1))
{
ADCcount = 0;
cli(); // UDRE interrupt slows this way down on arduino1.0
int i = 0;
while (i < FHT_N) //copy all data over to another array in case timer is called again, therefor data will not be overwritten
{
fht_input[i] = fht_mine[i];
++i;
}
fht_window(); // window the data for better frequency response
fht_reorder(); // reorder the data before doing the fht
fht_run(); // process the data in the fht
fht_mag_lin8();
sei();
for(i=0;i < FHT_N / 2;i++) //function to send FHT data over serial port
{
Serial.write(fht_lin_out8[i]*fht_lin_out8[i]);
i++;
}
for(i=0;i < FHT_N / 2;i++) //function to send raw analog data over serial port
{
Serial.write(fht_mine[i]);
i++;
}
}
else
{
++ADCcount; //increment count
}
}
So basically what I am wondering is, because I lowered the sampling rate I also lowered the max frequency and increased resolution, but did that come at a cost of accuracy?
any help or suggestions on how to clean up the input would be greatly appreciated!