Detect a single high pitched tone, like a dog whistle

Hello -

Trying to figure this out and keep getting confused by what I'm reading.

Here's what I'm looking for, I think it's fairly straightforward: I play a short 18 kHz tone from a speaker in my hand. My Arduino, six feet away, detects the 18 kHz tone. That's it - I basically want to use it to trigger my Arduino into action. So, the audio sensor/program has to be able to distinguish between the 18 kHz tone and other background noises.

Any any idea what would work?

My Arduino, six feet away, detects the 18 kHz tone.

That’s great. What’s the problem?
Care to share?

Perhaps the original sentence should have been:

My Arduino, six feet away, shall detect the 18 kHz tone, rejecting other sounds.

Unfortunately, that is not at all straightforward and in any case, a clearer specification is needed.

What are the expected background sounds in the vicinity?

Will the 18 kHz tone be relatively loud, compared to background?

What is the allowable range of frequencies to be detected?

I posted some code that detects a single tone in post #16 of this thread: Walkie-talkies to control DSLR camera via Arduino - Project Guidance - Arduino Forum

It won't work directly for your case because the sampling rate isn't high enough to resolve 18 kHz and the filters wouldn't run fast enough to keep up with faster sampling.

You have at least three non-trivial issues following from your requirements.

  1. Sampling fast enough which is faster than "analogRead()" supports. Something like this would be required presuming you're using an Uno or similar: Fast sampling from analog input - Yet Another Arduino Blog

  2. Detecting the power of the tone of interest. Possible approaches include a full band frequency transform via FFT, bandpass filtering as in my example from the other thread, or a single bin frequency transform ala the Goertzel algorithm.

  3. Finally there's figuring out a thresholding scheme to determine whether or not your tone of interest is present in the presence of interfering noise.

18 kHz... All children, dogs and cats in the nearby area will hate you for this!

It may be easier to try and hack an HC-SR04 for this purpose. Now if only there would be an easy way to reprogram its microcontroller... so it doesn't need a trig signal to start listening for incoming pings!

wvmarle:
It may be easier to try and hack an HC-SR04 for this purpose. Now if only there would be an easy way to reprogram its microcontroller… so it doesn’t need a trig signal to start listening for incoming pings!

Typical Murata-style ultrasound transducers are highly resonant at their operating frequency (40kHz) - they won’t respond at all well at 18kHz.

No intention to change that frequency for reasons given above... just use 40 kHz.

wvmarle:
It may be easier to try and hack an HC-SR04 for this purpose. Now if only there would be an easy way to reprogram its microcontroller... so it doesn't need a trig signal to start listening for incoming pings!

The HC-SR04 has a string of amplifiers following the receive transducer followed by a comparator, so it's effectively implementing a 1-bit ADC sort of thing. A while back I tapped a wire off the "signal" net (pin 10 on the HC-SR04 microcontroller) and ran that into an Arduino digital input pin as part of an experiment with ultrasonic communications links, so the hardware part of the proposed hack is pretty easy.

TheMemberFormerlyKnownAsAWOL:
Typical Murata-style ultrasound transducers are highly resonant at their operating frequency (40kHz) - they won't respond at all well at 18kHz.

If it's acceptable to change the operating frequency to 40 kHz for this problem, resonance is an advantage since the transducer will effectively reject out of band signals. In the aforementioned ultrasonic coms experiment, FSK didn't work well even going just a few hundred Hz off of center because the receiver presumably didn't see it.

One could type the words "arduino audio analyzer" into ones favorite internet search engine, where one would find some good info about FFT. Then one could use a ESP32, the ESP32 A:D API and freeRTOS using a task set to run round robin to detect the desired frequency.

An NE567 is a hardware solution, the device is rather good at detecting tones.

About 25p.

srnet:
An NE567 is a hardware solution, the device is rather good at detecting tones.

About 25p.

That appears to detect an electrical signal. OP is attempting to detect an audio signal through the air.

OP is attempting to detect an audio signal through the air.

A microphone and amplifier is required in either case.

+1 for the phase locked loop NE567 idea.

bigred1212:
OP is attempting to detect an audio signal through the air.

So how do you detect an audio signal 'through the air' ?

Do please tell.

I use my ears, but who knows what bigred1212 has in mind?

srnet:
So how do you detect an audio signal ‘through the air’ ?

Do please tell.

Simply trying to clarify that the tone was being transmitted through the air and that OP did not have a wired controller. You know, the old fashioned way- compression waves through the atmosphere.

I think the things MrMark was alluding to (“hearing” the tone to be able to act on it) are important.

jremington:
I use my ears, but who knows what bigred1212 has in mind?

I think one of OP's issues is finding suitable "ears" for his Arduino.

MrMark:
I posted some code that detects a single tone in post #16 of this thread: Walkie-talkies to control DSLR camera via Arduino - Project Guidance - Arduino Forum

It won't work directly for your case because the sampling rate isn't high enough to resolve 18 kHz and the filters wouldn't run fast enough to keep up with faster sampling. . . .

Just for giggles I compiled the code from the thread linked above for an STM32F103C8T6 board using the stm32duino.com boards package and it runs at a 40 kHz ADC sample and filter cycle rate. Changing only the "sampleIntervalMicros" parameter to 25 makes everything run 16x faster than the Uno thus giving tone detection at 16 kHz rather than 1 kHz as in the original design. One could recalculate the filter parameters in "filterloop()" to get 18 kHz.

So if the 25 pence dedicated frequency detection chip doesn't float your boat, throwing more processor at the problem is another option.

It is pretty awesome how easy it was to go to a completely different processor family in this case.