Go Down

Topic: DTMF 2 tones, no Library (Read 598 times) previous topic - next topic

steinie44

Here is a sketch I'm playing with to generate DTMF tones.
Code: [Select]

// 2 Tones using Blink without delay JDS 25 June 2014
// Constants
//int Number[] = {2, 5, 4, 3, 8, 1, 5};
int Number[] = {4, 3, 1, 1, 0, 3, 6};  // Phone number

//DTMF frequencys
//int HTones[] = {1336, 1209, 1336, 1477, 1209, 1336, 1477, 1209, 1336, 1477};
//int LTones[] = {941, 697, 697, 697, 770, 770, 770, 852, 852, 852};

//DTMF tones freq * 2 = Half Cycles
//int HTones[] = {2672, 2418, 2672, 2954, 2418, 2672, 2954, 2418, 2672, 2954};
//int LTones[] = {1882, 1394, 1394, 1394, 1540, 1540, 1540, 1704, 1704, 1704};

//DTMF tones microseconds = 1/(freq*2)
int HTones[] = {374, 414, 374, 339, 414, 374, 339, 414, 374, 339};
int LTones[] = {531, 717, 717, 717, 649, 649, 649, 587, 587, 587};

// Slightly lower microseconds to make up for loop overhead
//int HTones[] = {364, 404, 364, 329, 404, 364, 329, 404, 364, 329};
//int LTones[] = {521, 707, 707, 707, 639, 639, 639, 577, 577, 577};

const int HTone = 7;  // Pin D7
const int LTone = 8;  // Pin D8

//Variables
byte HToneState = LOW;
byte LToneState = LOW;
int i = 0;
int j = 0;
unsigned long s; // only for trouble shooting
unsigned long e; //                "
long PrevMicrosHTone = 0;
long PrevMicrosLTone = 0;
long PrevMillis = 0;
long HToneInterval = 414; // 1/(1209*2)
long LToneInterval = 717; // 1/(697*2)
long ToneInterval = 150;
unsigned long CurrentMicros = micros();
unsigned long CurrentMillis = millis();

void setup() {
  // put your setup code here, to run once:
  pinMode(HTone, OUTPUT);
  pinMode(LTone, OUTPUT);
  Serial.begin(9600);
  Serial.print(__FILE__ " " __DATE__ " " __TIME__);
  Serial.print("  IDE "); Serial.println(ARDUINO);
 
}

void loop() {
  if (i >6)
   {i = 0; delay(4000); Serial.println();} // 4 seconds between redial
   j = Number[i]; Serial.print(j); // digit to dial
   //Serial.println(e - s);
   i = i++;
   delay(100); //Blocking delay between digits
   HToneState = LOW;
   LToneState = LOW;
   PrevMillis = millis(); // set prev millis and micros
   PrevMicrosHTone = micros();
   PrevMicrosLTone = micros();
   
  while (millis() - PrevMillis < ToneInterval) // send tones for 150ms each
  {
  if (micros() - PrevMicrosHTone +0 > HTones[j])// + 6 to 17 fix for loop delay
   {PrevMicrosHTone = micros();
     //HToneState = !HToneState;
    //digitalWrite(HTone, HToneState); // High Tone
    PIND = 0x80; // toggle pin D7
   }
  if (micros() - PrevMicrosLTone +0 > LTones[j])
   { PrevMicrosLTone = micros();
     //LToneState = !LToneState;
    //digitalWrite(LTone, LToneState);  //Low Tone
    PINB = 0x01;// toggle pin D8
   }

  }
 
}





I just need a way to make the tones into sine waves. any ideas?

LarryD

Maybe integrate them with op-amps.
The way you have it in your schematic isn't the same as how you have it wired up!

retrolefty

#2
Jul 02, 2014, 02:23 am Last Edit: Jul 02, 2014, 02:28 am by retrolefty Reason: 1
In my opinion this is an example of the wrong tool for the job. Filtering the square wave DTMF frequencies to remove all the odd harmonics is going to require a lot of external components, which add costs, board space, and even then may not meet the DTMF rather strict electrical standards. A much better solution is to use a special purpose DTMF chip that the arduino controls.
Here is one example of a small 8 pin DIP IC and it's datasheet.

http://www.ebay.com/itm/HT9200A-DTMF-Generator-pic-micro-robot-control-/191211974617?pt=LH_DefaultDomain_0&hash=item2c851f2fd9

http://www.holtek.com.tw/english/tech/appnote/comm/pdf/ha0037e.pdf


steinie44

Quote

Here is one example of a small 8 pin DIP IC and it's datasheet.

Yes, I have seen these before. May go that route. Just playing with stuff for now.
I modified the sketch for an organ with 7 keys. Use PINB and PINC to speed up key reading.
No problem playing up to 7 tones at once.

Go Up