Such a circuit can be used to detect the presence of a certain frequency within an analog signal, such as an audio signal. I could be used in remote control applications, or to detect musical notes, or for any other situation where a specific frequency must be detected in a signal that may contain other frequencies or noise.
The circuit is based an 8 pin PIC 12F683 microprocessor. Only a few additional resistors and capacitors are needed to complete a circuit that will accept an analog signal and drive a microprocessor output pin high when the selected frequency is present in the signal. The circuit can be used as a frequecy detector IC that is part of some larger circuit of the users design.
The steps that follow detail the operation of the circuit and the program that runs on the processor. A description of the digital signal processing algorithm used by the PIC is included, but it is not necessary to understand it to make use of this circuit.
The code for programming the processor is included as a *.hex file. The source code *.asm file is also provided, to allow a user that is familiar with the Microchip PIC assembly language to modify the program. These files can be found under the step titled “Source Code”.
The operation of the circuit and the function of each component is described in the section that covers the schematic.
Remove these ads by
Signing UpStep 1: Parts and Tools
You will need a programmer for PIC microprocessors. I have seen instructions on this site for building your own programming device, but I cannot speak for any of them. The programmer I use is from a company called Micro Engineer Labs, Inc. at http://www.melabs.com.
It is also handy to have an audio generator of some sort, for testing and experimentation. This can be as simple as a connection to the line out of a PC, CD player, MP3 player, etc.
For example, to verify that the circuit works to detect a certain frequency, just play a file containing that frequency, with the audio output of the playback device connected to the input of the circuit.
A useful program for generating sound files can be downloaded for free at http://www.goldwave.com. This program allows you to create *.wav files containing specific tones, sweeps, etc. very easily.











































Visit Our Store »
Go Pro Today »




I'm trying to build your circuit in my project, however, I don't know how to program the PIC 12F683.
I mean, I can't transfer the program you provide it to PIC 12F683.
So, any clue.
Thanks
So, this confirms that there is no real need to use an external Xtal if the problem comes from the rounded maths.
Not a big issue if you know it...
Anyway, it was fun tracking down the problem and i learned a lot looking at your code !
Thanks again,
The limitations of the math cause the response to be at a slightly different frequency than expected. If the 1754 Hz center frequency (using the 1760Hz coefficients I mentioned in my last email) is close enough to 1750 Hz for your application, then I would use that along with the external crystal oscillator instead of the 1% tolerance internal oscillator.
Working through these issues has identified many things I had not discovered when I first create this project. It has been really helpful to improve the design. If I get time, I would like to investigate these in more detail, and possibly add an update to this article to benefit anyone else who may want to use the program so they can avoid the issues you had to work through.
I'm glad if i could help to improve your design !
It works perfectly on 2 of our repeaters right now. I will see how they age and keep you informed if necessary.
I stay tuned on this discussion, so i will be alarmed when you improve the code one day.
Thanks for you great design and help. I also learned a lot looking at your code. I'm not a programmer, but a "hardwarer"...
I digged into the code and found where to change the threshold pin from 3 to 6.
Now, with a 8 MHz external Xtal and threshold level set on pin 6, the circuit works !
Unfortunately, the bandpass is still not centered on the target frequency...
I measured a center frequency of 1736 Hz for a target of 1748 Hz.
The Xtal frequency is only a few Hz away from 8 MHz. So the problem is somewhere else.... :-(
Can it be that the sin and cosin values are not correct ?
Any guess ?
I think the problem is the limitations in how accurately the coefficients can be represented the way I'm doing it. There isn't really much that can be done about that, as trying to represent them with greater precision means that multiplication operations would take much longer, such that the program wouldn't even be possible on this general purpose processor.
I've attached the hex and asm files from my most recent build, which uses the 1760Hz values for response much closer to what you want. It is configured for HS_OSC.
This time, I've tested the code.
I tried your latest version with an external Xtal, but it does not oscillate.
You say, you used the XT mode, but according to the datasheets, it is to be used up to 4 MHz only.
Maybe, it is the only reason why my Xtal does not oscillate ?
Or maybe there is another problem in the modified source ?
I doublecheked my new board and it looks OK according your new design.
Pin 2 + 3 for the Xtal + capacitors.
Pin 6 AN3 for threshold setting.
Can you have a look on it and/or send me the modified code, so i can make my own tests without bothering you.
Thanks,
I programmed a part with the code and built the circuit using the crystal, but I could not get the crystal to oscillate either. I also tried a program for a different project I built that uses the 12f683 processor with an 8MHz crystal, but the crystal didn't oscillate with that either.
I don't know what to make of that, but I suspect that there may be a problem with the crystal and capacitor circuit. I've only used that setup a couple times before, as I usually just use the intenal oscillator or an external oscillator module if the application requires higher precision.
I plan to try again using an external oscillator instead of a crystal with capacitors. I should know how that turns out in a couple days, and then I can send you actual working, tested code that uses an oscillator module. I'll let you know when I have results.
I wanted to write a post again... I took the original asm file and modified ONLY the config to use the HS_OSC bit.
And now, i have a pure sine wave oscillation at 8 MHz on pin 3 i can see with my scope. Can't figure out why i don't have something on pin2 as this is an input...
I can't test the complete circuit, as i don't know how to modifiy the rest of the program to work with changed pin configuration.
So try to modify XT_OSC to HS_OSC on your latest version (with 1750HZ and changed threshold pin) and send me at least the HEX file.
Thanks for your help.
Using a different probe, i have a clean 4V oscillation that stop only when power supply drops down to 2V !
So, everything is just fine using HS_OSC ! I suppose XT_OSC does not have enough gain to start oscillation at 8 MHz.
I found some time and having 2 other PICs, i programmed them and made some tests.
None of the PICs has the same frequency response.... One does even not detect at the right frequency, being out of band !!
Internal frequency precision seems to be quite critical for your decoding, which os logical if based on time.
So, there must be a huge dispersion in these internal oscillator despite the 1% "high precision" claimed by the data sheet...
Or, there is something else interfering...... I saw in the data sheet that the OSCTUNE register can adjust the frequency..
I heated the PIC with my soldering iron, and the detection frequency changes also, which is quite normal...
I don't know if there is a way to measure and change the internal oscillator, but i think that for precise decoding an extrenal oscillator is mandatory !
Can you try to modify your code, so that i can use the pin 2 and 3 for an external crystal ? Maybe you can use pin 6 left free now (when using a fixed frequency) for the threshold of change the code, for a software defined threshold level ?
Patrick
When you connect the crystal, you will need to have two small caps connected as well, one on each side as shown in the schematic I attached. I've used 22pF caps with an 8MHz crystal on this processor before on another project , and it worked properly.
This code is configured for "XT" oscillator mode, and described in the oscillator section of the 12F683 datasheet.
I haven't tested this code, but the modifications were very minor so hopefully it works.
Thanks for that !
I will test it asap and keep you informed. Can you post the modified assembler, so i can see how you did that ?
BTW, on the 3 PICs i've tested, the bandpass is exactly the same. 34 Hz, so about 2%.
Thanks again !
I found the time to build a new pcb and ordered some 8 MHz Xtals.
I programmed a new PIC. But unfortunately, the xtal does not oscillate at all.
Can you check you hex file if it is really configured for XT ?
Thanks,
Thanks for the explanations.
At least, we could make a test with a modified code for an external 8MHz oscillator, so we can eliminate one source of inaccuracy.
I would be interested to test it; though.
Patrick
Yes, i already made an article on my page, but for the moment only in french. I will translate it in english for my radioamateur visitors. Actualy, it looks like that : http://www.egloff.eu/index.php?option=com_content&view=article&id=37&Itemid=202&lang=fr
I have added the more or less universal pcb design i've made with KICAD.
BTW, i made some measures and for a frequency target of 1750Hz, the decoder detects from 1713 to 1760 Hz.
Is there any reason for this asymetrical bandpass ? For a centered bandpass, should i choose a higher target frequency ?
Thanks and apologize again,
Patrick
Part of the reason for the actual detection range may be the limitations of how accurate the the math routines are. This PIC has no native multiplication instructions, just 8 bit add and subtract, so I had to write them myself. There is some inaccuracy and rounding involved, as I had to keep them simple so they would run fast enough on a general purpose PIC with only 8 bit add and subtract.
Another source of inaccuracy may be from the fact that the program I wrote has the processor using an internal 8MHz oscillator, which doesn't have the accuracy of a crystal.
I would suspect that as a result of the various sources of inaccuracy, the actual center frequency is about 1737Hz. In general the passband should be symetrical.
I hope that this doesn't impact your application. If it does, I could look into a slightly modified version of the code that would use an external 8MHz oscillator instead of the internal one.
I have to apologize !
Your modified code for a fixed frequency works perfectly !
I make some new tests today and found a broken transistor on my test board ! I should have double checked it before.... :-((
You know what ? I'm happy !
Thanks and apologize again !
Patrick
Are you going to include details of your project on your web site?
Anyway, I'm glad it seems to be working out. Please let me know if you need any other help.
I finaly found the time to test your design ... :-((
I made a small board yesterday evening and wired it right now.
The modified 1750 Hz version you put here does not work. The serial output is disabled, but no tone is detected.
I tested with the normal software and it works just as predicted... So, there must be a small mistake in the modified code.
One error i noticed in your text, the part describing the frequency selection.
The voltage divider used for the frequency setting should use R3+R4 and not R1+R2 in your formula.
I don't have the assembler to make my own tests in modyfing the code to make it work at a given frequency. This would still be fine, as i wouldn't be dependent of the supply voltage fluctuation.
Do you allow me to translate it in french and put it on my homepage ?
http://www.tk5ep.tk
I'm sure it will be useful to others as well.
Thanks again for this nice circuit !!
I'm sorry to hear that the 1750Hz code didn't work. It sounds like you can still make your application work by using the regular code and selecting the frequency using the analog input.
Thanks for pointing out the error. I have corrected the article to refer to the right resistors.
If you ever want to modify the code, the assembler I use is the free MPASM from www.microchip.com
When you say you want to translate to French, are you referring to the text of the article? That should be fine, as I have posted all the details of the project here, so go ahead. Perhaps make a reference back to the original article. If anyone else can make use of the code that would be great.
Thanks for your interest in this project, I'm glad you could make use of it.
It is not necessary to use the serial output for any functions. It is there just for user information/debugging if needed. You can tell if the frequency is detected by the state of the detection output alone.
Unfortunately, the range of detectable frequencies does not extend to 25kHz. The detectable range is only 148Hz tp 2148Hz. It was designed for use in detecting audio tones. The Goertzle algorithm concept and the related mathematics can apply be applied to any frequency, if it is sampled at a sufficient rate and the samples can be processed in time. With the project shown here it is not possible to go beyond that range, as to do so it far outside the processing capability of this small general purpose processor that is only running on an 8MHz clock.
If you want to make your own modified versions of the code, you will have to open the *.asm file in Microchips MPLAB software, make your changes, and then reassemble to generate a new *.hex file that reflects your changes.
Great project !
I would like to use your circuit for a local repeater. I want to replace the unstable NE567 decoder with a small addon board.
I only need a fixed frequency ( 1750 Hz ) and no serial data output. So for simplicity and no tuning, i would like to remove the divider for the target frequency.
I saw in the previous posts that someone modified the code to do that. I'm not a programmer, so can you help me to do that ?
Thanks
I won't have time to test the new code myself to verify performance though. If you have a PIC programmer, I can send you a hex file for programming, and you can test it from there.
Let me know if you think that would work for you.
Yes, that would be fine. If you can send the asm file as well, it would help me to understand what you did and probably be able to modify it for any tone.
I don't have 12F683 PICs, but will order a few. I have a PIC programmer.
BTW, is the internal clock precise enough for a stable operation ? Wouldn't a external Xtal be better ?
Thanks for the answer,
I will try this ASAP and will let you know.
Thanks for taking the time to answer me and being so helpful.
I made the changes by commenting out the sections that read the frequency setting. I deactivated the serial output by having the code immediately return from the subroutine that ordinarily would transmit the characters. I've added notes to the asm file to show where I have made the changes. I've left the code in the asm file, even unused code, for reference. The asm for the regular version is attached to the main article.
I have not tried this special version of code in circuit, but the modifications were very straightforward, so the should work. Let me know if the code doesn't work.
The width of the frequency response is fairly narrow, refer to some of the diagrams in the main article.
The internal oscillator has a tolerance of about 1%. I've found that it works well.
The special version of code I made uses the internal oscillator, but since the serial is not used, you could connect an external oscillator to pin 2 (RA5) and modify the code to use an external oscillator.
I hope the code works for you. Let me know if you have any problems. I'd like to hear about your repeater project when you have it finished!
I'm trying to design a circuit that detect/differentiate frequencies in the ranges of 190hz, 250hz and 285hz. Thanks!
The design I made for this instructable should work well for your application. One downside might be if you don't have a PIC programmer available and so you would need to make or buy one.
The 567 is probably somewhat less expensive than a 12F683, although the price of each is not very great. I think the 12F683 is less than $2 in small quantities from Digikey.
One strength of the detector in my instructable is that it is easily configurable using just a voltage divider on the frequency select input. You could use 3 processors running the software included in the instructable. The analog signal inputs could all be driven in parallel. A separate voltage divider would be needed on each process to select the desired frequency. The three outputs would easily interface to whatever logic your application needs.
you said, "if you don't have a PIC programmer available..." yea.. I'm sure one of these days I'll want to move on from the Arduino prototype playland and actually hard code something.. eh?
So just for curiosity, could this code be easily adopted for compiling into an Arduino and/or why hasn't someone done that? cheers,