Tone Detection
Well, I'm off on another tangent. A little background. Many, many moons ago I built IK3OIL's CW reader. I made a number of improvements to it, but being a CW guy and really enjoying the musical note of CW, I don't actually use the thing all that much. But still, improving it has been an interesting programming exercise.
Some time back now it became obvious that the tone detection was really part of the issue. The PLL (567 or similar) that is usually used for this purpose has a couple of problems. One, it is sensitive to noise. Two, the lockup time is variable, leading to uncertainty in the dit and dah times.
It occurred to me that perhaps the tone detection could be improved by using a PIC (perhaps a second PIC) for the tone detection. With the dsPICs offering up to a half million A/D samples per second (at the time), it seemed like a potential path. The dsPIC also offers an amazing amount of compute power. Initially I kind of thought it would be an easy way to sort the algorithm, then at a later time I could optimize it for a PIC16. In retrospect that seems sort of silly; dsPICs are barely more expensive than PIC16s. I built up a simple board with a dsPIC and did some experimentation, but never really got very far.
This spring I went to the Microchip spring seminar and picked up a 28 pin starter board. This board had a 24F on it, although it would support a dsPIC, but it also had an 18F2450, enabling simple USB communications between the dsPIC and a PC. I played with it for a bit, and after a while realized that the problem I was having with tone detection was really misunderstanding the dsPIC's A/D.
Yesterday I finally made up a cable that would allow me to get audio into the 28 pin board. This board is a lot more convenient since I can send selected debugging information to the PC. Yes, without the USB I can still have a peek with the ICD2, but it isn't nearly as convenient for some things.
N8ERO shared the observation that for the limited case of detecting a sine wave of a specific frequency, a sort of poor man's FFT can be accomplished by subtracting samples 180 degrees apart. The sharpness of the filter can be adjusted by how many samples are used over multiple cycles.
It took me a few minutes to get my head around this, but think about it for a minute. If I take a sample, and subtract the sample 180 degrees later, they will add since they will be a different sign. Now, the sample might be close to the zero crossing, so the result may be small. However, if I now take a sample 90 degrees later than the first, and subtract another sample 180 degrees later, they will have the same additive effect. But, if the first pair of samples was small, the second will be large. The sum of the two differences will tend to be more or less constant, providing the frequency was what I expected. If the frequency is different, the result will be smaller. How quickly it will fall off depends on how many cycles I sample over.
I think, not entirely sure, that for a constant amplitude, the sum of the squares of the differences will, in fact, be a constant. Still have to work the math to be sure.
OK, this is the theory. The next step is to grok some code and see if it works. I hope to get to this today, but I may have to go shopping some distance away which will put this experiment off for a while. But, it is interesting.