View Cart

Sierra

Radio

© Sierra Radio Systems

DTMF Decoder using the HamStack Project Board and 8870 decoder chip

This project uses standard features of the HamStack Project Board.  The board includes an 8870 DTMF decoder chip.  Receiver audio is fed into the decoder chip.  The output of the decoder chip is 5 digital signals, 4 to represent the 16 possible DTMF digits and one (DV pin) to indicate that a valid DTMF digit is being decoded.  The software example code scans the DV pin and when a digit is decoded, the other 4 data pins are read.  The four data pins, D1, D2, D3, D4 represent bits 0, 1, 2, and 3.  Bit 0 has a value of 1, bit 2 has a value of 2, bit 3 has a value of 4 and bit 3 has a value of 8.  So if bits 2 and 4 are active, that represents 2 + 4 which equals 6.  A value of 6 represents the DTMF digit 6.  The rest of the DTMF digits are as follows...

 

4 bit value   DTMF digit

    1               1

    2               2

    3               3

    4               4

    5               5

    6               6

    7               7

    8               8

    9               9

    10             0

    11             *

    12             #

    13             A

    14             B

    15             C

    0               D

 

Although the Project Board kit includes a front and back panel that can be routed out to fit the LCD, in this project we make custom front and back panels our of black plastic to make it look really nice.  We also added a 3.5mm stereo mini jack to connect the receiver audio.  Otherwise all the components are included in the Project Board kit.

 

Project box and LCD display

Inside view of the 8870 DTMF decoder chip, crystal, resistors and other parts are on the left of this photo. When installed, the CPU board will be mounted above this circuit.

Inside view of the Project Box.  Viewed from the back, you can see the CPU board installed in the middle and the back of the LCD at the top of the photo.

The LCD board is mounted to the front panel with nylon standoffs superglued to the back of the front panel.  First, screw the standoffs to the LCD board.  Then dab some superglue gel to the end of the standoffs and then set the standoffs against the back of the front panel.

 

Viewed from the front, the LCD interface cable plugs into the 10 pin header in the back of the project board.

The test receiver is plugged into the completed decoder.

 

Below, the back of the chassis shows the audio input connector added to the back panel in the upper left.  The other connectors, from left to right, are

As DTMF digits are decoded, the last decoded digit is displayed in the upper right corner.  As digits are decoded, they displayed in order on line 2 of the LCD display.  The example program will automatically flush the input buffer if no data is entered after about 5 seconds.  

In this example, if the command “123” is decoded, the program will activate the reed relay output.  If the command “456” is decoded, the relay will de-activate.

'  HamStack DTMF Decoder using the 8870 chip

'  This program listens to the output of a 8870 DTMF decoder and will

'  send each digit to the LCD display

'  Version 1.0

 

Device = 18F4620             ' Set the CPU type to a Microchip 18F4620

Clock = 10                   ' Set CPU clock frequency to 10 MHz

#option LCD_DATA = PORTD.0

#option LCD_RS = PORTD.4

#option LCD_EN = PORTD.5

Include "usart.bas"          ' Include the RS232 UART subroutines

Include "convert.bas"

Include "lcd.bas"

Include "utils.bas"

 

'----- CONSTANTS DEFINITIONS --------------------------------------

Const on = 1

Const off = 0

 

'----- VARIABLE DEFINITIONS ---------------------------------------

Dim x   As Byte              ' Working variable used to count how many times we go through the loop

Dim dv As PORTC.3

Dim d1 As PORTD.7

Dim d2 As PORTA.5

Dim d4 As PORTC.4

Dim d8 As PORTC.5

Dim led As PORTC.0

Dim relay As PORTB.3

Dim opto As PORTB.4

Dim loop_count As LongInt

Dim dtmf_char As Char

Dim charpos As Byte

Dim dtmfstring As String * 20

 

'----- DEFINE PIN DIRECTIONS --------------------------------------

'      0 = output

'      1 = input

TRISC.0 = 0                  ' Status LED is defined as an output pin

TRISC.3 = 1

TRISD.7 = 1

TRISA.5 = 1

TRISC.4 = 1

TRISC.5 = 1

TRISD.0 = 0

TRISD.1 = 0

TRISD.2 = 0

TRISD.3 = 0

TRISD.4 = 0

TRISD.5 = 0

TRISD.6 = 0

 

'----- INITIALIZE VARIABLES AND SERIAL PORT ------------------------

x = 0                        ' Initialize loop counter to zero

loop_count = 0

charpos = 0

relay = off

opto = off

led = off

SetBaudrate(br9600)          ' Set serial baud rate to 9600

Cls   

WriteAt(1,1,"DTMF Decoder")   ' Update LCD display

 

'----- START MAIN PROGRAM CODE -------------------------------------

DelayMS(100)                 ' Pause for 100ms after hardware reset to settle down

USART.Write("Hello world from HamStack", 13, 10)    ' Send hello world greeting

 

'----- START MASTER CONTROL LOOP ------------------------------------

master_loop:

 

loop_count = loop_count + 1

DelayMS (1)

If loop_count > 5000 Then

  WriteAt (2,1,"                ")

  charpos = 0

  dtmfstring = ""

  loop_count = 0

  WriteAt (1,15,"  ")

EndIf

 

If dv = 1 Then

   GoTo debounce_dv

  EndIf

GoTo master_loop

 

debounce_dv:

   DelayMS (10)

   If dv = 0 Then GoTo master_loop EndIf

 

   x = 0

   'dv still present, continue...      

   If d1 = 1 Then x = 1     EndIf

   If d2 = 1 Then x = x + 2 EndIf

   If d4 = 1 Then x = x + 4 EndIf

   If d8 = 1 Then x = x + 8 EndIf

 

   Select x

          Case  1 dtmf_char = "1"

          Case  2 dtmf_char = "2"

          Case  3 dtmf_char = "3"

          Case  4 dtmf_char = "4"

          Case  5 dtmf_char = "5"

          Case  6 dtmf_char = "6"

          Case  7 dtmf_char = "7"

          Case  8 dtmf_char = "8"

          Case  9 dtmf_char = "9"

          Case 10 dtmf_char = "0"

          Case 11 dtmf_char = "*"

          Case 12 dtmf_char = "#"

          Case 13 dtmf_char = "A"

          Case 14 dtmf_char = "B"

          Case 15 dtmf_char = "C"

          Case 0  dtmf_char = "D"

   EndSelect

 

   USART.Write(dtmf_char)

   charpos = charpos + 1

   WriteAt(1,16," ")                       ' Update LCD display

   WriteAt(1,16,dtmf_char)                 ' Update LCD display

   WriteAt(2,charpos,dtmf_char)            ' Update LCD display

   dtmfstring = dtmfstring + dtmf_char

   loop_count = 0                          ' Reset the digit timer

   If charpos = 16 Or dtmf_char = "D" Then ' End of display buffer reached.  Clear buffer.

      WriteAt (1,16," ")

      WriteAt (2,1,"                ")

      charpos = 0

      dtmfstring = ""

      loop_count = 0

   EndIf

 

debounce_dv2:

   DelayMS (10)

   If dv = 1 Then GoTo debounce_dv2 EndIf

 

Select dtmfstring

 

Case "123"       WriteAt (1,16," ")

                WriteAt (2,1,"Relay 1 On")

                relay = on

                led = on

                opto = on

                DelayMS (2000)

                WriteAt (2,1,"                ")

                charpos = 0

                dtmfstring = ""                 

Case "456"       WriteAt (1,16," ")

                WriteAt (2,1,"Relay 1 Off")

                relay = off

                opto = off

                led = off

                DelayMS (2000)

                WriteAt (2,1,"                ")

                charpos = 0

                dtmfstring = ""

End Select

 

GoTo master_loop   

 

 

 

 

Software Example

What would it take to build one of these?