PDA

View Full Version : A little DTMF help



Travin77
- 17th May 2006, 22:53
Hello all,
I am working on a control circuit using dtmf. I can decode the dtmf fine it is getting it into a usable format that is troubling me. I am looking to make an eight digit password. I have looked on the site but I don't seem to understand their method. I am using a 16f876a with 20 mhz. Here is my attempt. I also am controlling a isd 25120 chip based on the entry.

@ device pic16F876A, hs_osc, wdt_on, lvp_off, protect_off
include "MODEDEFS.BAS"
define OSC 20
adcon1=7
trisa.0 = 1
trisa.1 = 0
trisa.2 = 0
trisb = %11111111
trisc = %00000000
low portc
low portb

'_________pic to mc145436a assignments______________________

dtmf_ready VAR PORTA.0 'pin 12 (DV)
select_dtmf VAR PORTA.1 'pin 3 (Enamble)
reset VAR PORTA.2 'pin 5 (GT)
DT0 VAR PORTB.4 'pin 2 (D1)
DT1 VAR PORTB.5 'pin 1 (D2)
DT2 VAR PORTB.6 'pin 14 (D4)
DT3 VAR PORTB.3 'pin 13 (D8)
ce var portA.3 'pin from isd chip
'____________________variables____________________ ______

dtmf VAR byte ' Stores most recent DTMF digit
dtmf1 var byte
password var byte [8]
entry var byte
'___________________Initial Conditions__________________
start:
High reset
pause 500
high ce
low select_dtmf
c = 0
e = 0
loop:
IF dtmf_ready = 0 Then loop ' Check for DTMF present, if none loop again

welcome:
portc = %00000000
pause 500
gosub play 'play welcome statement
begin:
if dtmf_ready = 0 then begin 'waits for number to be depressed
gosub GetDtmf 'gets number
select case entry 'places number in an array
case c = 0
dtmf = password [0]
case c = 1
dtmf = password [1]
case c = 2
dtmf = password [2]
case c = 3
dtmf = password [3]
case c = 4
dtmf = password [4]
case c = 5
dtmf = password [5]
case c = 6
dtmf = password [6]
case c = 7
dtmf = password [7]
end select
c = c + 1
if c =< 7 then begin
if password [0] <> "1" then error
if password [1] <> "2" then error
if password [2] <> "3" then error
if password [3] <> "4" then error
if password [4] <> "5" then error
if password [5] <> "6" then error
if password [6] <> "7" then error
if password [7] <> "8" then error

play_menu_message:
portc = %000100100
gosub play 'play menu message

GetDtmf:
select_dtmf = 1 ' Enable the data output from the MT8870
Pause 1 ' Pause 1 mS to let data settle
dtmf = 0
IF DT0 = 1 Then 'Check Input port 0
dtmf = dtmf + 1
EndIF
IF DT1 = 1 Then 'Check Input port 1
dtmf = dtmf + 2
EndIF
IF DT2 = 1 Then 'Check Input port 2
dtmf = dtmf + 4
EndIF
IF DT3 = 1 Then 'Check Input port 3
dtmf = dtmf + 8
EndIF
LookUp dtmf,["_1234567890*#"],dtmf
dtmf_wait:
IF dtmf_ready Then dtmf_wait ' Loop here until DTMF signal stops
select_dtmf = 0
low reset
high reset
return

I can't seem to get the password go work correctly. I appreciate any help. There may very well be an easier method of creating a password for the user to enter, so please give me some ideas if possible.

Travin

paul borgmeier
- 18th May 2006, 07:27
low portc
low portb
portc = %000100100
IF dtmf_ready Then dtmf_wait ' Loop here until DTMF signal stops

I am not sure if you have figured this out by now but the above few lines look like possible trouble to me. I am not much of DTMF user so hopefully someone else will spot your woes.

Paul Borgmeier
Salt Lake City, Utah
USA

Travin77
- 18th May 2006, 17:34
Thanks for pointing out the portc = %000100100. That controls the address of the isd chip. One zero on each side shouldn't be there. Unfortunately, that didn't fix it. Its not the dtmf that doesn't work. It is getting the data into a usable form. Once the phone picks up, the user pushes a button on the key pad. The pic then makes the isd chip play the welcome statement, which asks the user to enter their password, which in this case is 12345678. During the entry of the password, I tried to make each entry go into an array via the select case command. During this progression, I advanced the var "c". When "c" reached 8, I compare each individual array segment to the individual section of that password. This is where the code stops working. It doesn't give me the error message and doesn't go on to the next step of the program. I am not sure if I am getting the code inputed correctly nor am I sure that I am comparing it correctly. Thanks for the catch though.

Travin

BigWumpus
- 18th May 2006, 21:47
trisa.0 = 1
trisa.1 = 0
trisa.2 = 0


PortA ist an analog-input after reset. Look at the manual !



trisb = %11111111
trisc = %00000000
low portc
low portb


OK, PortB is Input, why do you use the LOW-command,
and this is written in the wrong way. If you adress the TRIS direct, better don't use LOW and HIGH.



dtmf_ready VAR PORTA.0 'pin 12 (DV)
select_dtmf VAR PORTA.1 'pin 3 (Enamble)
reset VAR PORTA.2 'pin 5 (GT)
DT0 VAR PORTB.4 'pin 2 (D1)
DT1 VAR PORTB.5 'pin 1 (D2)
DT2 VAR PORTB.6 'pin 14 (D4)
DT3 VAR PORTB.3 'pin 13 (D8)
ce var portA.3 'pin from isd chip


While declaring this in the front of the program, you can easily use LOW/HIGH or INPUT/OUTPUT an this symbolic names, it is better to read!



c = 0
e = 0


not declared !




select case entry 'places number in an array
case c = 0
dtmf = password [0]


Hä ?
What is C ? Ever read the manual nearby "Select case" ?



dtmf = 0
IF DT0 = 1 Then 'Check Input port 0
dtmf = dtmf + 1
EndIF
IF DT1 = 1 Then 'Check Input port 1
dtmf = dtmf + 2
EndIF
IF DT2 = 1 Then 'Check Input port 2
dtmf = dtmf + 4
EndIF
IF DT3 = 1 Then 'Check Input port 3
dtmf = dtmf + 8


dtmf=0:dtmf.0=DT0:dtmf.1=DT1:dtmf.2=DT2:dtmf.3=DT3 ??


It's very quick'n'dirty !

Travin77
- 19th May 2006, 02:48
PortA ist an analog-input after reset. Look at the manual !

I used adcon1 = 7 to change port a to digital. Did I do something wrong?

c = 0
e = 0
not declared !

Right, somehow those got left off in the top as did these:
entry var byte
c var byte
e var byte

they are in the original program I just deleted them while I was cutting and pasting.

In the select case statement I used c as a counter for the number of entries pressed into the key pad. For example, once the call initiates, c=0. The user inputs the first DTMF signal. That is decoded and a lookup table is used. That input is then placed in the dtmf variable:

LookUp dtmf,["_1234567890*#"],dtmf

The program then returns to the select case statement and places that dtmf value into an array based on what c equals. C is then advanced by 1.
c = c + 1

If c is 7 or less then the program returns to the if dtmf_ready = 0 then begin loop to retrieve the next digit.

if c =< 7 then begin

This is supposed to continue until c >=8, at which point the program starts comparing the array values to a set of constant numbers. Now, this is how it is supposed to work. Obviously it does not work. This is my first attempt at using the select case statement and first time trying a password out. Thanks for your help, its just I am not sure what you are telling me to do.

Travin

BigWumpus
- 19th May 2006, 08:31
In my example of the PicBasic-manual there is an example for SELECT-CASE like this:

Example

SELECT CASE x
CASE 1
y = 10
CASE 2, 3
y = 20
CASE IS > 5
y = 100
CASE ELSE
y = 0
END SELECT

Travin77
- 19th May 2006, 15:50
So what you are saying is that portion of the code should look like this:

begin:
if dtmf_ready = 0 then begin 'waits for number to be depressed
gosub GetDtmf 'gets number
select case c 'places number in an array
case 0
dtmf = password [0]
case 1
dtmf = password [1]
case 2
dtmf = password [2]
case 3
dtmf = password [3]
case 4
dtmf = password [4]
case 5
dtmf = password [5]
case 6
dtmf = password [6]
case 7
dtmf = password [7]
end select
c = c + 1
if c =< 7 then begin
Is this what you are trying to say? Anyway I am going to try it. I guess I misuderstood what the example was telling me to do. Thanks for the help and suggestions.

Travin

BigWumpus
- 19th May 2006, 16:21
...and smoother:

dtmf=password[c] (replaces the hole Setect-part)

or better:

password[c]=dtmf

this maybe will work as you expect....

Travin77
- 19th May 2006, 20:27
...and smoother:

dtmf=password[c] (replaces the hole Setect-part)

or better:

password[c]=dtmf

this maybe will work as you expect....

I am not quite sure what you are saying. Why did you put [c]? Are you just using c in place of numbers for the array? Thanks for the help

Travin

Travin77
- 21st May 2006, 04:07
I haven't been able to get this thing to work. Maybe you smarter people can assist. Here is the gist: I call the phone and the welcome message asks for the password. The user then enters the password on the keypad. The password is 8 digits long. Everything works fine until this part, naturaly. For some reason, the program is not recognizing the password. Any help is appreciated. Using 16f876a with 20mhz and PBP

'____________________variables____________________ ______

dtmf VAR byte ' Stores most recent DTMF digit
dtmf1 var byte
password var byte [8]
codeword var byte [8]
codeword1 var byte [8]
c var byte
e var byte

Start:
c = 0
e = 0
loop:
iF dtmf_ready = 0 Then loop ' Check for DTMF present, if none loop again

welcome:
portc = %00000000
pause 20
gosub play 'play welcome statement
begin:
if dtmf_ready = 0 then begin 'waits for number to be depressed
gosub GetDtmf 'gets number
select case c 'places number in an array
case 0
dtmf = password [0]
case 1
dtmf = password [1]
case 2
dtmf = password [2]
case 3
dtmf = password [3]
case 4
dtmf = password [4]
case 5
dtmf = password [5]
case 6
dtmf = password [6]
case 7
dtmf = password [7]
end select
c = c + 1
if c =< 7 then begin
if password [0] = "1" then
goto password1
else
goto user_password
endif
password1:
if password [1] = "2" then
goto password2
else
goto error
endif
password2:
if password [2] = "3" then
goto password3
else
goto error
endif
password3:
if password [3] = "4" then
goto password4
else
goto error
endif
password4:
if password [4] = "5" then
goto password5
else
goto error
endif
password5:
if password [5] = "6" then
goto password6
else
goto error
endif
password6:
if password [6] = "7" then
goto password7
else
goto error
endif
password7:
if password [7] = "8" then
goto play_menu_message
else
goto error
endif

play_menu_message:
portc = %00010010
gosub play 'play menu message

GetDtmf:
select_dtmf = 1 ' Enable the data output from the MT8870
Pause 1 ' Pause 1 mS to let data settle
dtmf = 0
IF DT0 = 1 Then 'Check Input port 0
dtmf = dtmf + 1
EndIF
IF DT1 = 1 Then 'Check Input port 1
dtmf = dtmf + 2
EndIF
IF DT2 = 1 Then 'Check Input port 2
dtmf = dtmf + 4
EndIF
IF DT3 = 1 Then 'Check Input port 3
dtmf = dtmf + 8
EndIF
LookUp dtmf,["_1234567890*#"],dtmf

paul borgmeier
- 21st May 2006, 05:14
Travin,

For starters, in your Select Case section

change all the

dtmf = password [0], dtmf = password[1], etc
to
password[0] = dtmf, password[1]=dtmf, etc

otherwise you are setting the dtmf value you just converted to ASCII to some unknown value stored in your uninitialized password array.

Cheers,

Paul Borgmeier
Salt Lake City, Utah USA
www.cruxanalysis.com

Travin77
- 22nd May 2006, 20:53
I changed the format, as I had no idea that mattered. However, it still doesn't work. I know for sure that it is decoding the numbers, because it tells me what number is entered verbally. When I placed that section of the code after the select case for the password entry, it stopped telling me the values which leads me to believe the select case statement doesn't work for the passsword portion. Would it be easier if I didn't convert the data to ascii? Thanks for the help. Here is the code I have now if anyone feels like looking at it. Thanks for all the help.

@ device pic16F876A, hs_osc, wdt_on, lvp_off, protect_off
include "MODEDEFS.BAS"
define OSC 20
adcon1=7
trisa.0 = 1
trisa.1 = 0
trisa.2 = 0
trisb = %11111111
trisc = %00000000


'_________pic to mc145436a assignments______________________

dtmf_ready VAR PORTA.0 'pin 12 (DV)
select_dtmf VAR PORTA.1 'pin 3 (Enamble)
reset VAR PORTA.2 'pin 5 (GT)
DT0 VAR PORTB.4 'pin 2 (D1)
DT1 VAR PORTB.5 'pin 1 (D2)
DT2 VAR PORTB.6 'pin 14 (D4)
DT3 VAR PORTB.3 'pin 13 (D8)
ce var portA.3 'pin from isd chip
'____________________variables____________________ ______

dtmf VAR byte ' Stores most recent DTMF digit
dtmf1 var byte
password var byte [8]
codeword var byte [8]
codeword1 var byte [8]
c var byte
e var byte

'___________________Initial Conditions__________________
start:
High reset
pause 100
high ce
low select_dtmf
c = 0
e = 0
loop:
iF dtmf_ready = 0 Then loop ' Check for DTMF present, if none loop again

welcome:
portc = %00000000
pause 20
gosub play 'play welcome statement
begin:
if dtmf_ready = 0 then begin 'waits for number to be depressed
select_dtmf = 1 ' Enable the data output from the MT8870
Pause 1 ' Pause 1 mS to let data settle
dtmf = 0
IF DT0 = 1 Then 'Check Input port 0
dtmf = dtmf + 1
EndIF
IF DT1 = 1 Then 'Check Input port 1
dtmf = dtmf + 2
EndIF
IF DT2 = 1 Then 'Check Input port 2
dtmf = dtmf + 4
EndIF
IF DT3 = 1 Then 'Check Input port 3
dtmf = dtmf + 8
EndIF
LookUp dtmf,["_1234567890*#"],dtmf
dtmf_wait1:
IF dtmf_ready Then dtmf_wait1 ' Loop here until DTMF signal stops
select_dtmf = 0 ' Disable the MT8870 data output
low reset
high reset

select case c 'places number in an array
case 0
password [0]=dtmf
case 1
password [1]=dtmf
case 2
password [2]=dtmf
case 3
password [3]=dtmf
case 4
password [4]=dtmf
case 5
password [5]=dtmf
case 6
password [6]=dtmf
case 7
password [7]=dtmf
end select
Select case dtmf
case "1"
portc = %10010111
pause 200
low ce
pause 200
High ce
case "2"
portc = %10011001
pause 200
low ce
pause 200
high ce
case "3"
portc = %10011011
pause 200
low ce
pause 200
high ce
case "4"
portc = %10011101
pause 200
low ce
pause 200
high ce
case "5"
portc = %10011111
pause 200
low ce
pause 200
high ce
case "6"
portc = %10100001
pause 200
low ce
pause 200
high ce
case "7"
portc = %10100011
pause 200
low ce
pause 200
high ce
case "8"
portc = %10100101
pause 200
low ce
pause 200
high ce
case "9"
portc = %10100111
pause 200
low ce
pause 200
high ce
case "0"
portc = %10101001
pause 200
low ce
pause 200
high ce
end select
c = c + 1
if c =< 7 then begin
if password [0] = "1" then
goto password1
else
goto user_password
endif
password1:
if password [1] = "2" then
goto password2
else
goto error
endif
password2:
if password [2] = "3" then
goto password3
else
goto error
endif
password3:
if password [3] = "4" then
goto password4
else
goto error
endif
password4:
if password [4] = "5" then
goto password5
else
goto error
endif
password5:
if password [5] = "6" then
goto password6
else
goto error
endif
password6:
if password [6] = "7" then
goto password7
else
goto error
endif
password7:
if password [7] = "8" then
goto play_menu_message
else
goto error
endif

Travin

BigWumpus
- 22nd May 2006, 21:26
Your code is very "unoptimal".

3 Tips:
Replace the whole "select case"-statement by 1 command:
password[c]=dtmf

The if-then-else for checking the password may be shortened:
if password[1]<>"1" then goto error
if password[2]<>"2" then goto error
...

and the last select-case-statement could be shortened a lot by placing the low-pause-high-sequence in one part at the end ...



The datasheet of the mc145436a tells a minimum time of 18us for the Guardtime-input. Maybe they mean the minimum pulselength for reset. Your pulse is to short, PICs are fast !!!

Travin77
- 23rd May 2006, 00:52
Well I tried your ideas to much avail, they didn't solve the problem. Its like the program won't compare the parts of the array to constant values. Thanks for the help. I just don't know what else to try. Also, once the password doesn't pass the if then statement, the program should play the error message and advance the variable "e" by one. Instead, the program just jumps back to the beginning and plays the welcome statement. Here is the updated code that still doesn't work. thanks.

start:
pause 100
High reset
high ce
low select_dtmf
c = 0
e = 0

loop:
iF dtmf_ready = 0 Then loop ' Check for DTMF present, if none loop again
welcome:
portc = %00000000
pause 20
gosub play 'play welcome statement
begin:
if dtmf_ready = 0 then begin 'waits for number to be depressed
select_dtmf = 1 ' Enable the data output from the MT8870
Pause 1 ' Pause 1 mS to let data settle
dtmf = 0
IF DT0 = 1 Then 'Check Input port 0
dtmf = dtmf + 1
EndIF
IF DT1 = 1 Then 'Check Input port 1
dtmf = dtmf + 2
EndIF
IF DT2 = 1 Then 'Check Input port 2
dtmf = dtmf + 4
EndIF
IF DT3 = 1 Then 'Check Input port 3
dtmf = dtmf + 8
EndIF
LookUp dtmf,["_1234567890*#"],dtmf
dtmf_wait1:
IF dtmf_ready = 1 Then dtmf_wait1 ' Loop here until DTMF signal stops
select_dtmf = 0 ' Disable the MT8870 data output
low reset
high reset

password[c]=dtmf

Select case dtmf
case "1"
portc = %10010111
pause 200
low ce
pause 200
High ce
case "2"
portc = %10011001
pause 200
low ce
pause 200
high ce
case "3"
portc = %10011011
pause 200
low ce
pause 200
high ce
case "4"
portc = %10011101
pause 200
low ce
pause 200
high ce
case "5"
portc = %10011111
pause 200
low ce
pause 200
high ce
case "6"
portc = %10100001
pause 200
low ce
pause 200
high ce
case "7"
portc = %10100011
pause 200
low ce
pause 200
high ce
case "8"
portc = %10100101
pause 200
low ce
pause 200
high ce
case "9"
portc = %10100111
pause 200
low ce
pause 200
high ce
case "0"
portc = %10101001
pause 200
low ce
pause 200
high ce
end select
c = c + 1
if c =< 7 then begin
if password [0] <> "1" then user_password
if password [1] <> "2" then error
if password [2] <> "3" then error
if password [3] <> "4" then error
if password [4] <> "5" then error
if password [5] <> "6" then error
if password [6] <> "7" then error
if password [7] <> "8" then
goto error
else
goto play_menu_message
endif
user_password:
if password [0] <> codeword [0] then error
if password [1] <> codeword [1] then error
if password [2] <> codeword [2] then error
if password [3] <> codeword [3] then error
if password [4] <> codeword [4] then error
if password [5] <> codeword [5] then error
if password [6] <> codeword [6] then error
if password [7] <> codeword [7] then error
goto play_menu_message
error:
e = e + 1
if e >= 2 then end_call
portc = %00001000
pause 20
gosub play'play error message
goto begin
play_menu_message:
portc = %00010010
pause 20
gosub play 'play menu message

Travin

BigWumpus
- 23rd May 2006, 07:46
"if c =< 7 then begin"

maybe this must be written "if c<= 7 then begin"

BigWumpus
- 23rd May 2006, 07:52
Only when you are playing the single keys, you use the ce-signal. On all other places, only portc ist filled and then.... ?

Travin77
- 25th May 2006, 02:27
Hello all. Hoping someone knows how to fix this damn thing. It still won't take the data into the array. I know it is decoding fine. Any ideas? All are welcome. My best guess is the if statements, but I don't know. If anyone has another option for a code, that would be just fine too. Thanks Paul, your help did make it run smoother. Here is the code:

@ device pic16F876A, hs_osc, wdt_on, lvp_off, protect_off
include "MODEDEFS.BAS"
define OSC 20
adcon1=7
trisa.0 = 1
trisa.1 = 0
trisa.2 = 0
trisa.3 = 0
trisb = %11111111
trisc = %00000000


'_________pic to mc145436a assignments______________________

dtmf_ready VAR PORTA.0 'pin 12 (DV)
select_dtmf VAR PORTA.1 'pin 3 (Enamble)
reset VAR PORTA.2 'pin 5 (GT)
DT0 VAR PORTB.4 'pin 2 (D1)
DT1 VAR PORTB.5 'pin 1 (D2)
DT2 VAR PORTB.6 'pin 14 (D4)
DT3 VAR PORTB.3 'pin 13 (D8)
ce var portA.3 'pin from isd chip
'____________________variables____________________ ______

dtmf VAR byte ' Stores most recent DTMF digit
dtmf1 var byte
password var byte [8]
codeword var byte [8]
codeword1 var byte [8]
c var byte
e var byte

'___________________Initial Conditions__________________
start:
pause 100
ce = 1
reset = 1
low select_dtmf
c = 0
e = 0

loop:
iF dtmf_ready = 0 Then loop ' Check for DTMF present, if none loop again
welcome:
portc = %00000000
pause 200
ce = 0
pause 200
ce = 1
begin:
if dtmf_ready = 0 then begin 'waits for number to be depressed
select_dtmf = 1 ' Enable the data output from the MT8870
Pause 1 ' Pause 1 mS to let data settle
dtmf = 0
IF DT0 = 1 Then 'Check Input port 0
dtmf = dtmf + 1
EndIF
IF DT1 = 1 Then 'Check Input port 1
dtmf = dtmf + 2
EndIF
IF DT2 = 1 Then 'Check Input port 2
dtmf = dtmf + 4
EndIF
IF DT3 = 1 Then 'Check Input port 3
dtmf = dtmf + 8
EndIF
LookUp dtmf,["_1234567890*#"],dtmf
dtmf_wait1:
IF dtmf_ready = 1 Then dtmf_wait1 ' Loop here until DTMF signal stops
select_dtmf = 0 ' Disable the MT8870 data output
reset = 0
reset = 1

password[c]=dtmf

Select case dtmf
case "1"
portc = %10010111
case "2"
portc = %10011001
case "3"
portc = %10011011
case "4"
portc = %10011101
case "5"
portc = %10011111
case "6"
portc = %10100001
case "7"
portc = %10100011
case "8"
portc = %10100101
case "9"
portc = %10100111
case "0"
portc = %10101001
end select
pause 200
ce = 0
pause 200
ce = 1
c = c + 1
if c <= 7 then begin
if password [0] <> "1" then user_password
if password [1] <> "2" then error
if password [2] <> "3" then error
if password [3] <> "4" then error
if password [4] <> "5" then error
if password [5] <> "6" then error
if password [6] <> "7" then error
if password [7] <> "8" then
goto error
else
goto play_menu_message
endif
user_password:
if password [0] <> codeword [0] then error
if password [1] <> codeword [1] then error
if password [2] <> codeword [2] then error
if password [3] <> codeword [3] then error
if password [4] <> codeword [4] then error
if password [5] <> codeword [5] then error
if password [6] <> codeword [6] then error
if password [7] <> codeword [7] then error
goto play_menu_message
error:
e = e + 1
if e >= 2 then end_call
c = 0
portc = %00001000
pause 200
ce = 0
pause 200
ce = 1
goto begin
play_menu_message:
portc = %00010010
pause 200
ce = 0
pause 200
ce = 1
menu:
if dtmf_ready = 0 then menu'waits for number to be depressed
gosub GetDtmf 'gets number

Wink
- 25th May 2006, 05:58
I built a DTMF decoder a few years back using a CM8880 and I would have been lost without the use of a LCD connected. I first wrote a routine to display the DTMF tone on the LCD, so as I played with the keypad, I could see the keys that I pushed. Once I was convinced my programming worked, I then started writing the second routine for the passcode, and with the LCD attached I could do checks within the programming when I ran into troubles. I hope this helps!

Wink

khaynes
- 25th May 2006, 17:26
Hello,

I looked at your code and had a couple of questions you might look into. They are marked with <--
Hope this is helpfull.

Keith

if c <= 7 then begin
if password [0] <> "1" then user_password ' <-- Why isn't this "then error" ?
if password [1] <> "2" then error
if password [2] <> "3" then error
if password [3] <> "4" then error
if password [4] <> "5" then error
if password [5] <> "6" then error
if password [6] <> "7" then error
if password [7] <> "8" then
goto error
else
goto play_menu_message ' <-- This is where the code gets to if the password was "12345678" Can you tell if the code ever gets here ?
endif
user_password:
if password [0] <> codeword [0] then error ' <-- The value of codeword[0] is undefined.
if password [1] <> codeword [1] then error ' <-- The value of codeword[1] is undefined etc.
if password [2] <> codeword [2] then error
if password [3] <> codeword [3] then error
if password [4] <> codeword [4] then error
if password [5] <> codeword [5] then error
if password [6] <> codeword [6] then error
if password [7] <> codeword [7] then error
goto play_menu_message
error:
e = e + 1
if e >= 2 then end_call <-- someof your code seems to be missing, where is end_call defined ?
c = 0
portc = %00001000
pause 200
ce = 0
pause 200
ce = 1
goto begin
play_menu_message:
portc = %00010010
pause 200
ce = 0
pause 200
ce = 1
menu:
if dtmf_ready = 0 then menu'waits for number to be depressed
gosub GetDtmf 'gets number

Travin77
- 25th May 2006, 21:26
As for the LCD, I had the LCD hooked up. All of the decode works. Now, when the number is decoded, the isd25120 chip repeats the number entered. When the program initiates, the welcome statement plays when the user pushes any button. This prompts him to enter a password. The pic starts repeating the digits decoded after 5 digits have been input( for this I have no explanation why). Every tone decoded after is announced perfectly. That section of the code is after the password[c]. So I reason that the tone is being input into the array. When c = 8 the code should compare the array to the constants but it doesn't. It also doesn't play the error message. It allows about 7-8 more characters to be input and then starts over with the welcome message.

if password [0] <> "1" then user_password ' <-- Why isn't this "then error" ?
If password[0] doesn't equal "1", then I want the program to check codeword[0] to see if they equal.

goto play_menu_message ' <-- This is where the code gets to if the password was "12345678" Can you tell if the code ever gets here ?

As far as I can tell, The code never gets here.

if password [0] <> codeword [0] then error ' <-- The value of codeword[0] is undefined.
if password [1] <> codeword [1] then error ' <-- The value of codeword[1] is undefined etc.

These are undefined because in the play_menu_message the option is given to set this. I will post this section of the code. Here is the entire program:

@ device pic16F876A, hs_osc, wdt_on, lvp_off, protect_off
include "MODEDEFS.BAS"
define OSC 20
adcon1=7
trisa.0 = 1
trisa.1 = 0
trisa.2 = 0
trisa.3 = 0
trisb = %11111111
trisc = %00000000


'_________pic to mc145436a assignments______________________

dtmf_ready VAR PORTA.0 'pin 12 (DV)
select_dtmf VAR PORTA.1 'pin 3 (Enamble)
reset VAR PORTA.2 'pin 5 (GT)
DT0 VAR PORTB.4 'pin 2 (D1)
DT1 VAR PORTB.5 'pin 1 (D2)
DT2 VAR PORTB.6 'pin 14 (D4)
DT3 VAR PORTB.3 'pin 13 (D8)
ce var portA.3 'pin from isd chip
'____________________variables____________________ ______

dtmf VAR byte ' Stores most recent DTMF digit
dtmf1 var byte
password var byte [8]
codeword var byte [8]
codeword1 var byte [8]
c var byte
e var byte

'___________________Initial Conditions__________________
start:
pause 100
ce = 1
reset = 1
low select_dtmf
c = 0
e = 0

loop:
iF dtmf_ready = 0 Then loop ' Check for DTMF present, if none loop again
welcome:
portc = %00000000
pause 200
ce = 0
pause 200
ce = 1
begin:
if dtmf_ready = 0 then begin 'waits for number to be depressed
select_dtmf = 1 ' Enable the data output from the MT8870
Pause 1 ' Pause 1 mS to let data settle
dtmf = 0
IF DT0 = 1 Then 'Check Input port 0
dtmf = dtmf + 1
EndIF
IF DT1 = 1 Then 'Check Input port 1
dtmf = dtmf + 2
EndIF
IF DT2 = 1 Then 'Check Input port 2
dtmf = dtmf + 4
EndIF
IF DT3 = 1 Then 'Check Input port 3
dtmf = dtmf + 8
EndIF
LookUp dtmf,["_1234567890*#"],dtmf
dtmf_wait1:
IF dtmf_ready = 1 Then dtmf_wait1 ' Loop here until DTMF signal stops
select_dtmf = 0 ' Disable the MT8870 data output
reset = 0
reset = 1

password[c]=dtmf

Select case dtmf
case "1"
portc = %10010111
case "2"
portc = %10011001
case "3"
portc = %10011011
case "4"
portc = %10011101
case "5"
portc = %10011111
case "6"
portc = %10100001
case "7"
portc = %10100011
case "8"
portc = %10100101
case "9"
portc = %10100111
case "0"
portc = %10101001
end select
pause 200
ce = 0
pause 200
ce = 1
c = c + 1
if c <= 7 then begin
if password [0] <> "1" then user_password
if password [1] <> "2" then error
if password [2] <> "3" then error
if password [3] <> "4" then error
if password [4] <> "5" then error
if password [5] <> "6" then error
if password [6] <> "7" then error
if password [7] <> "8" then
goto error
else
goto play_menu_message
endif
user_password:
if password [0] <> codeword [0] then error
if password [1] <> codeword [1] then error
if password [2] <> codeword [2] then error
if password [3] <> codeword [3] then error
if password [4] <> codeword [4] then error
if password [5] <> codeword [5] then error
if password [6] <> codeword [6] then error
if password [7] <> codeword [7] then error
goto play_menu_message
error:
e = e + 1
if e >= 2 then end_call
c = 0
portc = %00001000
pause 200
ce = 0
pause 200
ce = 1
goto begin
play_menu_message:
portc = %00010010
pause 200
ce = 0
pause 200
ce = 1
menu:
if dtmf_ready = 0 then menu'waits for number to be depressed
gosub GetDtmf 'gets number

If dtmf = "1" then set_password
else
goto play_menu_message:
endif

set_password:
c = 0
portc = %01100101
pause 20
gosub play 'play enter password message
hold:
if dtmf_ready = 0 then hold
gosub getdtmf
codeword[c] = dtmf
c = c + 1
if c =< 7 then hold
c = 0
portc = %11011010
pause 20
gosub play 'play re-enter password message
hold1:
if dtmf_ready = 0 then hold1
gosub getdtmf
codeword1[c]=dtmf
c = c + 1
if c =< 7 then hold1
if codeword[0] <> codeword1[0] then password_entry_error
if codeword[1] <> codeword1[1] then password_entry_error
if codeword[2] <> codeword1[2] then password_entry_error
if codeword[3] <> codeword1[3] then password_entry_error
if codeword[4] <> codeword1[4] then password_entry_error
if codeword[5] <> codeword1[5] then password_entry_error
if codeword[6] <> codeword1[6] then password_entry_error
if codeword[7] <> codeword1[7] then password_entry_error
password_correct:
portc = %01111110
pause 20
gosub play 'play password has been changed message
pause 3000
goto play_menu_message
password_entry_error:
portc = %01110101
pause 20
gosub play 'plays entries do not match
pause 3000
goto play_menu_message
end_call:
portc = %10010001
pause 20
gosub play'play finish message
goto start
play:
ce = 0
pause 200
ce = 1
return
GetDtmf:
select_dtmf = 1 ' Enable the data output from the MT8870
Pause 1 ' Pause 1 mS to let data settle
dtmf = 0
IF DT0 = 1 Then 'Check Input port 0
dtmf = dtmf + 1
EndIF
IF DT1 = 1 Then 'Check Input port 1
dtmf = dtmf + 2
EndIF
IF DT2 = 1 Then 'Check Input port 2
dtmf = dtmf + 4
EndIF
IF DT3 = 1 Then 'Check Input port 3
dtmf = dtmf + 8
EndIF
LookUp dtmf,["_1234567890*#"],dtmf
dtmf_wait:
IF dtmf_ready = 0 Then dtmf_wait ' Loop here until DTMF signal stops
select_dtmf = 0 ' Disable the MT8870 data output
reset = 0
reset = 1
Select case dtmf
case "1"
portc = %10010111
case "2"
portc = %10011001
case "3"
portc = %10011011
case "4"
portc = %10011101
case "5"
portc = %10011111
case "6"
portc = %10100001
case "7"
portc = %10100011
case "8"
portc = %10100101
case "9"
portc = %10100111
case "0"
portc = %10101001
end select
pause 200
ce = 0
pause 200
ce = 1
return

Wink
- 26th May 2006, 06:02
After your program senses the first button push, your isd25120 message plays, but you are not cycling out that button push, you are going straight to another loop (BEGIN).

loop:
iF dtmf_ready = 0 Then loop ' Check for DTMF present, if none loop again
welcome:
portc = %00000000
pause 200
ce = 0
pause 200
ce = 1
begin:
if dtmf_ready = 0 then begin 'waits for number to be depressed

Try adding the following just after ( ce = 1 ) and just before ( begin: ) :

select_dtmf = 1 ' Enable the data output from the MT8870
Pause 1 ' Pause 1 mS to let data settle
dtmf_wait2:
IF dtmf_ready = 1 Then dtmf_wait2 ' Loop here until DTMF signal stops
select_dtmf = 0 ' Disable the MT8870 data output
reset = 0
pause 100
reset = 1

Also, lower down in the program you have more than once:

reset = 0
reset = 1

That is a very fast blip to the GT pin. Try giving it a chance to see it!

Add a PAUSE 100 between the trasistion.

reset = 0
pause 100
reset = 1

You probably notice I added this pause in the upper portion of the program too!

I am still trying to figure out how the routines for the password work, that sure is some creative programming! Maybe some comments beside them would help others (and me) understand it. (Or is it just me?) It does compile, but not sure how it works, or even it it does?!

Hope this helps

Wink
- 26th May 2006, 06:13
After your program senses the first button push, your isd25120 message plays, but you are not cycling out that button push, you are going straight to another loop (BEGIN).

loop:
iF dtmf_ready = 0 Then loop ' Check for DTMF present, if none loop again
welcome:
portc = %00000000
pause 200
ce = 0
pause 200
ce = 1
begin:
if dtmf_ready = 0 then begin 'waits for number to be depressed

Try adding the following just after (ce = 1) and just before (begin:):

select_dtmf = 1 ' Enable the data output from the MT8870
Pause 1 ' Pause 1 mS to let data settle
dtmf_wait2:
IF dtmf_ready = 1 Then dtmf_wait1 ' Loop here until DTMF signal stops
select_dtmf = 0 ' Disable the MT8870 data output
reset = 0
pause 100
reset = 1

Also, lower down in the program you have a couple of times:

reset = 0
reset = 1

That is a very fast blip to the GT pin. Try giving it a chance to see it!

Add a PAUSE 100 between the trasistion.

reset = 0
pause 100
reset = 1

You probably notice I added this pause in the upper portion of the program too!

I am still trying to figure out how the routines for the password work, that sure is some creative programming! Maybe some comments beside them would help others (and me) understand it. (Or is it just me?) It does compile, but not sure how it works, or even it it does?!

Hope this helps

Travin77
- 26th May 2006, 23:26
Here was my logic (if you can call it that) for the password:

In the beginning, I make an array (password[8])
After the welcome message plays, the pic waits for a tone. Once it sees the tone, it is decoded and placed in "password[c]=dtmf", where c is initially "0".
The program then advances c ( c = c + 1) and compares it to this statement "if c <= 7 then begin". Since c is only at 1, the program goes back up to wait for another tone. Once that tone is decoded, it places it in password[c], which this time is password[1] since c = 1. This goes on until all eight sections of the array are filled, in other words "c = 8". The program then goes to the next part of the program:

if password [0] <> "1" then error
if password [1] <> "2" then error
if password [2] <> "3" then error
if password [3] <> "4" then error
if password [4] <> "5" then error
if password [5] <> "6" then error
if password [6] <> "7" then error
if password [7] <> "8" then
goto error
else
goto play_menu_message
endif

each section of the array is compared to a hard coded value. If any of the single sections of the array fail the comparison, the program skips to the error routine. That is how it is supposed to work, however, at this point it doesn't work yet. Thanks for the advice.

Travin

Wink
- 27th May 2006, 00:36
So I understand, does the following section play a sound for each number that is pressed? If so, does it work? Or is the problem before this section of code?

Select case dtmf
case "1"
portc = %10010111
case "2"
portc = %10011001
case "3"
portc = %10011011
case "4"
portc = %10011101
case "5"
portc = %10011111
case "6"
portc = %10100001
case "7"
portc = %10100011
case "8"
portc = %10100101
case "9"
portc = %10100111
case "0"
portc = %10101001
end select
pause 200
ce = 0
pause 200
ce = 1

Travin77
- 27th May 2006, 00:47
Yes, those are the addresses for the individual number sounds on the isd25120.
This section works sometimes, allow me to explain.

I call the pic and the phone answers.
I press any button and the welcome message plays.
I start entering my password (1,2,3,4,5,6,7,8)
On the first try, I do not have a verbal reply until after the number 5 is decoded. Everytime after it works like a champ. Then randomly, the welcome menu message plays. Once it plays, I enter the password again, this time I have a verbal response everytime. Once all eight numbers are entered, the program should play the menu message, but it doesn't happen. I just press a few more numbers and then we start all over at the welcome message. I am boggled. I thought it may be the power supply, but I have caps on the pic, the op amp (lm 741), and the dtmf decoder. I know all the sound recordings work as I wrote a program to verify that. I know the decode sequence works as well as I have checked this out as well. It is this damn password and array that seems to be the problem. Thanks.

Travin

Wink
- 27th May 2006, 05:16
Remove the spaces in your arrays and see if this changes anything.

For example, change this (and others). . .

if password [0] <> "1" then user_password
if password [1] <> "2" then error
if password [2] <> "3" then error
if password [3] <> "4" then error
if password [4] <> "5" then error
if password [5] <> "6" then error
if password [6] <> "7" then error
if password [7] <> "8" then
goto error


to this. . .

if password[0] <> "1" then user_password
if password[1] <> "2" then error
if password[2] <> "3" then error
if password[3] <> "4" then error
if password[4] <> "5" then error
if password[5] <> "6" then error
if password[6] <> "7" then error
if password[7] <> "8" then
goto error

and also change this (and others). . .

password var byte [8]
codeword var byte [8]
codeword1 var byte [8]


to this . . .

password var byte[8]
codeword var byte[8]
codeword1 var byte[8]

I always thought that they had to be together without a space, but I could be wrong. Doesn’t hurt to try it.

Let me know.

BigWumpus
- 27th May 2006, 10:15
Just do some debugging !


1. Put the speaking of the single digits in a subroutine.

2. After collecting 8 digits, play each digit (with a pause!) through this subroutine in order to check the collected password.

3. put some LEDs to the PIC in order to see the handshakes from your chips.

4. fill the password by hardcoding:
After collecting 8 digits insert:
Password[0]="1"
Password[1]="2"...

I think, you are loosing digits, or there is some noise, so you get whorse digits.

Wink
- 27th May 2006, 15:25
I had a thought, but over looked the lookup command

Travin77
- 27th May 2006, 16:25
I changed the loop at the beginning from its original to a repeat:until loop. This didn't change anything. So, I made a rountine that allows the entry of 8 digits to be input. It then speaks them back to me. They are sometimes different than what I pressed into the keypad. Most of the mistakes are duplicates. All things being equal, that still doesn't explain why the error message doesn't play in the normal program. I guess I need to "debounce" the input section of the code with the software, but I am not sure how. Any ideas other than a whole lot of pauses? Thanks for the help. Here is the code I used:

@ device pic16F876A, hs_osc, wdt_on, lvp_off, protect_off
include "MODEDEFS.BAS"
define OSC 20
adcon1=7
trisa.0 = 1
trisa.1 = 0
trisa.2 = 0
trisa.3 = 0
trisb = %11111111
trisc = %00000000


'_________pic to mc145436a assignments______________________

dtmf_ready VAR PORTA.0 'pin 12 (DV)
select_dtmf VAR PORTA.1 'pin 3 (Enamble)
reset VAR PORTA.2 'pin 5 (GT)
DT0 VAR PORTB.4 'pin 2 (D1)
DT1 VAR PORTB.5 'pin 1 (D2)
DT2 VAR PORTB.6 'pin 14 (D4)
DT3 VAR PORTB.3 'pin 13 (D8)
ce var portA.3 'pin from isd chip
'____________________variables____________________ ______

dtmf VAR byte ' Stores most recent DTMF digit
dtmf1 var byte
password var byte [8]
codeword var byte [8]
codeword1 var byte [8]
c var byte
e var byte

'___________________Initial Conditions__________________
start:
pause 100
ce = 1
reset = 1
select_dtmf = 0
c = 0
e = 0

loop:
iF dtmf_ready = 1 Then
goto welcome
else
goto loop
endif
welcome:
portc = %00000000
pause 20
ce = 0
pause 20
ce = 1
pause 2000
c = 0
repeat
begin:
if dtmf_ready = 0 then begin 'waits for number to be depressed
select_dtmf = 1 ' Enable the data output from the MT8870
Pause 10 ' Pause 100 mS to let data settle
dtmf = 0
IF DT0 = 1 Then 'Check Input port 0
dtmf = dtmf + 1
EndIF
IF DT1 = 1 Then 'Check Input port 1
dtmf = dtmf + 2
EndIF
IF DT2 = 1 Then 'Check Input port 2
dtmf = dtmf + 4
EndIF
IF DT3 = 1 Then 'Check Input port 3
dtmf = dtmf + 8
EndIF
LookUp dtmf,["_1234567890*#"],dtmf

dtmf_wait1:
IF dtmf_ready = 1 Then dtmf_wait1 ' Loop here until DTMF signal stops
reset = 0
PAUSEUS 30 ' Hold GT for > 18mS
reset = 1
select_dtmf = 0 ' Disable the MT8870 data output
PAUSEUS 400 ' Allows time for DV transition

password[c]=dtmf

Select case dtmf
case "1"
portc = %10010111
case "2"
portc = %10011001
case "3"
portc = %10011011
case "4"
portc = %10011101
case "5"
portc = %10011111
case "6"
portc = %10100001
case "7"
portc = %10100011
case "8"
portc = %10100101
case "9"
portc = %10100111
case "0"
portc = %10101001
end select
pause 20
ce = 0
pause 20
ce = 1
c = c + 1
until c > 7
Select case password[0]
case "1"
portc = %10010111
case "2"
portc = %10011001
case "3"
portc = %10011011
case "4"
portc = %10011101
case "5"
portc = %10011111
case "6"
portc = %10100001
case "7"
portc = %10100011
case "8"
portc = %10100101
case "9"
portc = %10100111
case "0"
portc = %10101001
end select
pause 20
ce = 0
pause 20
ce = 1
pause 1500
Select case password[1]
case "1"
portc = %10010111
case "2"
portc = %10011001
case "3"
portc = %10011011
case "4"
portc = %10011101
case "5"
portc = %10011111
case "6"
portc = %10100001
case "7"
portc = %10100011
case "8"
portc = %10100101
case "9"
portc = %10100111
case "0"
portc = %10101001
end select
pause 20
ce = 0
pause 20
ce = 1
pause 1500
Select case password[2]
case "1"
portc = %10010111
case "2"
portc = %10011001
case "3"
portc = %10011011
case "4"
portc = %10011101
case "5"
portc = %10011111
case "6"
portc = %10100001
case "7"
portc = %10100011
case "8"
portc = %10100101
case "9"
portc = %10100111
case "0"
portc = %10101001
end select
pause 20
ce = 0
pause 20
ce = 1
pause 1500
Select case password[3]
case "1"
portc = %10010111
case "2"
portc = %10011001
case "3"
portc = %10011011
case "4"
portc = %10011101
case "5"
portc = %10011111
case "6"
portc = %10100001
case "7"
portc = %10100011
case "8"
portc = %10100101
case "9"
portc = %10100111
case "0"
portc = %10101001
end select
pause 20
ce = 0
pause 20
ce = 1
pause 1500
Select case password[4]
case "1"
portc = %10010111
case "2"
portc = %10011001
case "3"
portc = %10011011
case "4"
portc = %10011101
case "5"
portc = %10011111
case "6"
portc = %10100001
case "7"
portc = %10100011
case "8"
portc = %10100101
case "9"
portc = %10100111
case "0"
portc = %10101001
end select
pause 20
ce = 0
pause 20
ce = 1
pause 1500
Select case password[5]
case "1"
portc = %10010111
case "2"
portc = %10011001
case "3"
portc = %10011011
case "4"
portc = %10011101
case "5"
portc = %10011111
case "6"
portc = %10100001
case "7"
portc = %10100011
case "8"
portc = %10100101
case "9"
portc = %10100111
case "0"
portc = %10101001
end select
pause 20
ce = 0
pause 20
ce = 1
pause 1500
Select case password[6]
case "1"
portc = %10010111
case "2"
portc = %10011001
case "3"
portc = %10011011
case "4"
portc = %10011101
case "5"
portc = %10011111
case "6"
portc = %10100001
case "7"
portc = %10100011
case "8"
portc = %10100101
case "9"
portc = %10100111
case "0"
portc = %10101001
end select
pause 20
ce = 0
pause 20
ce = 1
pause 1500
Select case password[7]
case "1"
portc = %10010111
case "2"
portc = %10011001
case "3"
portc = %10011011
case "4"
portc = %10011101
case "5"
portc = %10011111
case "6"
portc = %10100001
case "7"
portc = %10100011
case "8"
portc = %10100101
case "9"
portc = %10100111
case "0"
portc = %10101001
end select
pause 20
ce = 0
pause 20
ce = 1
pause 1500
goto start

Travin

P.S. I also added another 1600ma 4.5v power source in parallel to make sure that power wasn't an issue.

Travin77
- 27th May 2006, 16:44
If you hold the numbers depressed too long, the program puts the same number in the next array space. So, I am going to have to revisit the decode section. It is interesting that the dtmf chip is disabled at the time of data entry of the decoded number into the array. Also, only one verbal response plays.

Travin

No need to post a reply to myself. I debounced the software with a Pause 500 just before "until c > 7", and it worked like a champ. I tried several different pauses during tone entry and never had another repeat. So, thinking I had it solved, I placed the corrected code into the original code and whalla, the same problem. So, I guess the if then statements on the password section are bunk. It still won't play the error message if the entry is wrong, it won't go to the menu message if the entry is right, and it still starts over after pressing a random number of buttons on the phone after all eight digits of the password have been input.

BigWumpus
- 27th May 2006, 18:45
You wrote:

reset = 0
PAUSEUS 30 ' Hold GT for > 18mS
reset = 1


Remember, you wrote a 30uS pause, but you need a 18mS pause !



PS: How to write your Programm in 40 lines ?

Travin77
- 27th May 2006, 18:56
Thanks for the catch. I guess I just wasn't careful. I know my program is incredibally long for something so easy, I just figured since the pic couldn't do something as simple as play the damn error message or menu message, why should I trust it to jump to a subroutine. I figure my next step is to start removing chips from the equation. I am going to hook up the ol LCD screen and use the lcdout command instead of the audio. That way I can try to se if what is going on visually.

Travin

BigWumpus
- 27th May 2006, 18:58
You wrote:

DT0 VAR PORTB.4 'pin 2 (D1)
DT1 VAR PORTB.5 'pin 1 (D2)

out of the manual of the chip, I think you have mixed up Pin1 and Pin2.

Travin77
- 27th May 2006, 19:05
Those pins are correct. I used someone elses code off of this forum and never updated the note. There is now no problem with decoding or the tone entry into the array as far as I can tell. I tried about twenty different combonations leaving the keys pressed for different amounts of time and every time it played back without any problems. The only change I made was the pause 500 before "until c > 7", which solved the entry problem Now the issue seems to be the if password[0] <> "1" then error. I am not sure why but it can't manange to do something that simple.

BigWumpus
- 27th May 2006, 19:16
maybe:

@ device pic16F876A, hs_osc, wdt_on, lvp_off, protect_off

include "MODEDEFS.BAS"
define OSC 20
adcon1=7
trisc = %00000000

'_________pic to mc145436a assignments______________________
dtmf_ready VAR PORTA.0 'pin 12 (DV)
select_dtmf VAR PORTA.1 'pin 3 (Enable)
reset VAR PORTA.2 'pin 5 (GT)
DT0 VAR PORTB.4 'pin 2 (D1) ??
DT1 VAR PORTB.5 'pin 1 (D2) ??
DT2 VAR PORTB.6 'pin 14 (D4)
DT3 VAR PORTB.3 'pin 13 (D8)
ce var portA.3 'pin from isd chip

'____________________variables____________________ ______
dtmf VAR byte ' Stores most recent DTMF digit
dtmf1 var byte
password var byte [8]
codeword var byte [8]
codeword1 var byte [8]
c var byte
e var byte

'___________________Initial Conditions__________________
start:
pause 100:high ce:high reset:Low select_dtmf:e = 0
repeat
until dtmf_ready
portc = %00000000:ce = 0: pause 20:ce = 1: pause 2000:c = 0
repeat
Repeat
until dtmf_ready 'waits for number to be depressed
select_dtmf = 1 ' Enable the data output from the MT8870
dtmf = 0:dtmf.0=DT0:dtmf.1=DT1:dtmf.2=DT2:dtmf.3=DT3
LookUp dtmf,["_1234567890*#"],dtmf:password[c]=dtmf
Repeat : until dtmf_ready=0 ' Loop here until DTMF signal stops
reset = 0: PAUSEUS 30:Reset=1 ' Hold GT for > 18mS
select_dtmf = 0 ' Disable the MT8870 data output
gosub Output_DTMF:c = c + 1
until c > 7
c=0:repeat:dtmf=password[c]:gosub output_DTMF: Pause 1000:c=c+1:until c>7
goto start
end

Output_DTMF:
Lookup dtmf-"0",[%10101001,%10010111,%10011001,%10011011,%10011101, %10011111,%10100001,%10100011,%10100101,%10100111],PortC
pause 1:ce = 0: pause 1:ce = 1
return

Travin77
- 27th May 2006, 19:32
Your code compiles with errors. I don't quite understand it enough to change either. it doesn't like you lookup table, either of them. Also, it apprears you may have an extra repeat so I removed it. Thanks for the code, I am going to fiddle with it for a while.

Travin

I see know what you were doing. My compiler says it is missing an end block on the repeat.

BigWumpus
- 27th May 2006, 19:42
It compiles fine with the MP (instead of MPASM). (228 words in a 16F876A .. snif)
You must put some lines together.... they are wrapped.

Maybe it is interesting to check the OEM-signal of the ISD-chip to wait for the end of a message, before sending the next...

The "pause 20" around the ce=x can be shortened to "pauseus 10".

Why are you using 20Mhz ? It is VERY fast for this slow devices !
at 4MHz you can throw away some pauses....

Travin77
- 27th May 2006, 19:49
I did that. I had a routine that was interupt based on the EOM pin during which the pic would do nothing until the EOM bit was pulsed low. I found that I really didn't need to do that. I didn;t gain anything from it. My problem isn't the decode, its the if then statements. The pic just won't do them. It won't go on in the program, it won't play the error message, it just wants to loop back to the beginning. Do you have another way of doing the password section? As to why I am using 20 mhz, I don't know, thats just what I was using. I will try a 4 mhz osc. Now I guess my question for that is it still as OSC_hs or just external?

Travin

BigWumpus
- 27th May 2006, 20:43
Your code looked good:

if password[0]<>"1" Then goto error
if password[1]<>"2" Then goto error
...
if password[7]<>"8" Then goto error
menu:

error:



You can extend the Output_DTMF-routine to wait for the EOM-bit in the beginning.
And you can add some code in order to use this routine to play the other menu-messages, too.

Travin77
- 28th May 2006, 04:02
Well, I don't know what else to try. The code just doesn't work past the entry. The if then statements just don't work for some reason or maybe the pic is bad. I know for sure the decode process works as well as all of the addresses for the messages work as well. thanks for the help.

Travin

BigWumpus
- 28th May 2006, 08:23
OK,

the if-then-part must work !

Just insert this before:

password[0]="1"
password[1]="2"
...
password[7]="8"

and write, what happens !

Travin77
- 28th May 2006, 21:01
I did as you suggested. I hard coded the the password and then sent it thorugh the if then statements and nothing happened, until I press 2 buttons on the phone, and then the menu message played. It will just wait until two buttons, any buttons, are pushed. Wierd huh. This is how I program the chip. Before I actually program the chip, I always erase it, then program it. Here is the snippet of code I used:

@ device pic16F876A, hs_osc, wdt_on, lvp_off, protect_off
include "MODEDEFS.BAS"
define OSC 20
adcon1=7
trisa.0 = 1
trisa.1 = 0
trisa.2 = 0
trisa.3 = 0
trisb = %11111111
trisc = %00000000


'_________pic to mc145436a assignments______________________

dtmf_ready VAR PORTA.0 'pin 12 (DV)
select_dtmf VAR PORTA.1 'pin 3 (Enamble)
reset VAR PORTA.2 'pin 5 (GT)
DT0 VAR PORTB.4 'pin 2 (D1)
DT1 VAR PORTB.5 'pin 1 (D2)
DT2 VAR PORTB.6 'pin 14 (D4)
DT3 VAR PORTB.3 'pin 13 (D8)
ce var portA.3 'pin from isd chip
'____________________variables____________________ ______

dtmf VAR byte ' Stores most recent DTMF digit
dtmf1 var byte
password var byte[8]
codeword var byte[8]
codeword1 var byte[8]
c var byte
e var byte

'___________________Initial Conditions__________________
start:
pause 100
ce = 1
reset = 1
select_dtmf = 0
c = 0
e = 0

loop:
iF dtmf_ready = 1 Then
goto welcome
else
goto loop
endif
welcome:
portc = %00000000
pause 20
ce = 0
pause 20
ce = 1
pause 2000
c = 0

Entry:
pause 100
password[0] = "1"
password[1] = "2"
password[2] = "3"
password[3] = "4"
password[4] = "5"
password[5] = "6"
password[6] = "7"
password[7] = "8"
Pause 1000

password_check:

if password[0] <> "1" then error
if password[1] <> "2" then error
if password[2] <> "3" then error
if password[3] <> "4" then error
if password[4] <> "5" then error
if password[5] <> "6" then error
if password[6] <> "7" then error
if password[7] <> "8" then
goto error
else
goto menu_message
endif
user_password:
if password [0] <> codeword [0] then error
if password [1] <> codeword [1] then error
if password [2] <> codeword [2] then error
if password [3] <> codeword [3] then error
if password [4] <> codeword [4] then error
IF password [5] <> codeword [5] then error
if password [6] <> codeword [6] then error
if password [7] <> codeword [7] then error
goto menu_message
error:
e = e + 1
if e>= 2 then
portc = %10010001
pause 20
ce = 0
pause 20
ce = 1
pause 3000
goto start
else
c = 0
portc = %00001000
pause 200
ce = 0
pause 200
ce = 1
pause 4000
goto loop
endif
menu_message:
portc = %00010010
pause 20
ce = 0
pause 20
ce = 1
menu:
if dtmf_ready = 0 then menu'waits for number to be depressed
gosub GetDtmf 'gets number

branch dtmf1,[menu_message,led1,led2,led3,led4]

Another thing that is interesting, is that after the menu message is done playing, I press a "0" as to send it back to paly the menu message again, but it goes to the top and plays the welcome message again. Thanks a lot for the help. This thing is annoying the hell out of me.

Travin

BigWumpus
- 28th May 2006, 21:33
I don't think you are looking for help....

The code is just unreadable,
we dont know what your "GetDTMF" or "DTMF1" is...
What starts after the branch-command ?
I think the stearing of the mc1..... and the isd..... is wrong or incomplete. There are pause-statements more than needed... the mc1.... isn't resetted after the first keypress....

Why should I write any further ?

Be shure, I'm able to write all the code, but I don't know the hardware and wiring.

Travin77
- 28th May 2006, 21:55
I apologize for patronizing you. I didn't post the extra code because it is the same as before I thought. I mearly did as you had mentioned. I will not ask for your help anymore. Thanks for the help you have given me up to this point. You have pointed me in the right direction. I will continue to post my updates, in an effort maybe to help others. Thanks.

Travin

BigWumpus
- 28th May 2006, 23:28
Hi Travin,

dont be shocked by me !

dont stuck your head into the sand....

I want to give you help to reach the goal, but you have to learn !!!!
I think there are some gadgets in your circuits, we don't know...
You have no problem in the if-then-part, you have a problem in the communication and timing with your mc- and isd-parts !
You try to write lousy code to talk to them. You have to write subroutines which communicate in the only right way with the chips and you have to use them in your little programm !

I don't think your little problem need such a lot of postings...

Travin77
- 28th May 2006, 23:37
I guess I am just confused here. The led subroutines are merely a visual aid for the debuggin process. I have about 10 different program written for this contraption. I started with each section of the main program until it worked correctly. Then I moved to the next section and so forth. When I put them all together, they don't work. Like for instance, in the previous post, the branch command didn't work. The led didn't blink on and off for 3 seconds. I know this routine is good. Also, I shouldn't have to push a button twice to go from the if then statements of the password comparison to the menu_message, but it will just sit there until I press two buttons. I know that is no where in the code so I am confused as to why it is like that. Thanks for the help, and I am not uposed to learning. I do a couple of questions for you, in your code you wrote, you have this:

Lookup dtmf-"0",[%10101001,....... My question is what is -"0" for?

Also,

dtmf = 0:dtmf.0=DT0:dtmf.1=DT1:dtmf.2=DT2:dtmf.3=DT3
LookUp dtmf,["_1234567890*#"],dtmf how does the lookup table know which number has been decoded by using this sequence: dtmf.0=DT0:dtmf.1=DT1:dtmf.2=DT2:dtmf.3=DT3

Travin

BigWumpus
- 29th May 2006, 20:32
I do a couple of questions for you, in your code you wrote, you have this:

Lookup dtmf-"0",[%10101001,....... My question is what is -"0" for?


It's a trick !?!

You have:
an ASCII-character (a digit "0"..."9") inside the variable "dtmf"

You want to get:
a bitpattern for the isd-chip.

Solution:
I used the lookup-command to index an bit-pattern. If I subtract the numerical äquivalent of "0" (IMHO 048 dezimal) from the ASCII-character in dtmf, I get an index-number 0..9. The lookup-command gets the bitpattern out of the list (10 patterns) and put it into the portC.


Also,

dtmf = 0:dtmf.0=DT0:dtmf.1=DT1:dtmf.2=DT2:dtmf.3=DT3
LookUp dtmf,["_1234567890*#"],dtmf how does the lookup table know which number has been decoded by using this sequence: dtmf.0=DT0:dtmf.1=DT1:dtmf.2=DT2:dtmf.3=DT3
Travin

Read it like:
Clear all bits in dtmf
Get the bit out out DT0 and put it into dtmf.0
Get the bit out out DT1 and put it into dtmf.1
Get the bit out out DT2 and put it into dtmf.2
Get the bit out out DT3 and put it into dtmf.3

So, the 4 bits are puzzled to the variable ! (index-number)
The lookup-command gets an ASCII-character for this number and stores it into the variable.

You love to work with ASCII-characters. It's not bad, but you have to convert sometimes from index-number to ASCII-character and back.

Travin77
- 29th May 2006, 20:59
I assume here that when you say index number you mean a binary repesentation of that number. Does this make the pic run smother? By the way, I finally got your code to compile. It won't announce the digits as they decode not will it announce the array after the 8 digits are input. Still trying to make the program work like I need it to.

Thanks

Travin

Travin77
- 30th May 2006, 01:31
I found the problem. The isd chip is not playing the error or menu message. I put a led in those routines. I know now that the program is getting through them I guess I am not interfacing with the isd chip correctly. Back to the manual. Thanks for the help bigwimpus. If anyone knows how to properly interface to a isd chip (25120) and wouldn't mind sharing there knowledge, this bald guy would appreciate it. thanks again.

travin