Detect 1khz tone from headphone socket

Hi,

I'd be grateful for some help here.

I want to connect the headphone output of a device to a digital pin of an Arduino such that the pin goes high when a 1khz tone appears at the headphone socket.

The only output at the headphone socket will be either nothing or 1khz, so the audio processing side doesn't need to discriminate much or be very intelligent, so I am guessing a simple RC filter of some kind will be adequate. Where I am completely lost is how to convert this signal into a digital level.

I know I could probably do it using the ADC, but I would much rather detect it digitally, this is for a timing application so speed is fairly important.

In terms of experience, I am mainly a software engineer, but I know enough digital electronics to be dangerous, it is analogue that I am pretty inexperienced at. I have a decent scope available.

Thanks in advance!

How accurate and fast does it need to be?
You could use a tone detector chip which incorporates a PLL ( Phase Locked Loop ) these chips are quite cheap. Look at the LM567C

The other way is to amplify the signal with a transistor or op amp and turn it into a square wave, have that trigger an interrupt and time the period between interrupts, or count how many interrupts you get in a set period of time.

Assuming you've scaled and offset the signal appropriately in the analog domain and fed it to a digital pin

long correlated = 0 ;
long counter = 0 ;

void loop()
{
  val = digitalRead (pin) ;
  if (val ^ ((micros()/500) & 1))
    correlated ++ ;
  else
    correlated -- ;
  counter ++ ;
}

Will correlate the pin with a 1kHz (derived directly from micros() call). You just need to look for the ratio of correlated/counter tending to +1.0 or -1.0, and do some housekeeping to reset the counters regularly to prime the system.

Its not perfect, and with analogRead() you'll be able to do a much better job, perhaps using a cosine or complex resonator.

Thanks for the responses. Just to clarify, I don't need to detect that the tone is 1khz, just that is there. It is a test tone, and I need to know when it has arrived. It could be anything, it just happens to be 1khz.

While I say I don't care about ensuring the tone is 1khz, I don't want the circuit triggered by noise or whatever.

Attached is a chicken sketch of what I'm going to try, a band pass filter followed by a BC548 switch.

Seems very crude to me, any comments? I'm particularly concerned about any possibility of damaging either the system under test or the Arduino.

Thanks again.

I'm particularly concerned about any possibility of damaging either the system under test or the Arduino.

No problem with that.
What amplitude is your tone? It will need to be at least 1.4V peak to peak. Possibly more.

How much delay can you stand between the arrival of the tone and signalling its presence?

However I would still use a LM567C.

Yes, amplitude is another issue, very much doubt it will be as much as 1.4v, and also worry the circuit may have to work under conditions where the amplitude (i.e. headphone socket volume) is not under control.

Would like to keep delay below 1ms ish, but any delay being constant is probably more important.

Looking at the 567 now - good call I think - looks like a good solution.

twj:
Yes, amplitude is another issue, very much doubt it will be as much as 1.4v, and also worry the circuit may have to work under conditions where the amplitude (i.e. headphone socket volume) is not under control.

I was going to suggest an envelope follower approach, but varying signal amplitude probably rules that out.

Would like to keep delay below 1ms ish, but any delay being constant is probably more important.

1 ms is a single cycle of the 1 kHz tone which limits how well one can discriminate tone from noise, so it might be helpful if you can better constrain the characteristics of "noise" that can potentially triggers the system. For instance is the expectation that the noise power is fixed while the signal amplitude varies or is the signal to noise nominally fixed.

Very late response to this, but just to say thanks very much for the advice. I changed to 10KHz and used a lm567 - bit of a struggle getting it going, in part due to the awful awful datasheet (FWIW, the Philips one is the best), but works well now. Thanks again for the help.