Go Down

Topic: Arduino and HM91710A - Generate DTMF! (Read 10875 times) previous topic - next topic


Hi Guys,

I just received my Arduino in the post a few days ago and have been having great fun with it..

I am currently building a burglar alarm with 2 PIR sensors from sparkfun. I have these working so on to my next problem.

I wish to interface my arduino with the HM91710A chip so I can generate DTMF tones and dial my number when the alarm is triggered.. I have searched the internet far and wide for the past few days and I have come up blank. All I can say is that the MT8880 IC is a lot more popular to mine and quite similar. Still no tutorials however. :'(

Below is a datasheet for my IC and I have spent many hours trying to get this to work... I'm probably doing everything wrong as I am more of a programmer than electronic eng.


Do you think it is possible for me to use this IC with the arduino to generate DTMF tones? I'd really appreciate your help on this..

I promise to post start a build log for my alarm as soon as I know I can do it...

Thanks in advance for any help..



I don't think this is the ideal IC for your purpose, because it's set up to receive inputs from a 12-key numeric pad.  To get it to work, you'll have to get the arduino to mimic the electrical behavior caused by the capacitance change that happens when you press one of those buttons.  

I think what you want is an IC that takes something the arduino can talk to easily, like serial, i2c, etc. and converts that to DTMF.

OR... cut out the middleman, and get the arduino to output DTMF directly... I know I've seen threads from other people trying to interface Arduino to DTMF, maybe there's a solution out there that you could adapt.


Jun 08, 2009, 02:36 pm Last Edit: Jun 08, 2009, 02:37 pm by Grumpy_Mike Reason: 1
electrical behavior caused by the capacitance change that happens when you press one of those buttons.  

No it's not a capacitance change it is simply continuity.

You need to use an analogue switch to short out each one the column/row combinations to simulate pressing a switch. The 4066 has four such analogue switches so you would need three of those chips to do it.
Then from the arduino you need to control the enable lines to those switches. This can be either straight off the pins or through some sort of output expander like a shift register (two in fact as you only get 8 outputs from one shift register).
This is the same sort of circuit you use in "circuit bending" so Google that for more specific examples.


Ah, I took another look at the datasheet and you're right.  I revise my answer to ^^^  :)


Hey  :D

Thanks for the replies!

I found this video on youtube < http://www.youtube.com/watch?v=lHjs4kHJloc >

I mailed the owner and he was helpful..

He recommends Holtek 9200B. < http://www.holtek.com.tw/english/docum/comm/9200.htm > I have checked out the datasheet and it looks like it might be perfect. It has a serial and a paralell interface.
I think the serial interface would suit perfectly with the arduino but I may be wrong. Would I just connect the data pin of the IC to the pin 1 of my arduino to send the serial data to it?

Actually, I think it may be a little complex to use serial mode after viewing this document.

There is assembly code in there, I don't think this can be ran on the arduino.

if I want to go down the paralell road then do I need 7 (i.e. 4rows x 3 columns) pins available on the arduino ?

Thanks for any insight..


Jun 09, 2009, 04:19 pm Last Edit: Jun 09, 2009, 04:27 pm by Grumpy_Mike Reason: 1
There is assembly code in there, I don't think this can be ran on the arduino.

There is nothing you can do in assembler that you can't do in C so this is not a barrier.
The serial mode looks like the SPI mode of the Arduino with clock and data, or you could just do it by hand.

if I want to go down the paralell road then do I need 7 (i.e. 4rows x 3 columns) pins available on the arduino ?

The parallel mode is only a 4 bit parallel mode, just like some LCDs. It requires a nibbler select and a clock. Quite hostly the serial mode is simpler.

It has a serial and a paralell interface.

Note there are two different chips the HT9200A for serial mode and the HT9200B for parallel mode, one chip will not do both. Note the two chips produce different groups of frequencies as well, make sure you choose the one you need.



The HT9200B allows both serial and parallel mode (one or the other depending on S/P pin state).  

Both modes produce the same basic tone pairs for digital dialing, corresponding to the keys: 0-9, *, #, plus A-D, but in serial mode you can select the single frequency tones as well.



Oct 31, 2009, 08:26 pm Last Edit: Oct 31, 2009, 10:00 pm by BroHogan Reason: 1
Here is some code I wrote for that chip . . .

Code: [Select]
/* HT9200B DTMF Generator Test                           BroHogan 7/17/09
* SETUP FOR PARALLEL MODE - Requires 5 pins - 4 data + CS (to stop tone)
* Serial Mode only req. 2 pins - no CS (cmnd to stop tone)
* Serial Mode also provides 8 "pure" tones
* Wire per data sheet - req. 3.57MHz xtal (4.0MHz works but won't dial)

#define D0_PIN  2              // Data 0
#define D1_PIN  3              // Data 1
#define D2_PIN  4              // Data 2
#define D3_PIN  5              // Data 3
#define CS_PIN  6              // Chip Select LOW = On

void setup() {
 pinMode(D0_PIN, OUTPUT);
 pinMode(D1_PIN, OUTPUT);
 pinMode(D2_PIN, OUTPUT);
 pinMode(D3_PIN, OUTPUT);
 pinMode(CS_PIN, OUTPUT);

void loop() {
 //DTMF_Out (0,10000);

void DTMF_Out (byte digit, long duration){
 digitalWrite(CS_PIN, LOW);           // Enable chip

 digitalWrite(D0_PIN, bitRead(digit,0));
 digitalWrite(D1_PIN, bitRead(digit,1));
 digitalWrite(D2_PIN, bitRead(digit,2));
 digitalWrite(D3_PIN, bitRead(digit,3));
 digitalWrite(CS_PIN, HIGH);           // Disable chip (req if parallel)
 delay(100);                           // not required for dialing

void Test_DTMF(){  // cycles through all tones
 for (byte i=0; i<16; i++){
   DTMF_Out (i,400);    // use this if parallel

void Dial_Phone(){    // dials phone
 DTMF_Out (1,300);
 DTMF_Out (8,300);
 DTMF_Out (0,300);   //SB 10!
 DTMF_Out (0,300);
 DTMF_Out (5,300);
 DTMF_Out (5,300);
 DTMF_Out (5,300);
 DTMF_Out (1,300);
 DTMF_Out (2,300);
 DTMF_Out (1,300);
 DTMF_Out (2,300);

Serial mode (better)
Code: [Select]
/* HT9200B DTMF Generator Test                             BroHogan 7/17/09
* SETUP FOR SERIAL MODE - Requires 3 pins - Data and Clock (100KHz) and CE
* Wire per data sheet - 3.57MHz xtal (4.0MHz won't dial) S/P to GND = serial
* Serial Mode also provides 8 "pure" tones (N/A w/ parallel)

#include "HT9200.h"                     // defines for HT9200 DTMF chip
#define DATA_PIN   2                    // Data (serial)
#define CLOCK_PIN  3                    // Clock (serial)
#define CE_PIN     4                    // Chip Enable pin (must control)

#define PHONE_NMBR "18005551212"         // phone # to dial
char PhoneNum[] = PHONE_NMBR;           // load phone # for dialer

void setup() {
 pinMode(CE_PIN, OUTPUT);
 Init_HT9200();                        // init the chip

void loop() {
 Dialer();                             // dials phone
 Pure_Tones();                         // plays all the pure tones

void Init_HT9200 (){
 digitalWrite(CE_PIN, HIGH);           // start with chip disabled (else you go nuts)
 digitalWrite(CLOCK_PIN, HIGH);        // start with clock pin high
 digitalWrite(CE_PIN, LOW);            // now enable the chip
 delay(10);                            // delay 10ms to ramp up the ocillator
 DTMF_Out (DTMF_OFF,1,0);              // turn off ant tone from previous run

void DTMF_Out (byte digit, long duration, long pause){  // FOR SERIAL COMM
 if (digit == 0) digit = 10;           // take care of 0 here
 for (byte i=0; i<5; i++){
   digitalWrite(CLOCK_PIN, HIGH);      // clock high while setting data
   digitalWrite(DATA_PIN, bitRead(digit,i)); // set data LSB->MSB
   delayMicroseconds(5);               // 1/2 of 100K Clock speed
   digitalWrite(CLOCK_PIN, LOW);       // clock low to latch data
   delayMicroseconds(5);               // 1/2 of 100K Clock speed
 delay(duration);                      // how long tone will play
 if (pause != 0){                      // tone sounds continuously if zero
   for (byte i=0; i<5; i++){           // same as above
     digitalWrite(CLOCK_PIN, HIGH);
     digitalWrite(DATA_PIN, bitRead(DTMF_OFF,i));
     digitalWrite(CLOCK_PIN, LOW);
   delay(pause);                       // how long pause between tones

void Dialer(){  // cycles through all tones
 for (byte i=0; i<11; i++){
   DTMF_Out(PhoneNum[i]-'0',500,100);  // 1/2 sec tome with 1/10 pause

void Pure_Tones(){
 DTMF_Out (HZ_697,1000,0);
 DTMF_Out (HZ_770,1000,0);
 DTMF_Out (HZ_852,1000,0);
 DTMF_Out (HZ_941,1000,0);
 DTMF_Out (HZ_1209,1000,0);
 DTMF_Out (HZ_1336,1000,0);
 DTMF_Out (HZ_1477,1000,0);
 DTMF_Out (HZ_1633,1000,0);

 DTMF_Out (DTMF_OFF,1,0);              // turn off DTMF because zero pause used

and the include tab . . .
Code: [Select]
/* HT9200.h  defines for HT9200 DTMF chip in serial mode */

#define DTMF_OFF  24  // SB 31 but next cmd will be lost - a not used cmnd# works fine
#define STAR      11
#define POUND     12
#define A_KEY     13
#define B_KEY     14
#define C_KEY     15
#define D_KEY      0

// pure frequencies that can be made by the chip . . .
#define HZ_697    16
#define HZ_770    17
#define HZ_852    18
#define HZ_941    19
#define HZ_1209   20
#define HZ_1336   21
#define HZ_1477   22
#define HZ_1633   23

If you're not in a big hurry, you can get them here . . .
"Data is not information, information is not knowledge, knowledge is not understanding, understanding is not wisdom."
~ Clifford Stoll

Go Up