' Name : REMOTEXT.pbp ' Compiler : PICBASIC PRO Compiler 2.6 ' Assembler : PM or MPASM ' Target PIC : PIC16F877-20, PIC18F452 or similar type ' Hardware : LAB-XT Experimenter Board ' Oscillator : 20MHz external ' Keywords : FREQOUT, LCDOUT, LOOKUP, SELECT CASE ' Description : PICBASIC PRO sample to demonstrate remote control using ' DTMF over a phone line. The LAB-XT will answer an incoming call on the ' third ring and sound a short tone to the caller. The caller can then ' control 2 leds by pressing keys on his telephone. ' ' Press 1 for LED4 ON ' Press 2 for LED3 ON ' Press 4 for LED4 OFF ' Press 5 for LED3 OFF ' Press 0 to disconnect Define LOADER_USED 1 ' Only required for melabs Loader Define OSC 20 ' Match the crystal on the board ' Define LCD registers and bits Define LCD_DREG PORTD Define LCD_DBIT 4 Define LCD_RSREG PORTE Define LCD_RSBIT 0 Define LCD_EREG PORTE Define LCD_EBIT 1 seize Var PORTD.1 ' Alias the line seize control pin loop_current Var PORTA.3 ' alias the loop current detect input pin ring_detect Var PORTA.2 ' Alias the ring-detect input pin dtmf_ready Var PORTA.4 ' Alias the dtmf data-ready pin select_dtmf Var PORTD.3 ' Alias the dtmf enable pin DTMF_out Var PORTE.2 ' Alias pin for remote user prompts led3 Var PORTC.0 ' Alias pin for LED3 led4 Var PORTC.1 ' Alias pin for LED4 TRISD = 0 ' Set PORTD to output PORTD = 0 ' Initialize PORTD, all zero ADCON1 = 7 ' Set PORTA and PORTE to digital Pause 200 ' Wait for LCD to start up LCDOut $fe,1 ' Clear display i Var Word ' Variable for loop count rings Var Byte ' Stores number of rings dtmf_digit Var Byte ' Stores dtmf received digit initialize: LCDOut $fe,1, "Waiting for call" ' Display user prompt Low seize ' Release the line rings = 0 ' Reset ring count to 0 i = 0 Low led3 ' Shut off LED3 Low led4 ' Shut off LED4 mainloop: Pause 1 ' Pause 1mS i = i + 1 ' Increment counter IF i > 5000 Then initialize ' If 5 seconds have elapsed without ring, re-initialize IF ring_detect Then mainloop ' Loop here until ring detected ringing: IF ring_detect = 0 Then i = 0 ' Clear timer variable if still ringing i = i + 1 ' Increment timer variable Pause 1 ' Pause 1mS IF i < 250 Then ringing ' Return to loop until 250mS after ring stops rings = rings + 1 ' Increment ring counter LCDOut $fe,1, DEC rings," rings detected" ' Display user prompt IF rings < 3 Then mainloop ' If less than 3 rings, wait for more seize = 1 ' If ring 5, answer the call Pause 250 ' Wait 250mS for the line to settle FreqOut DTMF_out, 500, 800 ' Play a short tone to prompt the caller LCDOut $fe,1, "Waiting for DTMF" ' Display user prompt listen: IF (seize = 1) AND (loop_current = 1) Then initialize ' Re-initialize if the call is dropped remotely IF dtmf_ready = 0 Then listen ' Check for DTMF present, if none loop again ' If DTMF present, continue select_dtmf = 1 ' Enable the data output from the MT8870 Pause 1 ' Pause 1 mS to let data settle dtmf_digit = (PORTB >> 4) ' Read the top nibble of PORTB for DTMF data ' Use LOOKUP to change the DTMF data to an ASCII character LookUp dtmf_digit, ["_1234567890*#ABCD"], dtmf_digit dtmf_wait: IF dtmf_ready Then dtmf_wait ' Loop here until DTMF signal stops select_dtmf = 0 ' Disable the MT8870 data output Select Case dtmf_digit ' Take action based on the dtmf digit Case "1" ' DTMF "1" lights LED3 High led3 Case "2" ' DTMF "2" lights LED4 High led4 Case "4" ' DTMF "4" kills LED3 Low led3 Case "5" ' DTMF "5" kills LED4 Low led4 Case "0" ' DTMF "0" hangs up and re-initializes GoTo initialize End Select GoTo listen ' Listen for next DTMF digit End