On Wed, 10 Sep 1997 14:26:21 -0400 Pierce Nichols writes: > DTMF decoders are cheaper than most PICs, I think, but I am >not >sure. Doing it with a PIC is awfully klugey, but it might be a fun >thing >to try... > I've tried the method outlined by Scott Dattalo on his web page. It does work, but it requires nearly all the processing power of a 20 MHz PIC in order to detect any of the 8 tones arbitrarily. Since I was hoping to use a 16F84, I abandoned the project. I could push a 16F84 to 16 MHz but it definitely wouldn't do 20. My implementation also needed about 50 bytes of RAM. It is feasible and may be good for some applications. Overall I'd recommend using a decoder chip, especially if the tone input is not going to be perfectly clean. Though I only tested the PIC decoder with a direct connection to a tone telephone, I wouldn't expect it to work very well with noisy tones. The method is as follows. All of the processing can be done in a timer interrupt at about 15 KHz, so the tone decoder can operate independent of the main program other than taking a lot of its CPU cycles away. Each of the processing steps below is serviced once per interrupt. Create a local tone at each of the 8 frequencies (4 rows and 4 columns). I used DDS with 16-bit phase accumulators. Every interrupt, add a constant (tone frq * 65536 / interrupt frq) to the accumulator. The MSB of the accumulator will be a square wave at the tone frequency. The MSB xor the second most-significant bit will be a square wave at the tone frequency, but quadrature in phase to the MSB (the usefullness of this is in Scott's description) Sample the input (1 bit). I used 3 gates of a 4069 with the first one biased for linear operation and capacitively coupled to the phone. This processes the tone into a square wave suitable for a PIC input. Exclusive-or the input sample with all the tones, and the quadrature of all the tones. If the input contains a signal near the tone frequency, some of these exclusive-or results will contain a predominance of ones (or a predominance of zeros if out of phase) Filter the exclusive-or results. I used a simple filter which was an 8 bit variable which increased by 1 if the xor was a match, and decreased by 2 if it didn't. Half of the filters consider a result of 1 to be a match, the other half use the same results but call 0 a match. There are a total of 32 filters, 4 for each tone. The main program looks at the filter results, and if any one of the 4 filters for a particular tone is higher than a threshold (I used 32 IIRC) that tone is present in the input signal. The filtering needs to be improved. Sometimes the tone would drop out periodically. Lowering the threshold some to prevent that caused other tones to be falsely detected. If your application doesn't need to detect all 8 tones simultaneously then it can be optimized to use a lot less PIC resources by only looking for one tone at a time. An example of this would be an answering machine which listens for it's owner to press 1-2-3-4 to replay any messages remotely. The program would look only for the two tones that represent button #1 at first, if those are detected it would retune for tone 2, etc. If no tone in the sequence is detected within a timeout time it would go back to listening for the first one. This could be done easily by running 2 tone generators and 8 filters and changing the DDS constants depending on which tone is expected.