Detecting audio of particular frequency?

I’m considering using an electret microphone and pre-amp to detect brief tone bursts. An Arduino UNO sketch would use the pre-amp’s output as its input to A0. The two tone bursts would be approximately 1kHZ and last about 200ms each, separated by a gap of 100-500ms. (They result from the press of a button.)

I’m fairly confident about getting an output in quiet conditions. But is it feasible to ensure that the program reacts only to a narrow range of frequency, say 900 - 1100 Hz, to avoid unwanted triggering?

Or is 16 MHz too slow for my idea to be practical please? A brief test showed that a loop doing nothing but serial print millis() took about 1ms.


According to theory sampling a 1000 Hz signal calls for more than 2000 samples per second. That gives a maximum of 500 microseconds between samples. Check the controller data sheet for the time used for one ad conversion. I don't have the figures in my head right now.
Note that one dummy conversion is needed to make registers set. After that the speed is better.

Google "Goertzel"

Ha, I was trying to Google, "that efficient algorithm for detecting single frequencies" but "Goertzel" works much faster. Thanks.

@OP, I think this still leaves a sampling problem, in order to finesse the audio input part, it's probably necessary to perform ADC conversions via a timer interrupt, or built in automatic free running ADC operation on a processor that supports it. The Goertzel transform will not work unless you have properly timed samples.

As you have discovered, polling the ADC in loop() won't give you the timing accuracy you need.

Terry- Please post your project here if you get it working.

I did something similar to decode DTMF telephone signaling:


ONLY for a band limited signal; and that implies a signal that is not (significantly) time limited.

Thanks all, much appreciated. Lot of learning ahead re FFT, Goetzel and ADC in general. I might invest in that or, frankly more likely, decide that the relatively trivial application doesn’t justify the effort!

For anyone curious, its only a ‘fun and learning’ project. When I or my wife tap in the burglar alarm code before exiting the house I want to deliver a reminder about something. I’m unwilling to access the commercial alarm’s PCB so thought of recognising the ‘beeps’ described. (An earlier test using instead a capacitive touch switch failed, as the alarm case is itself earthed.)

I’ll see if a less ambitious detector would cut the mustard instead. (“In the last 5 seconds have there been at least two AC signals greater than 100ms in length and over 400mv in amplitude throughout, with a gap of over 50ms?”)

Might even lapse into some legacy (solder!) practical electronics and try a CR filter after the preamp, plus further amplification (the signal to A0 is currently only around 500mv pk-to-pk), and then a rectifier before the result to D6 instead of A0.


@johnerrington That's interesting - could you enlarge upon that a bit? I don't think I understand the implications of the limitations you mentioned.

Don't forget the 'r' in Goertzel, otherwise you won't find it. :grinning:

If you put the microphone very very close to the device (i.e. a few centimeters), you might be able to get away with simple amplitude detection (perhaps also require a certain amplitude sustained for a certain minimum time interval). Sound energy follows the inverse square law, drops off rapidly with distance. Think about the microphones on helicopter pilot headphones. They can talk to ground and passengers, inside the cabin, it is so loud you couldn't hear yourself yell. It's because they are almost kissing the mike.

...and you can use an op amp bandpass filter:

A simple sine wave V = A sin (2 pi() f t + P) (for t = -00 to +00 )
where 00 represents infinity, P represents the phase phi
may be properly represented by a series of samples at no less than 2f.

A time-limited (or windowed) sine wave has more frequency components which is why an FFT offers different windowing functions which affect the results in different ways.

Sampling a non-trivial stochastic wave is even more complicated.

1 Like

You can use I2S microphone and a SAMD21 board such as MKR ZERO to get the full spectrum of the sound then isolate required frequency with included ARM FFT library

Fantastic - thanks, @johnerrington. Really appreciate that cogent summary. I'll be following up those links for further study. :+1: :grinning:

1 Like

Theoretically, this may be so, but it doesn't provide useful permission to omit a filter.

For practical purposes, it must be band limited, or else the base band (band of interest, containing frequencies less than the sampling rate), will be polluted with unusable information from signals that are present which are greater than the sampling frequency. This manifests itself as noise.

Also, in the OP's case, the sampling window is definitely broad enough to make an FFT or a Goertzel transform function effectively.

Thanks aarg. Unfortunately the buttons are not only those very ‘soft’ type but they are directly behind the PCB. So the mic would at best be at least 4 cm away from the pressed point.

Those 500 mv signals I mentioned from the pre-amp were taken with the tiny electret touching a small 64 ohm speaker.

I may try the op-amp filter though.



Are you trying to detect the "beep" from a button press?

What is the application?

Thanks.. Tom... :smiley: :+1: :coffee: :australia:

No problem there, sounds close enough. I'm fairly sure the buttons themselves don't beep. There would be some speaker in the device. If you don't know that, there's not much point in talking about op amps and bandpass filters etc.

I believe it's time to see images of this mystery device with buttons...

Hi Tom,

Yes. As described in my post #8.