Sierra

Radio

PayPal: View Cart

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?