The idea of a sound trigger with better sensitivity than the "clap sensors" and some reasonable noise immunity touched on some ideas I've been working on, so I put together a little audio signal processing sketch. The code below triggers (the built in LED) upon receiving a 1 kHz tone. It seems robust against tones outside of that (excepting image frequencies) and noise in the environment in the sense that there weren't noticable false triggers.
I tested using an Android phone app as the tone source. In a quiet room it rejects tones more than about 5 Hz off center. Outdoors, range from the tone source was limited, presumably because of greater background noise.
The approach is to compute the running average signal power through a narrow band pass filter at 1 kHz center and compare that with the running average of the total signal power. The LED is turned on when the 1 kHz power exceeds half the total signal power.
/* Sketch implements single tone detection using a narrow bandpass filter
* Tone detection occurs when integrated power out of BPF is greater than
* one half the integrated power of the full ADC band
*/
// ***************************************************************************
/* Integrator class maintains running average of input using recursion formula
xAvg = x + xAvg - xAvg/(2**N) where N is a positive integer
Effective integration period is on the order of 2**N
*/
class Integrator {
public:
long int xAvg ; // Running average left shifted N bits
int shift ;
Integrator(int N) { // Constructor for class
xAvg = 0 ;
shift = N ;
}
// Update average with sample and return updated average
long int integrate(long int xIn) {
xAvg = xAvg + xIn - (xAvg >> shift) ;
return (xAvg >> shift) ;
}
} ;
// ***************************************************************************
/* Digital bandpass filter for sample rate 2500 Hz, passband 995-1005 Hz */
/* Using: https://www-users.cs.york.ac.uk/~fisher/mkfilter/trad.html */
/* Digital filter designed by mkfilter/mkshape/gencode A.J. Fisher
Command line: /www/usr/fisher/helpers/mkfilter -Bu -Bp -o 1 -a 3.9800000000e-01 4.0200000000e-01 -l */
#define NZEROS 2
#define NPOLES 2
#define GAIN 8.057026980e+01
static float xv[NZEROS + 1], yv[NPOLES + 1];
static int filterloop(int xIn) {
xv[0] = xv[1]; xv[1] = xv[2] ;
xv[2] = xIn * (1 / GAIN) ;
yv[0] = yv[1]; yv[1] = yv[2] ;
yv[2] = (xv[2] - xv[0]) + ( -0.9751778762 * yv[0]) + ( -1.5980786463 * yv[1]);
return int(yv[2]) ;
}
// ***************************************************************************
// Parameter and object definitions
#define sampleIntervalMicros 400 // Sample interval in microseconds
long int nextInterval ; // Time of next ADC collection cycle
Integrator adcRunningMean(8) ; // Integrator object to track ADC offset
Integrator channelPower(6) ; // Integrator object to track full band channel power
Integrator tonePower(6) ; // Integrator object to track filter band power
void setup() {
digitalWrite(LED_BUILTIN, LOW) ;
pinMode(LED_BUILTIN, OUTPUT) ;
Serial.begin(115200) ;
nextInterval = micros() + sampleIntervalMicros ;
}
void loop() {
if (micros() >= nextInterval) {
int x = analogRead(A0) ;
long int adcMean = adcRunningMean.integrate(x) ;
long int y = filterloop(x) ;
long int chanPower = channelPower.integrate(sq((x - adcMean))) ;
long int sigPower = tonePower.integrate(sq(y)) ;
nextInterval += sampleIntervalMicros ;
if (2 * sigPower > chanPower) {
digitalWrite(LED_BUILTIN, HIGH) ;
} else {
digitalWrite(LED_BUILTIN, LOW) ;
}
}
}
The bandpass filter was designed using the tools at https://www-users.cs.york.ac.uk/~fisher/mkfilter/trad.html with the parameters Filter Type Butterworth/Bandpass, Filter Order 1, Sample Rate 2500 Hz, Corner Frequencies (950, 1005). The tool produces C code which is used essentially verbatim.
The integrator class defines a simple no multiply low pass filter that is used to average the DC offset of the ADC, to average the power out of the 1 kHz BPF, and to average the power out of the ADC.
The sketch was run on an Uno with a max9814 microphone board configured for 60 dB gain on input A0. I initially used a FC-109/max9812 20 dB gain board which was insufficiently sensitive for reliable operation.
The ADC sampling rate must be uniform and consistent with the band pass filter design of 2.5 kHz sampling. Sampling rate is controlled by using a "BlinkWithoutDelay" sort of structure to sample at a 400 microsecond interval. The signal processing bit as written is sufficiently fast to keep up with a 350 microsecond sample interval, but not much more.
The sketch serves as a neat demo of image frequencies as it will trigger the LED at any frequency (n2500 + 1000) or (n2500 - 1000) kHz where n = (0, 1, 2, 3, ...).
I'm not sure how practical any of this is for the original poster's problem, but I got the chance to work through some ideas and it may be of use to someone.