Picture of Frequency Detector using PIC 12F683 Processor
This project describes hardware and software I have developed which allows a small 8 bit PIC microprocessor to function as a single frequency detector or tone decoder. 

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.
1-40 of 60Next »
renju12345 months ago

i am very much interested in ur project. pls clarify the foll doubts:

1. will this project work with pic18f6520?

2. can this be changed for higher freq ranges? khz or mhz?

3. if yes, how to change the program?

4. do u use adc input channel for freq detect?

5. if so, can the program be carried out in such a way that we know in which channel the freq is detected?

6. can u help me with the pgmming? ill do the hardware part

boomer488 months ago

Not sure if you are still monitoring this post but I'll give it a try. I found this project interesting but both versions of the source code appear to be truncated. Several labeled routines are missing when I try to assemble it. The files are also not formatted but that is a minor inconvenience.

DrDiodac2 years ago
Trying to make the hex file but did not quit. MPLAB makes mistakes and the hex file that is included here, when you try to download recorded as TMP ..
Please help me ... if someone could send me an e-mail the latest code in hex​​?
Thank you,
DrDiodac2 years ago
Great topic, sorry for my childish question :) I am not a good programmer. How do to lower the entry threshold of 100Hz for example, 30? would range from 30 Hz or even lower. This is a big change in the program?
TaZzZz2 years ago
Hi there,
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.
LargeMouthBass (author)  TaZzZz2 years ago
Do you have a PIC programmer? I use one that I purchased from www.melabs.com years ago, but there are many other sources. There are also plans out there to build your own, but I haven't ever tried them so I can't give more guidance there.
tk5ep2 years ago
Hi, Thanks for the help.

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,
LargeMouthBass (author)  tk5ep2 years ago
I think that it is still necessary to use a crystal, otherwise the center of the response will be different from on processor to the next, and my vary over temperature as you discovered. If an oscillator with a greater tolerance is used there will be a corresponding change to the sample rate, and since the coefficents used are a function of the sampilng rate, the response will be different fhan expected.

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"...
tk5ep2 years ago
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 ?
LargeMouthBass (author)  tk5ep2 years ago
I've been experimenting with the code today, and found the same issue you describe. I also found that the center frequency was low for what should have been about 1750 Hz. I tried using the coefficients for slightly higher frequencies, and found that the closest I could get was to use the values for 1760Hz. This resulted in a response that was centered around 1755Hz.

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.
tk5ep2 years ago
Hi again !
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.

LargeMouthBass (author)  tk5ep2 years ago
I checked my code, and I did set it up for XT mode.

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.
HI !

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.

tk5ep tk5ep2 years ago
I noticed that using a scope probe introduces some additional capacitance and that reading is disturbed by it.
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.
tk5ep2 years ago
HI again !
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 ?

LargeMouthBass (author)  tk5ep2 years ago
I've made a modified version of the 1750Hz code for use with an external 8 MHz crystal (attached to pins 2 and 3). The threshold setting has been changed to pin 6.

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.
Wow !

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 !
LargeMouthBass (author)  tk5ep2 years ago
I will send the asm file if the code checks out. Let me know once you get a chance to test it with the crystal.

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 ?


tk5ep2 years ago

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.

tk5ep2 years ago
Hi !

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,
LargeMouthBass (author)  tk5ep2 years ago
I couldn't say offhand exactly what the cause is. One thing I should add is that the constants I used in the fixed frequency code were for 1748 Hz, as they were calculated out in 4Hz increments. The next highest frequency was 1752Hz, so still 2 Hz off your target.

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.
tk5ep2 years ago
Hello LargeMouthBass,

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 !

LargeMouthBass (author)  tk5ep2 years ago
I'm glad to hear that it is working!

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.
tk5ep2 years ago
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 ?
I'm sure it will be useful to others as well.

Thanks again for this nice circuit !!
LargeMouthBass (author)  tk5ep2 years ago

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.
curious5552 years ago
what is the frequency you set here as default ?? and where to change in the coding?? ( am a beginner help me plz ). How can i know the desired frequency was found by the circuit if serial output is not taken??? i want to switch ON a diode if that desired frequency was found.. is it possible without serial output, help me with any alternative way??? ALSO WHAT IS THE RANGE OF FREQUENCY DOES THIS CIRCUIT COULD DETECT ( am expecting 25khz) plz help me out... its urgent buddy ....
LargeMouthBass (author)  curious5552 years ago
There is no "default" frequency. It is determined by the voltage which is read on an analog input. There is an equation in the text that can be used to find the voltage to apply to the pin to set the desired frequency to detect.

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.
curious5552 years ago
i want analog output to analyse it... ie; i dont want only the detection, also i want the sound output from the pic. plz guide me
LargeMouthBass (author)  curious5552 years ago
This program doesn't output any analog, just the detection output. I assume that you are wanting a narrow filter for audio? That is beyond my present knowledge of DSP, and probably isn't feasible for a general purpose processor like the 12F683 used here. It would need a "real" DSP.
thanks for your response... i hav some queries here . to operate this frequency detector, whether i want to load that .asm directly or i have to write the coding on own ??? plz guide me ,, am just a beginner
LargeMouthBass (author)  curious5552 years ago
The *ASM file is what the assembler program uses to generate the *.hex file that is actually used to program the part. I attached both the asm and hex files to the article. If you just want to program the part with the code I created, use your programmer to load the *.hex file onto it. You won't need to do anything with the asm file just to use my code as-is.

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.
curious5552 years ago
i want to analyse the amplitude i.e; output sound.... plz guide me that how to take the analog signal from the filtered output from the pic
tk5ep3 years ago
Hi !

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 ?

LargeMouthBass (author)  tk5ep3 years ago
I can probably make a separte version of the code that would just do a single frequency. I can also disable the serial output. (The serial output is just for information only, and it is not necessary to use it to use the circuit. It could also just be left disonnected. Disabling it improves response time, but only slightly).

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,
LargeMouthBass (author)  tk5ep3 years ago
For some reason, my file attachments to my earlier message didn't work right. I'll try again. The uploader didn't like the *.asm file externsion, so I had to change it to .txt.

Thanks a million,

I will try this ASAP and will let you know.

Thanks for taking the time to answer me and being so helpful.
LargeMouthBass (author)  tk5ep3 years ago
I've made a special version of the code which is set to detect 1750Hz. Actually, it is for 1748 Hz, as the frequency cannot be selected that precisely with the math I am doing. The serial output has been disabled.

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!
1-40 of 60Next »