|
|
View previous topic :: View next topic |
Author |
Message |
Ln_mark7930
Joined: 06 Mar 2009 Posts: 21
|
DTMF |
Posted: Wed Jan 11, 2012 12:33 pm |
|
|
Hi boys,
I want to do a circuit that generate DTMF tone. I'm using EX_DTMF.c example for my PIC18F876A. my clock is 20 Crystal, but there is a problem with signal generated. I install also a 2W MONO audio amplifier at the ouput pin.
I use 220 Ohm resistors instead of 200 Ohm: I think that it's not the problem.Telephone don't recognize Tone.
I have not oscilloscope to view the ouput signal, so it's too difficult understand what''s the problem. I check the output signal with DTMF Tone Decoder (DEMO VERSION) software and seems witch the frequency of N°6 are 742,1Hz (Row) and 1484 Hz (Column).
Does some have tested this example? Does it work?
I try also the other example ( the other with 2 array of waves) but with the same result.
Follow the code of my source:
Code: |
#if defined(__PCB__)
#include <16C56.h>
#fuses HS,NOWDT,NOPROTECT
#use delay(clock=20000000) // must be 20 MHz
#elif defined(__PCM__)
#include <16F876A.h>
#fuses HS,NOWDT,NOPUT,NOPROTECT,NOLVP,DEBUG,NOBROWNOUT,
#use delay(clock=20000000) // must be 20 MHz
#elif defined(__PCH__)
#include <18F452.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000) // must be 20 MHz
#endif
CONST unsigned int SINE_WAVE[200] = {
128,132,136,139,143,147,150,154,158,161,165,169,172,176,179,
182,186,189,192,195,199,202,204,207,210,213,215,218,220,223,
225,227,229,231,233,235,237,238,240,241,242,243,244,245,246,
247,247,247,248,248,248,248,248,247,247,247,246,245,244,243,
242,241,240,238,237,235,233,231,229,227,225,223,220,218,215,
213,210,207,204,202,199,195,192,189,186,182,179,176,172,169,
165,161,158,154,150,147,143,139,136,132,128,124,120,117,113,
109,106,102, 98, 95, 91, 87, 84, 80, 77, 74, 70, 67, 64, 61,
57, 54, 52, 49, 46, 43, 41, 38, 36, 33, 31, 29, 27, 25, 23,
21, 19, 18, 16, 15, 14, 13, 12, 11, 10, 9, 9, 9, 8, 8,
8, 8, 8, 9, 9, 9, 10, 11, 12, 13, 14, 15, 16, 18, 19,
21, 23, 25, 27, 29, 31, 33, 36, 38, 41, 43, 46, 49, 52, 54,
57, 61, 64, 67, 70, 74, 77, 80, 84, 87, 91, 95, 98,102,106,
109,113,117,120,124};
int index1,index2,inc1,inc2;
int8 freq=13;
#INT_RTCC
void wave_generator() {
int wave = 0;
set_rtcc(freq); //13 // when clock is 20MHz, interrupts every 100us
wave = ((long)SINE_WAVE[index1]+(long)SINE_WAVE[index2])/2;
output_c(wave);
index1 += inc1;
index2 += inc2;
if(index1 >= 200)
index1 -= 200;
if(index2 >= 200)
index2 -= 200;
}
//#define DTMF_ROW1 14 // for 700 Hz, increment this many times every 100us
//#define DTMF_ROW2 15 // for 750 Hz, increment this many times every 100us
//#define DTMF_ROW3 17 // for 850 Hz, increment this many times every 100us
//#define DTMF_ROW4 19 // for 950 Hz, increment this many times every 100us
//#define DTMF_COLA 24 // for 1200 Hz, increment this many times every 100us
//#define DTMF_COLB 27 // for 1350 Hz, increment this many times every 100us
//#define DTMF_COLC 30 // for 1500 Hz, increment this many times every 100us
#define DTMF_ROW1 14 // for 700 Hz, increment this many times every 100us
#define DTMF_ROW2 15 // for 750 Hz, increment this many times every 100us
#define DTMF_ROW3 17 // for 850 Hz, increment this many times every 100us
#define DTMF_ROW4 19 // for 950 Hz, increment this many times every 100us
#define DTMF_COLA 24 // for 1200 Hz, increment this many times every 100us
#define DTMF_COLB 27 // for 1350 Hz, increment this many times every 100us
#define DTMF_COLC 30 // for 1500 Hz, increment this many times every 100us
void generate_dtmf_tone(char keypad, long duration)
{
index1=0;
index2=0;
inc1=0;
inc2=0;
if ((keypad==1)||(keypad==2)||(keypad==3)) inc1=DTMF_ROW1;
else if ((keypad==4)||(keypad==5)||(keypad==6)) inc1=DTMF_ROW2;
else if ((keypad==7)||(keypad==8)||(keypad==9)) inc1=DTMF_ROW3;
else if (keypad==0) inc1=DTMF_ROW4;
if ((keypad==1)||(keypad==4)||(keypad==7))inc2=DTMF_COLA;
else if ((keypad==2)||(keypad==5)||(keypad==8)||(keypad==0))inc2=DTMF_COLB;
else if ((keypad==3)||(keypad==6)||(keypad==9))inc2=DTMF_COLC;
setup_counters(RTCC_INTERNAL,RTCC_DIV_2);
enable_interrupts(INT_RTCC);
enable_interrupts(GLOBAL);
while(duration-- > 0)
{
delay_us(1000);
}
disable_interrupts(INT_RTCC);
output_c(0);
}
////
//
// tone_out.c 2002/02/20
///* -------------------------------------------------------------------------------
// F_Low F_High TONE HM9270_Q4 Q3 Q2 Q1 Hex_from_HM9270
// pin_A3 A2 A1 A0 PORTA & 0x0F
//------------------------------------------------------------------------------- */
//#define TONE_1 0x01 // 697 1209 1 0 0 0 1 1
//#define TONE_2 0x02 // 697 1336 2 0 0 1 0 2
//#define TONE_3 0x03 // 697 1477 3 0 0 1 1 3
//#define TONE_4 0x04 // 770 1209 4 0 1 0 0 4
//#define TONE_5 0x05 // 770 1336 5 0 1 0 1 5
//#define TONE_6 0x06 // 770 1477 6 0 1 1 0 6
//#define TONE_7 0x07 // 852 1209 7 0 1 1 1 7
//#define TONE_8 0x08 // 852 1336 8 1 0 0 0 8
//#define TONE_9 0x09 // 852 1477 9 1 0 0 1 9
//#define TONE_0 0x0A // 941 1336 0 1 0 1 0 a
//#define TONE_mi 0x0B // 941 1209 * 1 0 1 1 b
//#define TONE_pa 0x0C // 941 1477 # 1 1 0 0 c
//#define TONE_A 0x0D // 697 1633 A 1 1 0 1 d
//#define TONE_B 0x0E // 770 1633 B 1 1 1 0 e
//#define TONE_C 0x0F // 852 1633 C 1 1 1 1 f
//#define TONE_D 0x00 // 941 1633 D 0 0 0 0 0
//// -------------------------------------------------------------------------------
//
//const unsigned int SINE_WAVE_HIGH[256] = { // Sine wave amplitude range : 8 ~ 248
//128,131,134,137,140,143,146,149,151,154,157,160,163,166,168,
//171,174,177,179,182,185,187,190,192,195,197,199,202,204,206,
//209,211,213,215,217,219,221,223,224,226,228,229,231,232,234,
//235,236,238,239,240,241,242,243,244,244,245,246,246,247,247,
//247,248,248,248,248,248,248,248,247,247,247,246,246,245,244,
//244,243,242,241,240,239,238,236,235,234,232,231,229,228,226,
//224,223,221,219,217,215,213,211,209,206,204,202,199,197,195,
//192,190,187,185,182,179,177,174,171,168,166,163,160,157,154,
//151,149,146,143,140,137,134,131,128,125,122,119,116,113,110,
//107,105,102, 99, 96, 93, 90, 88, 85, 82, 79, 77, 74, 71, 69,
// 66, 64, 61, 59, 57, 54, 52, 50, 47, 45, 43, 41, 39, 37, 35,
// 33, 32, 30, 28, 27, 25, 24, 22, 21, 20, 18, 17, 16, 15, 14,
// 13, 12, 12, 11, 10, 10, 9, 9, 9, 8, 8, 8, 8, 8, 8,
// 8, 9, 9, 9, 10, 10, 11, 12, 12, 13, 14, 15, 16, 17, 18,
// 20, 21, 22, 24, 25, 27, 28, 30, 32, 33, 35, 37, 39, 41, 43,
// 45, 47, 50, 52, 54, 57, 59, 61, 64, 66, 69, 71, 74, 77, 79,
// 82, 85, 88, 90, 93, 96, 99,102,105,107,110,113,116,119,122,
//125};
//
//CONST unsigned int SINE_WAVE_LOW[256] = { // Sine wave amplitude range : 43 ~ 213
//128,130,132,134,136,138,140,143,145,147,149,151,153,155,157,
//159,161,162,164,166,168,170,172,173,175,177,179,180,182,184,
//185,187,188,190,191,192,194,195,196,197,199,200,201,202,203,
//204,205,206,207,207,208,209,209,210,210,211,211,212,212,212,
//213,213,213,213,213,213,213,213,213,212,212,212,211,211,210,
//210,209,209,208,207,207,206,205,204,203,202,201,200,199,197,
//196,195,194,192,191,190,188,187,185,184,182,180,179,177,175,
//173,172,170,168,166,164,162,161,159,157,155,153,151,149,147,
//145,143,140,138,136,134,132,130,128,126,124,122,120,118,116,
//113,111,109,107,105,103,101, 99, 97, 95, 94, 92, 90, 88, 86,
// 84, 83, 81, 79, 77, 76, 74, 72, 71, 69, 68, 66, 65, 64, 62,
// 61, 60, 59, 57, 56, 55, 54, 53, 52, 51, 50, 49, 49, 48, 47,
// 47, 46, 46, 45, 45, 44, 44, 44, 43, 43, 43, 43, 43, 43, 43,
// 43, 43, 44, 44, 44, 45, 45, 46, 46, 47, 47, 48, 49, 49, 50,
// 51, 52, 53, 54, 55, 56, 57, 59, 60, 61, 62, 64, 65, 66, 68,
// 69, 71, 72, 74, 76, 77, 79, 81, 83, 84, 86, 88, 90, 92, 94,
// 95, 97, 99,101,103,105,107,109,111,113,116,118,120,122,124,
//126};
//
////int8 index1,index2,inc1,inc2;
//
//#INT_RTCC
//void wave_generator()
//{
// int16 wave;
//
// set_rtcc(freq); //25 when clock is 20MHz, interrupts every 100us
//
// wave = SINE_WAVE_LOW[index1] ;
// wave += SINE_WAVE_HIGH[index2];
// wave >>= 2; //
// output_c( wave);
//
// index1 += inc1; //if(index1 >= 256) index1 -= 256; // Wu, 2003/02/26
// index2 += inc2; //if(index2 >= 256) index2 -= 256;
//}
//
//#define DTMF_ROW1 18 //18 for 697 Hz, increment this many times every 100us
//#define DTMF_ROW2 20 //20 for 770 Hz, for SIN_WAVE[256]
//#define DTMF_ROW3 22 //22 for 852 Hz,
//#define DTMF_ROW4 24 //24 for 941 Hz,
//
//#define DTMF_COLA 32 //32 for 1209 Hz,
//#define DTMF_COLB 35 //34 for 1336 Hz, changed to 35, 2003/03/04
//#define DTMF_COLC 38 //38 for 1477 Hz,
//#define DTMF_COLD 43 //42 for 1633 Hz, //43
//
//void generate_dtmf_tone(int8 keypad, long duration) {
//
// index1=0; index2=0; inc1=0; inc2=0;
//
// if ((keypad== 1)||(keypad== 2)||(keypad== 3)||(keypad==13)) inc1=DTMF_ROW1;
// else if((keypad== 4)||(keypad== 5)||(keypad== 6)||(keypad==14)) inc1=DTMF_ROW2;
// else if((keypad== 7)||(keypad== 8)||(keypad== 9)||(keypad==15)) inc1=DTMF_ROW3;
// else if((keypad==11)||(keypad==10)||(keypad==12)||(keypad== 0)) inc1=DTMF_ROW4;
//
// if ((keypad== 1)||(keypad== 4)||(keypad== 7)||(keypad==11)) inc2=DTMF_COLA;
// else if((keypad== 2)||(keypad== 5)||(keypad== 8)||(keypad==10)) inc2=DTMF_COLB;
// else if((keypad== 3)||(keypad== 6)||(keypad== 9)||(keypad==12)) inc2=DTMF_COLC;
// else if((keypad==13)||(keypad==14)||(keypad==15)||(keypad== 0)) inc2=DTMF_COLD;
//
// setup_counters(RTCC_INTERNAL,RTCC_DIV_2);
// enable_interrupts(INT_RTCC);
//
// enable_interrupts(GLOBAL);
//
// while ( duration-- > 0 ) delay_us(1000);
//
// disable_interrupts(INT_RTCC);
// output_c(0);
//}
//
//
void main()
{
char k;
while(TRUE)
{
// for (k=0;k<10;k++)
// {
// generate_dtmf_tone(k, 500);
// delay_ms(1000);
// }
generate_dtmf_tone(2, 500);
delay_ms(1000);
generate_dtmf_tone(2, 500);
delay_ms(1000);
generate_dtmf_tone(6, 500);
delay_ms(3000);
}
} |
Some One have some Idea?
Do someone use DTMF on sinlge PIN? Is it possibile have source code for DTMF single Pin? |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9243 Location: Greensville,Ontario
|
|
Posted: Wed Jan 11, 2012 1:13 pm |
|
|
First, I would go back to the ORIGINAL CCS ex_dtmf.c program, wire up your 16F876a as stated in the preamble of the code and see what happens.
CCS is very good about supplying working code examples, so I suspect you may have wiring issues.Be sure to use the proper resistors 100r and 200r.You could also use 110r and 220r though.
As far as a 'one pin' DTMF generator, the simple solution is to buy a DTMF chip ($2), lookup the Microchip application notes,or try 'googling' to see what is already on the Net. |
|
|
Ln_mark7930
Joined: 06 Mar 2009 Posts: 21
|
No results |
Posted: Thu Jan 12, 2012 7:39 am |
|
|
I realize original circuit with R=100 ohms 2R=200 Ohms.
I restore original ccs example firmware (EX_DTMF.C) ; I change only uC = PIC16F876A instead PIC16F16F877), but phone don't place the call.
Nothing happen's.
Now I try to replace 16f876A with 16F877A and recompile firmware.
I hope that it works!
2 o 3 years ago my friend show me that he realyzed a very simple circuit that generate DTMF tone with only one PIN ( with 16F628A - 10 Mhz clock's). I see that he use Microcode Studio software and a routine called DTMFOUT . Ie = DTMFOUT DT,200,100,[1,7,2]. DT is pin-name ; 200 is tone duration ; 100 is pause between tones and [1,7,2] is phone number that it call. Isn't there nothing similar on CCS?
I don't need that code use only one pin: code can use also eight bit. I tell you that I prefer only one pin. It's very important witch code must will work.
From CCS site: http://www.ccsinfo.com/content.php?page=compexamples we can read new functions added:
Frequency Generator - Generate tones, frequencies and DTMF using only one user define general purpose I/O pin. This is done by implementing a software PWM on one pin.
Where is DTMF only one pin function???
Do you/someone ever test/try this source on your circuit?
Is it work without problems? |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9243 Location: Greensville,Ontario
|
|
Posted: Thu Jan 12, 2012 11:48 am |
|
|
You should try 'googling'. While I didn't quickly find CCS C code, there are several ASM programs as well as a PBASIC 'function'. Converting them to C isn't that bad though I don't know why you're having problems with the CCS example. It could be your wiring setup as you need to have that R-2R ladder right! Also be sure to use the same crystal frequency.
Also what DTMF decoder are you using to prove/disprove it's working right or is it that you do not get any tones ? |
|
|
Ln_mark7930
Joined: 06 Mar 2009 Posts: 21
|
DMTF : right low frequency , wrong high frequency |
Posted: Thu Jan 12, 2012 2:08 pm |
|
|
Hi, thank for your time.
I control the frequency with a PC and a software that verify the audio spectrum from microphone connected to the sound card.
I can see the low frequency it's perfect, but the high frequency is always wrong about of 30-100 Hz. DTMF Tolerance it's too small respect to my frequency error.
However if put the speaker near the microphone of my phone no call start.
I retry more times to place a call with the phone, but nothing.
If You look my source I call a small number (3 digits/tone only) but it's a mystery, because no tone is decoded by phone. Tomorrow I connect my circuit to a DTMF decoder by Holtek (at the moment I forgot the name) and update the forum with the result.
Maybe I try to realize an ASM code to generate DTMF, maybe it work well. |
|
|
Ln_mark7930
Joined: 06 Mar 2009 Posts: 21
|
No result |
Posted: Mon Jan 16, 2012 8:24 am |
|
|
Nothing's change...
Holtek ( model HT9170D ) don't recognize TONES.
PIC don't generate DTMF correctly. I re-check one more time my circuit ( is only R2R circuit) and it result correct.
I found one example realized on MicroC language witch used PWM and one single PIN ( PWM pin).
Today I Convert original source to CCS C language.
I hope that its work fine.
If someone have some different solution ( without external active component) pleace write me. Thanks a lot. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Mon Jan 16, 2012 4:16 pm |
|
|
I just tweaked the example a fraction, and it then gives good tones.
I changed the interrupt to use timer2, and programmed this with:
setup_timer_2(T2_DIV_BY_4, 124, 1);
and obviously enabled INT_TIMER2, rather than INT_RTCC.
Then got rid of the 'set_rtcc(25)' line in the interrupt, and frequencies were then right.
Unfortunately the example was made rather 'generic' to cover basic PIC's that don't have timer2, and at the top end the accuracy is then being degraded by the amount the counter has advanced by the time the code gets into the interrupt. The example tones were good enough to happily trigger a couple of DTMF decoders, but failed with a couple of others. The DTMF spec requires +/-1.5% and the example only manages about 2.5% on the top tone. Actually OK with quite a few things (it actually placed a phone call for me), but 'borderline'.....
Best Wishes |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|