Capacitive Touch Button by using ADC channel (the CVD system)


Closed Thread
Results 1 to 40 of 43

Hybrid View

  1. #1
    Join Date
    Aug 2004
    Posts
    34


    Did you find this post helpful? Yes | No

    Default Re: Capacitive Touch Button by using ADC channel (the CVD system)

    Thank you for the reply. I will do them.

    Ero

  2. #2
    Join Date
    Jun 2008
    Location
    Milwaukee, WI
    Posts
    37


    Did you find this post helpful? Yes | No

    Default Re: Capacitive Touch Button by using ADC channel (the CVD system)

    ero, Martin, or anybody

    I've been trying to do this with a PIC16F819, with only mediocre results. My 819 has a 10 bit A2D, while I see that you are trying it with a 8 bit A2D, so theoretically, your results should be even worse than mine, if that's possible. so, I'm interested in what your typical RAW value is, what it drops to with a finger press, and if it stays relatively constant while your finger is near, because mine does not.

    I started out not tying any of the A2D inputs directly to VCC, and my program began with the A2D pins TRIS being outputs. It worked, sort of, but the A2D value was not constant while my finger was near the pad. Then, I read Martin's suggestion, tied my 'dummy' A2D channel to VCC, modified the code, and ... same thing.

    I've got my PIC16F819 on a olimex 18 pin dev board. I have two copper tape pads, about 1 inch square, covered with electrical tape, on pins 2 and 18.

    my debug statement spits out usually 30 for my untouched S2_AVE (which is not really an average) and when i put my finger on the sensor, it jumps (rings) between 1 and 37. :-(

    I tried putting 10uS delays all over my sense subroutine, tried a longer or no pause before running the A2D, and I tried messing with the A2D clock source, which now doesn't match the define statement.

    oh yeah, I tried to manually control the A2D, but that didn't work. I think I'm pointing to the wrong bits

    If anybody is still with me, here is my down-n-dirty, non-averaging, non-optimized, soon to be pitched, code.
    I'd love to hear any suggestions.

    Code:
    							'    PIC BASIC PRO 2.6 & MPLAB v8.40 PIC16F819 
    '    ================
    
    
    @ __CONFIG  _HS_OSC & _MCLR_OFF  &  _LVP_OFF & _WDT_OFF & _PWRTE_OFF  & _BODEN_OFF
    
    DEFINE DEBUG_REG PORTB        ' asyncronous RS-232 output on PORTB...
    DEFINE DEBUG_BIT 7        ' bit 7
    DEFINE DEBUG_BAUD 19200        ' 19200 Baud, 
    DEFINE DEBUG_MODE 0        ' 1 = inverted,  0 = true,like for using max232, or pickit2
    DEFINE DEBUG_PACING 1000    ' 1mS delay 
    
    DEFINE  ADC_BITS        10    ' Set number of bits in result
    DEFINE  ADC_CLOCK       3    ' Set clock source (3=rc)
    DEFINE  ADC_SAMPLEUS    50    ' Set sampling time in uS
    
    DEFINE OSC 20    
    
    PORTA = 0
    PORTB = 0
    
    TRISA = %00000100        ' dummy channel = PortA.2 = tied to VCC
    TRISB = %00000100           ' pushbutton input   
    
    
    PUSHB          var PORTB.2        ' Pushbutton    (OLIMEX 18 pin PIC dev board - active low)
    REDLED        var PORTB.3        ' Indicator LED (OLIMEX 18 pin PIC dev board)
    YELLOWLED     var PORTB.5    
    GREENLED     var PORTB.6
    
    
    S1_AVE        var word 
    S2_AVE        var word 
    S1value        var word 
    S2value        var word 
    counter        var word 
    
    ADGO    VAR ADCON0.0
    ADDONE    VAR ADCON0.2
    
    DEBUG REP $00\8,13,10,"Starting Up"
    
    
    ADCON0 = %10010000            '10 = A2D freq FOSC/64
                        '010 = point to the dummy channel, AN2
                        '0 = status bit
                        '0 = unused
                        '0 = "ADON", 1 = on
                    
    
    ADCON1 = %11000000              '1 = right justified
                        '1 = A/D clock divide by 2 is used
                        '00 = unused
                        '0000 = all analog inputs
    
    
    PAUSE 1000
    
    
    counter = 0
    
    GOSUB SENSE1
    GOSUB SENSE1
    GOSUB SENSE1
    S1_AVE = S1value
    
    GOSUB SENSE2
    GOSUB SENSE2
    GOSUB SENSE2
    S2_AVE = S2value
    
    
    
    mainloop:
    
    GOSUB SENSE1
    
    IF S1value < (S1_AVE-3) THEN
        GREENLED =1 
    ELSE 
        GREENLED =0
    ENDIF
    
    
    GOSUB SENSE2
    
    IF S2value < (S2_AVE-3) THEN
        YELLOWLED =1 
    ELSE 
        YELLOWLED =0
    ENDIF
    
    
    IF PUSHB = 0 THEN
        DEBUG DEC S1_AVE, ", ",DEC S1value,", ", DEC S2_AVE, ", ",DEC S2value,13,10
    ENDIF
    
    
    counter = counter +1
    
    IF counter > 3000 THEN
        TOGGLE REDLED
        counter = 0
    ENDIF
    
    
    GOTO mainloop
    
    
    ' *   Microchip AN1298: CVD Touch Sensing using two ADC channels
    ' *
    ' *  1. Set 2nd channel to output, set high (VDD)
    ' *  2. Select 2nd channel on ADC (charges CHOLD to VDD).
    ' *  3. Set sensor line to output, set low (GND)
    ' *  4. Select sensor line as input (TRISx = 1)
    ' *  5. Select sensor channel on ADC (V-div sensor:CHOLD)
    ' *  6. Begin ADC conversion
    ' *  7. Reading is in ADRESH:ADRESL
    
    
    
    SENSE1:
    'setup and read the first sensor (PORTA1, AN1, pin 18)
    
    'TRISA.2 = 0           'Set Dummy channel to digital output
    'PORTA.2 = 1         ' Dummy channel goes high
    ADCON0 = %10010000    ' set A/D to dummy channel  
    PAUSEUS 10        ' let it charge
    PORTA.1 = 0         'Sensor line gets set low
    TRISA.1 = 0        'Sensor line gets set to digital output
    TRISA.1 = 1        'Sensor line gets set to digital/analog input
    ADCON0 = %10001000     'Point A/D to sensor line
    PAUSEUS 10        'wait for voltage to stabilize
    ADCIN 1, S1value    ' Read channel 1 to variable 
    
    'ADGO = 1        'turn on A/D
    'WHILE ADDONE = 1
    'WEND
    'S1value = ADRESL
    
    TRISA.1 = 0           'return sense line to be digital output
    RETURN
    
    
    SENSE2:
    'setup and read the 2nd sensor (PORTA3, AN3, pin 2)
    
    'TRISA.2 = 0           'Set Dummy channel to digital output
    'PORTA.2 = 1         ' Dummy channel goes high
    ADCON0 = %10010000    ' set A/D to dummy channel  
    PAUSEUS 10        ' let it charge
    PORTA.3 = 0         'Sensor line gets set low
    TRISA.3 = 0        'Sensor line gets set to digital output
    TRISA.3 = 1        'Sensor line gets set to digital/analog input
    ADCON0 = %10011000     'Point A/D to sensor line
    PAUSEUS 10        'wait for voltage to stabilize
    ADCIN 3, S2value    ' Read channel 3 to variable 
    
    'ADGO = 1        'turn on A/D
    'WHILE ADDONE = 1
    'WEND
    'S2value = ADRESL
    
    TRISA.3 = 0           'return sense line to be digital output
    RETURN
    
    
    END

  3. #3
    Join Date
    Aug 2004
    Posts
    34


    Did you find this post helpful? Yes | No

    Default Re: Capacitive Touch Button by using ADC channel (the CVD system)

    Max Power,

    I need to make a correction. 12F675 having 10 bit ADC channels but I was using them as 8 bit. Because in that job I do not need 10 bit conversation.

    I made a system which is working without any problem. But it was not so easy to do that. Because as I told on my first message the system does not work with stability. Let say if you touch the touch point it is not coming the same result all the time. There is like a loop and after that loop you obtain again the same result.
    For instance the ADC value is depend on what you use as touch point (cable , cupper plate etc) The capacity of that equipments are changing the ADC value.
    I was using one short (about 25 cm) thick cable (single line inside). With that cable I was getting $85 value without touching to the cable. If I touch the ADC value was going down as zero ("0") This was the trick for me to catch the touch moment. BUt as I told you it was not stabil. Finally I decided to use also one loop to eliminate the false signals. Finally my siystem is working very well without any problem. I made both TOGGLE system and also NON-TOGGLE system.
    Here is the codes for Toggle system;
    * : TOGGLE *
    '************************************************* ***************
    @ DEVICE pic12F675
    @ DEVICE pic12F675, WDT_ON
    @ DEVICE pic12F675, PWRT_ON
    @ DEVICE pic12F675, PROTECT_OFF
    @ DEVICE pic12F675, MCLR_off
    @ DEVICE pic12F675, INTRC_OSC_NOCLKOUT

    DEFINE OSCCAL_1K 1

    DEFINE OSC 4

    DEFINE ADC_BITS 8
    'DEFINE ADC_CLOCK 1
    DEFINE ADC_SAMPLEUS 10
    CMCON = 7
    RAW VAR byte 56
    TOP VAR WORD
    SINIR VAR BYTE
    I VAR BYTE
    BUYUK var byte
    KUCUK VAR BYTE
    poz var bit
    OPTION_REG=%01001111
    GPIO=0
    TRISIO=0
    ANSEL = %01011111
    ADCON0=%00001001
    WPU=0
    GPIO.2=1
    SINIR=132 'This is the sensibility value can reach up to 136 according to my touching cable and it can be changed for the different material.
    BUYUK=0
    KUCUK=255

    START:
    GOSUB TUSBAK
    '------------------------do not use these lines I was used them to see the ADC values-------------------------------
    IF RAW>BUYUK THEN BUYUK=RAW
    IF RAW>0 and RAW<KUCUK THEN KUCUK=RAW
    WRITE $10,BUYUK
    WRITE $11,KUCUK
    '-------------------------------------------------------------------------------------------------------------------
    IF RAW<SINIR and POZ=0 THEN 'this is the lines to eliminate the false loop
    TOGGLE GPIO.5
    I=0oz=1
    BIR: gosub tusbak
    IF RAW<SINIR then
    I=0
    GOTO BIR
    ELSE
    I=I+1
    IF I<SINIR then BIR
    ENDIF
    pause 50
    I=0
    goto start
    endif

    pause 10
    poz=0
    GOTO START
    TUSBAK: 'means check if there is a touch
    GPIO.2=0
    ANSEL.2=0
    HIGH GPIO.2
    ADCON0=%00001001 ' The direction of ADC channel is now GPIO.2 and C_hold is charging by the signal coming from AN2.
    ANSEL.0=0 'sensor pin is digital
    TRISIO.0=0 'sensor pin is now output pin
    GPIO.0=0 'sensor pin is LOW and it was discharged
    TRISIO.0=1 'Sensor pin is again input
    ANSEL.0=1 'sensor pin is analog input now
    ADCIN 0,RAW
    BAK:
    TRISIO.0=0
    ANSEL.0=0
    GPIO.0=0
    RETURN
    I hope everything is clear now.

    Ero

  4. #4
    Join Date
    Dec 2010
    Posts
    409


    Did you find this post helpful? Yes | No

    Default Re: Capacitive Touch Button by using ADC channel (the CVD system)

    I've made a touch controlled dimmer with touch up/touch down controls using this method. There is a lot of variability in the measurement, but empirically I determined a range of values that the result always falls within when touched. I then implemented a "tell me three times" loop to eliminate noise. I'm happy with the result and there are several complete units in use with no complaints.

    I can't post the code because I sold the rights to it, but the only tricks to making it work are in the paragraph before this one.

  5. #5
    Join Date
    Oct 2004
    Posts
    448


    Did you find this post helpful? Yes | No

    Default Re: Capacitive Touch Button by using ADC channel (the CVD system)

    Mister_e had an elegant piece of code that worked flawlessly;

    http://www.picbasic.co.uk/forum/show...?t=2671&page=1

    Hope it works for you.

    Regards,

    Anand

  6. #6
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default Re: Capacitive Touch Button by using ADC channel (the CVD system)

    I remember struggling with a16f690 for a good while wrt cap touch (albeit a different method to the one being discussed here )...I then bought a £1.00 12f1822 & was up and running with cap touch within about 20 minutes!

    moral of the story (for me at least) - get the right pic for the task at hand!

  7. #7
    Join Date
    Jun 2008
    Location
    Milwaukee, WI
    Posts
    37


    Did you find this post helpful? Yes | No

    Default Re: Capacitive Touch Button by using ADC channel (the CVD system)

    Thanks everybody. I love this forum.
    Looks like I will get a 12F1822 for my low pin count micro, and a 16F1823 for my higher pin count micro. I was kind of put off by the lack of examples here.

    Hank, I'm so glad you chimed in. I've been reading your posts about your relaxation osc. and the 16F690 with great interest, and I watched your youtube video. the 690 seemed like an easy way to get multiple channels. I've done a few single channel, relaxation osc, cap sensors using a comparator and a timer in the 16F628A, but I was always limited to 1 channel. Then, I got the 16 channel mux and SOIC breakout board from sparkfun and I made a 16 key piano - thats probably my most fun project yet. I really should post the code, it could be so much better.

    You were up and running in 20 min?!? jeez, what am I waiting for! did you use PBP? 2.6 or 3? or... (shudder) C code? :-) what did you program it with? pickit2 pickit3? I might pick your brain a little more later.

    Thanks again.

Members who have read this thread : 1

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts