'**************************************************************** '* Name : ADC_blue_box_05.BAS * '* Author : df99 * '* Notice : Copyright (c) 2008 * '* : All Rights Reserved * '* Date : 3/9/2008 * '* Version : 0.5 * '* Notes : Simple PWM blue box with single pin * '* : keyboard decode. MF and DTMF modes. * '**************************************************************** ' Resistor network detection values assume a network of 14-1KOhm ' resistors in series, from Vdd to Vss, with a tap between each ' resistor pair. Taps at Vdd and Vss are not used, to avoid ADC ' issues when trying to read at the voltage rails. ' The slight effect of a 250KOhm pull-down resistor on the ADC input ' pin is also factored into the calculations, although the effect is ' almost negligible. ' Set PIC configuration fuses. PICBASIC PRO refreshes WDT automatically. ' HS_OSC works well for the Murata 20 MHz ceramic resonator. No parallel ' resistor required. @ DEVICE PIC12F683,HS_OSC,WDT_ON,PWRT_ON,MCLR_ON,BOD_OFF,CPD_OFF,PROTECT_OFF,IESO_OFF,FCMEN_OFF DEFINE OSC 20 ' 20 MHz clock DEFINE ADC_BITS 10 'Use 10 bit resolution with ADCIN DEFINE ADC_CLOCK 3 'Use internal RC clock for ADC only DEFINE ADC_SAMPLEUS 50 'Wait 50 uS before read after ADCIN turns on ADC ADCON0 = %10001001 'Right justify ADC, Vdd ref, Chan 2, enable ADC KEY VAR WORD 'Define variable for ADC input value MODE VAR WORD 'Tone mode KEYDOWN VAR WORD 'Keydown loop counter DTMF CON 0 'Alias for DTMF mode MF CON 1 'Alias for MF mode Mode = DTMF 'Default to DTMF mode loop: ADCIN 2, KEY 'Get keypad value again keydown = 0 'Clear keydown value 'Decode and play DTMF IF ((KEY > 37)AND(MODE = DTMF)) THEN GOSUB dtmftest 'Decode and play MF IF ((KEY > 37)AND(MODE = MF)) THEN GOSUB mftest Pause 10 'Allow ADC to settle between reads GOTO loop ' Any key value <= 37 is essentially 0 VDC because of the pull-down ' resistor, with some margin for noise. This means that no key has ' been pressed. mftest: IF ((KEY > 914) AND (KEY <= 1023)) THEN FREQOUT 0,120,700,900 'MF1 ' 4.64 volts calculated, with Vdd = 5VDC. ADC value=949 ' Prototype measured value with 5% resistors: 4.65 VDC IF ((KEY > 841) AND (KEY <= 914)) THEN FREQOUT 0,120,700,1100 'MF2 ' 4.29 volts calculated, with Vdd = 5VDC. ADC value=878 ' Mean with previous value = 914 ' Prototype measured value with 5% resistors: 4.29 VDC IF ((KEY > 767) AND (KEY <= 841)) THEN FREQOUT 0,120,900,1100 'MF3 ' 3.93 volts calculated, with Vdd = 5VDC. ADC value=804 ' Mean with previous value = 841 ' Prototype measured value with 5% resistors: 3.94 VDC IF ((KEY > 694) AND (KEY <= 767)) THEN FREQOUT 0,120,700,1300 'MF4 ' 3.57 volts calculated, with Vdd = 5VDC. ADC value=730 ' Mean with previous value = 767 ' Prototype measured value with 5% resistors: 3.58 VDC IF ((KEY > 621) AND (KEY <= 694)) THEN FREQOUT 0,120,900,1300 'MF5 ' 3.21 volts calculated, with Vdd = 5VDC. ADC value=657 ' Mean with previous value = 694 ' Prototype measured value with 5% resistors: 3.22 VDC IF ((KEY > 549) AND (KEY <= 621)) THEN FREQOUT 0,120,1100,1300 'MF6 ' 2.86 volts calculated, with Vdd = 5VDC. ADC value=585 ' Mean with previous value = 621 ' Prototype measured value with 5% resistors: 2.86 VDC IF ((KEY > 475) AND (KEY <= 549)) THEN FREQOUT 0,120,700,1500 'MF7 ' 2.50 volts calculated, with Vdd = 5VDC. ADC value=512 ' Mean with previous value = 549 ' Prototype measured value with 5% resistors: 2.51 VDC IF ((KEY > 401) AND (KEY <= 475)) THEN FREQOUT 0,120,900,1500 'MF8 ' 2.14 volts calculated, with Vdd = 5VDC. ADC value=438 ' Mean with previous value = 475 ' Prototype measured value with 5% resistors: 2.15 VDC IF ((KEY > 329) AND (KEY <= 401)) THEN FREQOUT 0,120,1100,1500 'MF9 ' 1.78 volts calculated, with Vdd = 5VDC. ADC value=364 ' Mean with previous value = 401 ' Prototype measured value with 5% resistors: 1.79 VDC IF ((KEY > 256) AND (KEY <= 329)) THEN FREQOUT 0,120,1100,1700 'KP ' 1.43 volts calculated, with Vdd = 5VDC. ADC value=293 ' Mean with previous value = 329 ' Prototype measured value with 5% resistors: 1.43 VDC IF ((KEY > 182) AND (KEY <= 256)) THEN FREQOUT 0,120,1300,1500 'MF0 ' 1.07 volts calculated, with Vdd = 5VDC. ADC value=219 ' Mean with previous value = 256 ' Prototype measured value with 5% resistors: 1.07 VDC IF ((KEY > 110) AND (KEY <= 182)) THEN FREQOUT 0,120,1500,1700 'ST ' 0.71 volts calculated, with Vdd = 5VDC. ADC value=145 ' Mean with previous value = 182 ' Prototype measured value with 5% resistors: 0.72 VDC IF ((KEY > 37) AND (KEY <= 110)) THEN FREQOUT 0,1000,2600 'Seize ' 0.36 volts calculated, with Vdd = 5VDC. ADC value=74 ' Mean with previous value = 110 ' Mean with ground (0VDC) = 37 ' Prototype measured value with 5% resistors: 0.36 VDC ' The following code waits until the key is released (if pressed) to insure ' one tone burst per keypress. Delay seems needed for reliable ADC settling, ' since loop is so small. A counter tracks the number of 10 ms iterations ' through the loop to time the keydown period to trigger a mode change. again: 'Get keypad value again after tone ADCIN 2, KEY 'Allow ADC to settle between reads Pause 10 'Increment keydown count KEYDOWN = KEYDOWN + 1 'Toggle mode after 2 sec of 2600 key keydown if ((KEYDOWN > 200)and(KEY > 37)AND(KEY <= 110))then gosub modechg 'Wait for key release IF (KEY > 37) THEN again RETURN dtmftest: IF ((KEY > 914) AND (KEY <= 1023)) THEN FREQOUT 0,120,697,1209 'DTMF1 IF ((KEY > 841) AND (KEY <= 914)) THEN FREQOUT 0,120,697,1336 'DTMF2 IF ((KEY > 767) AND (KEY <= 841)) THEN FREQOUT 0,120,697,1477 'DTMF3 IF ((KEY > 694) AND (KEY <= 767)) THEN FREQOUT 0,120,770,1209 'DTMF4 IF ((KEY > 621) AND (KEY <= 694)) THEN FREQOUT 0,120,770,1336 'DTMF5 IF ((KEY > 549) AND (KEY <= 621)) THEN FREQOUT 0,120,770,1477 'DTMF6 IF ((KEY > 475) AND (KEY <= 549)) THEN FREQOUT 0,120,852,1209 'DTMF7 IF ((KEY > 401) AND (KEY <= 475)) THEN FREQOUT 0,120,852,1336 'DTMF8 IF ((KEY > 329) AND (KEY <= 401)) THEN FREQOUT 0,120,852,1477 'DTMF9 IF ((KEY > 256) AND (KEY <= 329)) THEN FREQOUT 0,120,941,1209 'DTMF* IF ((KEY > 182) AND (KEY <= 256)) THEN FREQOUT 0,120,941,1336 'DTMF0 IF ((KEY > 110) AND (KEY <= 182)) THEN FREQOUT 0,120,941,1477 'DTMF# ' The following code waits until the key is released (if pressed) to insure ' one tone burst per keypress. Delay seems needed for reliable ADC settling, ' since loop is so small. A counter tracks the number of 10 ms iterations ' through the loop to time the keydown period to trigger a mode change. again2: 'Get keypad value again after tone ADCIN 2, KEY 'Increment keydown count KEYDOWN = KEYDOWN + 1 'Toggle mode after 2 seconds of 2600 key keydown if ((KEYDOWN > 200)and(KEY > 37)AND(KEY <= 110))then gosub modechg 'Allow ADC to settle between reads Pause 10 'Wait for key release IF (KEY > 37) THEN again2 RETURN modechg: if (mode = mf) then mode = DTMF 'Toggle mode to DTMF keydown = 0 'Play high to low beep to confirm mode change to MF freqout 0,75,1700 'Play high beep freqout 0,75,1300 'Play low beep return else if (mode = dtmf) then mode = mf 'Toggle mode to MF keydown = 0 'Play low to high beep to confirm mode change to MF Freqout 0,75,1300 'Play low beep freqout 0,75,1700 'Play high beep return endif endif return