16F726 Capacitive sensing module


Closed Thread
Results 1 to 40 of 40
  1. #1
    Join Date
    Jan 2009
    Location
    California, USA
    Posts
    323

    Default 16F726 Capacitive sensing module

    Well here I am... stuck again.

    I'm trying to learn how to use the capacitive sensing module on the 16F726.

    My first problem seems to be getting the sensing oscillator running.

    I've been through the CSM section (14.0) of the data sheet and I've read AN1171 (Using the Capacitive Sensing Module on the PIC16F72X)

    According to AN1171, once I've set the appropriate registers the oscillator should start up. At this point I would expect to see the oscillator running on my chosen sensor pin... right?

    I've got my 'scope on pin 21 (RB0/AN12/CPS0/INT) of the PIC but I don't see anything except a few millivolts of 60 cycle hum. It just looks like a high impedance input with no oscillator running.

    Shouldn't this be all it takes to get the CSM oscillator running on CPS0 (pin21) ?

    Code:
     '****************************************************************
    
    Include "MODEDEFS.BAS"   ' Include Shiftin/out modes
    
    @  __config _CONFIG1, _DEBUG_OFF & _PLL_EN & _BORV_2_5 & _BOR_ON & _CP_OFF & _MCLRE_OFF & _PWRT_EN & _WDT_OFF & _INTOSCIO
    @  __config _CONFIG2, _VCAP_RA0
    
    OSCCON = $10         'set oscillator to 4 Mhz
    
    TRISA= %11111111     'Set 'em all to inputs
    ANSELA= %11111111	 ' Set all pins to analog...
    
    TRISB= %11111111   	 'all input
    ANSELB= %11111111    'all analog
    
    TRISC= %00000000     'Set portC all outputs   
    
    CPSCON0 = %10001101  'Cap sense on, high range oscillator
    CPSCON1 = %00000001  'Cap sense channel input 0 is selected
    Could someone please point me in the right direction?

    Thanks!

    Steve

  2. #2
    Join Date
    Jan 2009
    Location
    California, USA
    Posts
    323


    Did you find this post helpful? Yes | No

    Default Well, I'm still trying with this CSM...

    I'm trying to learn to use the Capacitive Sensing Module (CSM) on the PIC16F727. I've had some minor success getting the CSM set up and running, and with reading the count from TMR1 to an LCD module.

    I'm using (trying) Darrel's Instant Interrupts to run an ISR when TMR2 matches PR2, but I clearly don't understand what I'm doing yet...

    Here's the part that works so far:
    I've got the CSM oscillator running and I can see the triangle wave on pin B0. I've got a wire and "touchpad" connected to it, and when I touch the pad the oscillator slows way down, so that part is working great.


    Here's what I'm *trying* to do at this point :

    Timer1 is used to count pulses on the cap sensing oscillator. It is set up so that Timer2 controls the gate of Timer1 and starts/stops the Timer1 counter.

    Timer2 counts until it matches the value in the PR2 register, then stops Timer1 and triggers an interrupt.

    The ISR reads the count in the Timer1 register and stores it in a variable called "timercount", then it resets the registers to 0, resets Timer2 to 0, clears the Timer2 interrupt flag, and restarts the timers.

    The main loop is supposed to read the contents of "timercount" and display it on an LCD so I can read the change in timercount when a finger touches the sensing pad.


    Here's the problems I'm having (so far):

    First, the Interrupt seems to "steal the show" and the program never enters the main loop and displays the data on LCD, UNLESS I put a "goto Main" inside the ISR routine. Then it will display my value on the LCD.

    Second, the count in TMR1 seems to be entirely dependent on the length of the "pause" in the main loop. With 100mS pause the timer reads about 15,000 counts, with a 200mS pause it reads about 29,000 counts. What's up with that? The ISR zeros the timers each time through.

    I've read sections 11-14 (using the timers and CSM) of the 16F727 datasheet (41341B.pdf) *repeatedly*, as well as AN1103 and AN1171 which explain using the CSM in the 16F727. Hey, I even managed to make Darrels "Blinky light" interrupt example work for me, but alas, I seem unable to pull it all together and make the touch sensor routine work. I figured I'd start by reading the count in TMR1 to an LCD so I can see what's happening..

    I've been hammering away at this for quite a while and starting to feel rather lost.

    Here's the code I've got so far if someone would *please* be so kind as to take a look and offer advice..

    Code:
    '-------------------------------------------------------------------------------
    'Trying to learn to use the Capacitive Sensing Module on a 16F727 --------------
    '-------------------------------------------------------------------------------
    
    @  __config _CONFIG1, _DEBUG_OFF & _PLL_EN & _BORV_2_5 & _BOR_ON & _CP_OFF & _MCLRE_OFF & _PWRT_EN & _WDT_OFF & _INTOSCIO
    @  __config _CONFIG2, _VCAP_RA0
    
    Include "MODEDEFS.BAS"    ' Include Shiftin/out modes
    INCLUDE "DT_INTS-14.bas"  ' Base Interrupt System
    INCLUDE "ReEnterPBP.bas"  ' Include if using PBP interrupts
    
    DEFINE LCD_DREG PORTA    ' Set LCD Data port
    DEFINE LCD_DBIT 4        ' Set starting Data bit (0 or 4) if 4-bit bus
    DEFINE LCD_RSREG PORTA   ' Set LCD Register Select port
    DEFINE LCD_RSBIT 2       ' Set LCD Register Select bit
    DEFINE LCD_EREG PORTC    ' Set LCD Enable port                                                   
    DEFINE LCD_EBIT 0        ' Set LCD Enable bit
    DEFINE LCD_BITS 4        ' Set LCD bus size (4 or 8 bits)
    DEFINE ADC_BITS 8        ' Set number of bits in ADC result
    DEFINE ADC_CLOCK 3       ' Set clock source for ADC (rc = 3)
    DEFINE ADC_SAMPLEUS 100  ' Set ADC sampling time in microseconds 
    DEFINE OSC 4
    
    OSCCON = $10         'set oscillator to 4 Mhz
    
    TRISA= %00000000     'Set 'em all to outputs
    ANSELA= %00000000	 'Set 'em all to digital
    TRISB= %11111111   	 'all input
    ANSELB= %11111111    'all analog
    TRISC= %00000000     'Set portC all outputs   
    
    CPSCON0 = %10001101  'Cap sense on, high range oscillator
    CPSCON1 = %00000000  'Cap sense channel input 0 is selected
    
    '-----Alias Pins
    RW           var    PORTC.3   'Read/Write line for the LCD
    
    '-----Allocate Variables
    timercount   var    word   ' A place to store the count from TMR1
    
    '-----Set up Interrrupts
    ASM
    INT_LIST  macro    ; IntSource,        Label,  Type, ResetFlag?
            INT_Handler   TMR2_INT,  _CheckCount,   PBP,  yes
         endm    
        INT_CREATE               ; Creates the interrupt processor
    ENDASM
    
    @ INT_ENABLE  TMR2_INT     ; enable Timer 2 interrupts
    
    
    
    low rw          'LCD Read/Write line low (write)
    Pause 200       'Let the LCd wake up
    lcdout $fe, 1   'Clear LCD
    
    '----- Timer Setup
    T2CON.2 = 1     'TMR2 on
    T2CON.0 =1      'adjust prescaler
    PR2 = $B4       ' w/prescale=1:1, $B4 sets 125us scan rate.  '= 10110100
    PIR1.1 = 0      'Clear the TMR2 interupt flag
    PIE1.1 = 1      'Turn TMR2 interrupt enable on
    T1CON = %11010101 'clock=CAPOSC, prescale=1:2, dedicated OSC disabled, no external clock synchronize, timer on
    T1GCON = %11100010 'Timer1 gate init/ Toggle Mode
    PIR1.7 = 0   'Clear Gate Interrupt Flag
    PIR1.1 = 0   'clear the TMR2 interupt flag
    PIE1.7 = 1 'Enable Gate Interrupt
    
    Goto main   'Just get it going...
    
    '---[TMR2 - interrupt handler]--------------------------------------------------
        disable   'I think I need to kill the interupts here..?
    CheckCount:
        T2CON.2 = 0   'stop timer2
        T1CON.0 = 0   'stop timer1
        timercount = TMR1L + TMR1H << 8   'stuff the contents of the timer register into a word
        TMR1L = 0     'reset counter to 0...
        TMR1H = 0     'upper 1/2 too
        TMR2 = 0       'rest timer 2
        PIR1.1 = 0   'Clear TMR2 Interrupt Flag
        T1CON.0 = 1  'restart timer1
        T2CON.2 = 1  'restart timer2
      '  gosub main    'if I don't add this, I never seem to get out of the interrupt and return to the main routine...
    @ INT_RETURN
        enable     're-enable interrupts
        
    '----Main loop-----------------------------------------------------------
    Main:
        LCDOUT $fe,2, " Count= ", dec timercount,"    ",$fe,$C0,"  TMR2 = ", dec timertemp,"    "
        pause 100   'changing the duration of the pause also changes the count on timer1.  Why?
        return    
      
    GOTO Main
    
        end

    Thanks very much,

    Steve

  3. #3
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    I've never used the touch sensor thingy's, but here's a couple items that will be causing problems.
    • You've enabled TMR1GIE (PIE1.7), but there isn't a handler for it.
      Don't think you really need it anyway if TMR2 is handling the gate, and creating an interrupt at the same time.
      &nbsp;
    • There is a return in your Main loop. Very Bad!
      &nbsp;
    DT

  4. #4
    Join Date
    Jan 2009
    Location
    California, USA
    Posts
    323


    Did you find this post helpful? Yes | No

    Default

    Ahhh, thanks Darrel... where would this forum be without you! No problem too large or small.

    I don't know what happened with the return inside my main loop... Bad late night cut & paste I guess. Thanks for pointing that out!

    About TMR1GIE (PIE1.7)...
    I've gone back and re-re-re-read section 12.6 (and figure 12-6) about the timer1 gate and "toggle mode" again, and also the "Timer 2 Time Base Setup" section of AN1171, and a few things are starting to make more sense... and it appears that the interrupt I want to watch is NOT the TMR2 to PR2 match, it's the Timer 1 Gate Event Interrupt , "TMR1GIF"(PIR1.7) . That explains some of the other weird results I've had.

    I don't see the "Timer 1 Gate Event Interrupt" listed in the Available Interrupt Sources on your website Darrel. Is there a way for me to add that to the selection so i can use TMR1GIF with "Instant Interrupts"?

    Thanks very much for your help! Hopefully I'll be able to get the Touch Sensor thing figured out and be one of the first to post a chunk of working code for it.


    Steve

  5. #5
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by Byte_Butcher
    I don't see the "Timer 1 Gate Event Interrupt" listed in the Available Interrupt Sources on your website Darrel.
    Yeah, it's not in there.

    But it's not too hard to add it to the DT_INTS-14.bas file....
    Code:
    ASM
      #define TMR1GATE_INT   PIR1,TMR1GIF     ;-- Timer1 Gate Interrupt
      #define INT_INT   INTCON,INTF     ;-- INT External Interrupt
      #define RBC_INT   INTCON,RBIF     ;-- RB Port Change Interrupt
      #define TMR0_INT  INTCON,T0IF     ;-- TMR0 Overflow Interrupt 16F
      #define TMR1_INT  PIR1,TMR1IF     ;-- TMR1 Overflow Interrupt
    ...
    and
    Code:
    GetIntInfo  macro  IflagReg, IflagBit
    
    Found = NO
    ; nolist
      ifdef TMR1GIF    ;----{ TMR1 Gate Interrupt }---------------[PIR1, TMR1GIF]---
          INT_Source  PIR1, TMR1GIF, PIE1, TMR1GIE
      endif
      ifdef INTF    ;----{ INT External Interrupt }----------------[INTCON, INTF]---
          INT_Source  INTCON, INTF, INTCON, INTE
      endif
      ifdef RBIF    ;----{ RB Port Change Interrupt }--------------[INTCON, RBIF]---
    ...
    <hr>
    Then in your program's interrupt definition ...
    Code:
    '-----Set up Interrrupts
    ASM
    INT_LIST  macro    ; IntSource,        Label,  Type, ResetFlag?
            INT_Handler   TMR1GATE_INT,  _CheckCount,   PBP,  yes
        endm    
        INT_CREATE               ; Creates the interrupt processor
    ENDASM
    
    @ INT_ENABLE  TMR1GATE_INT     ; enable Timer1 Gate interrupts
    Good Luck!
    DT

  6. #6
    Join Date
    Aug 2005
    Location
    Houston, TX
    Posts
    43


    Did you find this post helpful? Yes | No

    Default Capacitor checker

    I made a capacitor checker using a 16F84A which works very well within limits. It uses the pot command. The code in PICBasic (not Pro) is:

    ' Capacitor Measurement
    ' Four digit common anode mulitplexed display
    ' Scan about 60/s (4ms pause)
    ' Driver 74HC4511
    ' Works for 2.0 uf (1K)- 100pf (20K)
    ' 8/20/06
    ' For 16F84A Chip
    ' Data output port A (Pin A5 NC)
    ' Pins 1 - 4 - Digit select for multiplex
    ' Pin5 - pot command
    ' Pin6 - Display Blanking signal (0 = blank)
    ' Pin7 - Range 1 = high value (1K resistor); 0 = low (20K)
    ' Digits 1 - 4; W1 - W4
    ' Measurement (Msr) W10
    ' Note that scan must be 60/s, and 1ms on + 3ms off shows no flicker, but
    ' leds are dim. 2ms on & 2ms off works well.
    Settings:
    Symbol Blank = pin6
    Symbol Range = pin7
    Symbol D1 = w1
    Symbol D2 = w2
    Symbol D3 = w3
    Symbol D4 = w4
    Symbol Msr = w10
    Symbol PortA = 5
    Poke $85, 0 ' Set port A to all outputs
    Output 1 ' Digit 1 - MSD
    Low 1 ' off
    Output 2 ' Digit 2
    Low 2
    Output 3 ' Digit 3
    Low 3
    Output 4 ' Digit 4
    Low 4
    Output 6 ' Blanking
    Low 6 ' Blank all segments


    Start:
    pause 750
    Blank = 0
    If range = 0 then testlow 'Check high or low state

    'Testhigh:
    pot 5,40,msr
    Msr = Msr*10 'Raise results for 4 digit display
    goto math

    Testlow:
    Pot 5,255, msr
    Msr = Msr*100

    Math: 'Set up digits in memory for display
    D1 = Msr/1000
    D4 = Msr//1000
    D2 = D4/100
    D4 = D4//100
    D3 = D4/10
    D4 = D4//10

    Display:
    poke porta, D1 'Send data
    High 1 'Select Digit
    Blank = 1 'Remove blanking
    Pause 2 'Pause
    Blank = 0 'Blank
    Low 1 'Unselect digit
    'Pause 2 'Pause again to save battery

    poke porta, D2
    High 2
    Blank = 1
    Pause 2
    Blank = 0
    Low 2
    'Pause 2

    poke porta, D3
    High 3
    Blank = 1
    Pause 2
    Blank = 0
    Low 3
    'Pause 2

    poke porta, D4
    High 4
    Blank = 1
    Pause 2
    Blank = 0
    Low 4
    Pause 2
    Goto display
    end

  7. #7
    Join Date
    Jan 2009
    Location
    California, USA
    Posts
    323


    Did you find this post helpful? Yes | No

    Default Thanks Darrel!, CSM is working!

    Bingo!
    I changed my interrupt from TMR2/PR2 match to TMR1 gate event and it's working beautifully now. The count on the LCD now accurately reflects what's going on with the CSM oscillator.

    Thanks so much for posting the necessary modifications to DT_INTS-14.bas.
    I actually opened that file and had a look just before bed last night and had pretty much figured out to do the modifications you posted. Thanks for confirming it for me.

    It looks like I need to adjust the TMR2 prescaler a bit to maximize the number of counts in the period, but it's working great now and the next thing to do is set up the averaging and "button pressed" detection routine but I think that should be pretty easy, even for me.

    I'll post code when I've got it working well. I'm rather surprised no one here has played with the Touch Sensor module on the 16F726/7 yet....
    I spent hours searching the archives and came up with a big zero.

    Thanks again Darrel!
    Last edited by Byte_Butcher; - 12th March 2009 at 16:19.

  8. #8
    Join Date
    Jan 2009
    Location
    California, USA
    Posts
    323


    Did you find this post helpful? Yes | No

    Default

    Thanks AMay,
    The capacitance checker may come in handy for me some time.

    But what I'm working on isn't a capacitance meter, it's the Capacitive Sensing Module in the PIC 16F726/7's.

    It's used to make capacitive "Touch Sensors" that detect a human finger without any buttons, just a simple conductive pad.

    I think Darrel has got me up and running now.

  9. #9
    Join Date
    Jan 2009
    Location
    California, USA
    Posts
    323


    Did you find this post helpful? Yes | No

    Default

    OK, I was gonna sit on this for a few more days until I had a chance to perfect it a little more, but here it is now in it's crude form. I'm sure it needs lots of fixing to be "good" code, but it's functional as is and hopefully will give a starting place for folks who want to play with the capacitive sensing module on the 16F72X PIC's. Please feel free to critique it and fix it up. I need the education...

    This program sets up Capacitive Sensing pin0 (CPS0/RB0) on the 16F726 / 16F727 to be a "Touch Sensor" pin
    When the sensor pad is touched, the raw count (from TMR1) will drop below the running average and a LED on PORTA.1 will flash. If the finger is held on the pad long enough, eventually the running average will catch up with the current value and the LED will turn off.

    Relevant Data Sheets for the CSM module include:

    http://ww1.microchip.com/downloads/e...Doc/41341B.pdf 16F72X / 16LF72X Data Sheet.
    http://ww1.microchip.com/downloads/e...tes/01101a.pdf AN1101 "Introduction to Capacitive Sensing "
    http://ww1.microchip.com/downloads/e...tes/01103a.pdf AN1103 'Software Handling for Capacitive Sensing"
    http://ww1.microchip.com/downloads/e...tes/01171B.pdf AN1171 "Using the Capacitive Sensing Module on the PIC16F72X"

    Crude Code follows.... Enjoy!

    Steve

    ------------
    Code:
    '-------------------------------------------------------------------------------
    'Trying to learn to use the Capacitive Sensing Module on a 16F727 --------------
    '-------------------------------------------------------------------------------
    
    @  __config _CONFIG1, _DEBUG_OFF & _PLL_EN & _BORV_2_5 & _BOR_ON & _CP_OFF & _MCLRE_OFF & _PWRT_EN & _WDT_OFF & _INTOSCIO
    @  __config _CONFIG2, _VCAP_RA0
    
    Include "MODEDEFS.BAS"    ' Include Shiftin/out modes
    INCLUDE "DT_INTS-14.bas"  ' Base Interrupt System
    INCLUDE "ReEnterPBP.bas"  ' Include if using PBP interrupts
    
    DEFINE LCD_DREG PORTA    ' Set LCD Data port
    DEFINE LCD_DBIT 4        ' Set starting Data bit (0 or 4) if 4-bit bus
    DEFINE LCD_RSREG PORTA   ' Set LCD Register Select port
    DEFINE LCD_RSBIT 2       ' Set LCD Register Select bit
    DEFINE LCD_EREG PORTC    ' Set LCD Enable port                                                   
    DEFINE LCD_EBIT 0        ' Set LCD Enable bit
    DEFINE LCD_BITS 4        ' Set LCD bus size (4 or 8 bits)
    DEFINE ADC_BITS 8        ' Set number of bits in ADC result
    DEFINE ADC_CLOCK 3       ' Set clock source for ADC (rc = 3)
    DEFINE ADC_SAMPLEUS 100  ' Set ADC sampling time in microseconds 
    DEFINE OSC 8
    
    OSCCON = $10         'set oscillator to 8 Mhz
    
    TRISA= %00000000     'Set 'em all to outputs
    ANSELA= %00000000	 'Set 'em all to digital
    TRISB= %11111111   	 'all input
    ANSELB= %11111111    'all analog
    TRISC= %00000000     'Set portC all outputs   
    
    CPSCON0 = %10001101  'Cap sense on, high range oscillator
    CPSCON1 = %00000000  'Cap sense channel input 0 is selected
    
    '-----Alias Pins
    RW           var    PORTC.3 : LOW rw   'Read/Write for LCD
    LED          var    PORTA.1      'LED to display when button is pressed
    
    '-----Allocate Variables
    timercount   var    word  ' raw count from TMR1
    timerave     var    word  ' long term average of timercount
    AvgCount     var    word : AvgCount = 32 'number of samples to average 
    
    '-----Set up Interrrupts
    ASM
    INT_LIST  macro    ; IntSource,        Label,  Type, ResetFlag?
            INT_Handler   TMR1GATE_INT,  _CheckCount,   PBP,  yes
         endm    
        INT_CREATE               ; Creates the interrupt processor
    ENDASM
    
    @ INT_ENABLE  TMR1GATE_INT     ; enable Timer 2 interrupts
    
    High LED
    Pause 200       'Let the LCd wake up
    lcdout $fe, 1   'Clear LCD
    lcdout $fe, 2, " Awake! "
    pause 500
    
    '----- Timer Setup
    T2CON = %01110110 'bit7=unimplemented, bit6-3=postscaler, bit2=TMRON, bit1-0=prescaler 
    PR2 = %11111111       'give PR2 a number for TMR2 to match
    PIR1.1 = 0      'Clear the TMR2 interupt flag
    PIE1.1 = 1      'Turn TMR2 interrupt enable on
    T1CON = %11000101 'Timer clock source=CAPOSC, prescale=1:1, dedicated OSC disabled, no external clock synchronize, timer on
    T1GCON = %11100010 'Timer1 gate init/ Toggle Mode
    PIR1.7 = 0   'Clear Gate Interrupt Flag
    PIR1.1 = 0   'clear the TMR2 interupt flag
    
    Goto main   'Just get it going...
    
    '---[TMR2 - interrupt handler]--------------------------------------------------
        disable   
    CheckCount:
        T2CON.2 = 0   'stop timer2
        T1CON.0 = 0   'stop timer1
        timercount = TMR1L + TMR1H << 8   'stuff the contents of the timer register into a word
        Gosub Fingercheck
        
        TMR1L = 0     'reset counter to 0...
        TMR1H = 0     'upper 1/2 too
        TMR2 = 0       'rest timer 2
        PIR1.1 = 0   'Clear TMR2 Interrupt Flag
        T1CON.0 = 1  'restart timer1
        T2CON.2 = 1  'restart timer2
    @ INT_RETURN
        enable 
        
    '----Average the timercount result----------------------------------------------
    
    Fingercheck:
        timerave = timerave - (timerave/AvgCount)    'average the count so you have a reference to compare....
        timerave = timerave + (timercount/AvgCount)  '...with yimercount
            
        If timerave - (timerave /40) > timercount then  'If timercount drops more than 2.5% below the average, signal that a button is pressed.
            low LED      'make the LED do a little dance.
            pause 50
            High LED
            pause 25
        endif
        
        If timercount > timerave +50 then    'do a "fast recovery" on the average when finger is removed.
           timerave = timercount
        endif
        return     
        
    '----Main loop-----------------------------------------------------------
    Main:
        LCDOUT $fe,2, " Count= ", dec timercount,"    ",$fe,$C0,"Average = ", dec timerave,"    "
        pause 50  
    GOTO Main
    
        end

  10. #10
    Join Date
    Jan 2009
    Posts
    22


    Did you find this post helpful? Yes | No

    Default

    Anybody else working with capacitive sensing? Any updates?

  11. #11
    Join Date
    May 2007
    Posts
    604


    Did you find this post helpful? Yes | No

    Default

    I have used capacitive sensing in a handheld terminal with a graphic LCD. It scans 24 keys (although it will handle up to 32 keys) and does require a special MCU - I'm using a PIC18F44K20. Does auto-repeat, audible feedback, etc.
    Name:  A_66A.JPG
Views: 6449
Size:  15.5 KBName:  A_6B.JPG
Views: 6398
Size:  24.0 KB
    Last edited by rmteo; - 4th May 2010 at 21:09.

  12. #12
    Join Date
    Jul 2003
    Posts
    2,405


    Did you find this post helpful? Yes | No

    Default

    Nice looking project rmteo. Do you have a PBP example for it?
    Regards,

    -Bruce
    tech at rentron.com
    http://www.rentron.com

  13. #13
    Join Date
    May 2007
    Posts
    604


    Did you find this post helpful? Yes | No

    Default

    The project was done in SF BASIC for a client so I cannot go into too much detail. As for the capacitive touch part, the keyboard is implemented as PCB copper pads on the top side (see picture). Each of the 24 pads is routed through a pair of 16-to-1 multiplexers (74HCT4067) to act as the timing capacitor to a TS555 (CMOS version of 555) timer running at about 2MHz in astable mode.

    A timer in the PIC is set up as a counter. It counts the number of pulses in a fixed time frame (I use 2 ms). When a pad is touched, its capacitance increases thereby lowering the frequency (lesser pulse count) of the TS555. You will typically see 10-15% change when a key is touched. Because the capacitance can (and will) drift due to temperature (and the fact that each key will have a slightly different capacitance due to trace length, etc.), you will need to employ some algorithms to ensure accurate readings. There is an app note on the MC website that describes this.

    The nice thing about this method is that you can use any PIC - it does not need to have a capacitive sense module to work and uses fewer I/O pins. I implemented a similar scheme using the ARM Cortex M0/M3 but the same principle can be applied to work with just about any microcontroller.

    Name:  A_71E.JPG
Views: 6757
Size:  67.4 KB
    Last edited by rmteo; - 5th May 2010 at 01:35.

  14. #14
    Join Date
    Jul 2003
    Posts
    2,405


    Did you find this post helpful? Yes | No

    Default

    Good looking unit you made there. Nice work. I guess i'm going to have to start playing a bit with cap sensing on the 16F1827 here shortly...
    Regards,

    -Bruce
    tech at rentron.com
    http://www.rentron.com

  15. #15
    Join Date
    Jan 2009
    Location
    Miami, Florida USA
    Posts
    644


    Did you find this post helpful? Yes | No

    Default

    rmteo,

    Nice project. I have a project using CSM (capacitive sensing module) on a 16F727. In that project I'm using only two buttons. Yes, you can do it with any PIC but you will need some extra external components.

    How did you do the external plastic cover for the buttons? Was it custom made by some company?

    Robert

  16. #16
    Join Date
    May 2007
    Posts
    604


    Did you find this post helpful? Yes | No

    Default

    I used a clear acetate (0.012in.thick) overlay for the buttons. This way, the end user can change legends by printing their own labels on paper using an ink-jet printer. This is one of the nice features of a capacitive switch - you don't have to spend a lot of money for custom labels (and the attendant lead times). And you can change labels easily and cheaply at any time. There is a downside though - there is no feedback (like tactile with a mechanical switch). I implemented an audible click using a buzzer like this one, which is also used for alarms, etc.


  17. #17
    Join Date
    Jan 2009
    Location
    Miami, Florida USA
    Posts
    644


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by rmteo View Post
    I used a clear acetate (0.012in.thick) overlay for the buttons. This way, the end user can change legends by printing their own labels on paper using an ink-jet printer.
    Nice! Now, that is one more item for my "To Buy List".

    Robert

  18. #18
    Join Date
    May 2007
    Posts
    604


    Did you find this post helpful? Yes | No

    Default

    I got the material from a local office supply place - OfficeMax. It is the clear stuff used as covers for book bindings.

  19. #19
    Join Date
    Oct 2004
    Posts
    440


    Did you find this post helpful? Yes | No

    Default

    I have been using capacitive touch switches for several years with little problem except the
    Q prox chips became obsoleted after a couple of years.

    Any Microchip can be used as the requirements are unbelievably simple:
    An I/O pin to charge with supply voltage and an AD pin to read the cap sense value.

    I sometimes take 20 to 100 readings, bubble sort them highest to lowest, then average
    only array elements 20% to 80% to to remove any errant readings.
    The outcome is stable, varies only one or two at 8 bit.
    The AD needs to be coded for power conservation however.

    The following code is derived almost directly from AN1286:
    Code:
    'PIC18F2520  
    subLOAD_AD_ARRAY:
        ADCON0 = %00000001  'ENABLES AD
        For i = 0 To 99
            LOW PORTA.0
            LOW PORTA.2 
            ASM 
            NOP 
            ENDASM 
            TRISA.0 = 1 'INPUT
            HIGH PORTA.2
            ASM 
            NOP
            ENDASM 
    
            'AD BY REGISTER'S  
            ADCON0.1 = 1   ' START AD  GO/DONE BIT
            While ADCON0.1 = 1 : Wend  ' AD ENDED GO/DONE Bit
            wAD.LowByte = ADRESL       ' 2520 10 BIT AD ONLY
            wAD.HighByte = ADRESH  
            yAD_ARRAY100[i] = wAD >> 2
        Next
        ADCON0 = %00000000  'DISABLE AD
        Return
    The touch button is simply a 3/16" stainless steel machine screw through the faceplate with
    a double nut tightened around a soldered wire loop connected to the AD.
    I add a little grommet for looks.
    The charge lead is simply wound several times around the screw behind the faceplate.

    Another version is individual metal tabs of sheet metal adhered to the underside of the
    enclosure for buttons.
    The AD wire is soldered to each tab and the charge wire only needs to wrap around the
    AD wire or all AD wires.

    The cap sensor readings can vary over time and the base line to compare the readings against
    should be re zeroed and a new max value redetermined at regular intervals.

    I laminate an inkjet photo quality paper (not photo paper) printout for the faceplate.

    The last consideration is ESD.
    A simple 100k resistor in line on both leads is a good solution.

    Norm
    Last edited by Normnet; - 7th May 2010 at 04:50.

  20. #20
    Join Date
    Nov 2003
    Location
    Greece
    Posts
    3,807


    Did you find this post helpful? Yes | No

    Default

    Hi Norm.

    I think you can shorten your code by Left justify the AD results and take only the ADRESH. Same as with the lines:

    Code:
            wAD.LowByte = ADRESL       ' 2520 10 BIT AD ONLY
            wAD.HighByte = ADRESH  
            yAD_ARRAY100[i] = wAD >> 2
    Ioannis

  21. #21
    Join Date
    Jan 2009
    Location
    Miami, Florida USA
    Posts
    644


    Did you find this post helpful? Yes | No

    Default

    Norm,

    There are many ways to do it. You can also use the interrupt TMR1 to detect changes in the output frequency due to a pad being touched by a finger. This is explained in AN1101 "Introduction to Capacitive Sensing".

    http://ww1.microchip.com/downloads/e...tes/01101a.pdf


    Quote Originally Posted by Normnet View Post
    The following code is derived almost directly from AN1286:
    I see that you are using AN1286 "Water-Resistant Capacitive Sensing". If you are using your touch sensors in a wet environment, then you might want to consider using inductive sensors. Take a look at the table I attached to this post.

    http://www.microchip.com/stellent/id...param=en538303

    Name:  Inductive.JPG
Views: 6295
Size:  38.5 KB

    Robert

  22. #22
    Join Date
    Oct 2005
    Location
    New Zealand
    Posts
    171


    Did you find this post helpful? Yes | No

    Default Errors left right and center

    I'm trying to use capacitive touch too - was kinda hoping that the inbuilt capacitive sensing was a bit more straight forward than the convoluted mess and complexity it looks like. Would it be too hard for microchip to make it a bit user friendly so you just enable named pins as capacitive, then read the register to see which were pressed and had inbuilt filtering etc??

    I've used Mister E's capacitive touch idea before and it seems so much simpler than the "integrated' solution.

    Anyrate - enough of my ramblings, I'd like to learn to use it - hopefully it's not as complex as it appears from outset. I've copied byte butchers code as above and pasted it directly into MCS and I have errors all over the place. I have a fresh install of PBP2.6 and have also just downloaded DTs' ints-14.

    How come it works for him and not for me? I had the chip type 16F726 like his also

    While I'm on a roll, why wont MCS allow you to copy and paste the error list???

    I think many of the issues come from the Interrupt routine but asm and interrupts are well over my head. Is there any reason Byte Butcher used interrupts rather than just checking pins periodically?

    Thanks

    Error[118]c:\pbp...asm 213 : Overwriting previous address contents (2007)
    Error[101]c:\pbp...asm 342 : ERROR: (wsave variable not found)
    Error[101]c:\pbp...asm 308 : ERROR: (" Add:" wsave VAR BYTE $20 SYSTEM)
    Error[101]c:\pbp...asm363 : ERROR: (Chip has RAM in BANK1, but WSAVE was not found)
    Error[101]c:\pbp...asm315 : :ERROR: (" Add:" wsave VAR BYTE $A0 SYSTEM)
    Error[128]c:\pbp...asm 989 : Missing argument(s)
    Error[101]c:\pbp...asm672 : ERROR: ("INT_Handler" - Interrupt Flag (FlagReg,FlagBit) not found)
    Error[128]c:\pbp...asm 1000 : Missing argument(s)
    Error[101]c:\pbp...asm 672 : ERROR: (INT_ENABLE" - Interrupt Flag ( FlagReg,FlagBit) not found)

  23. #23
    Join Date
    Jan 2009
    Location
    Miami, Florida USA
    Posts
    644


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by George View Post
    I think many of the issues come from the Interrupt routine but asm and interrupts are well over my head. Is there any reason Byte Butcher used interrupts rather than just checking pins periodically?
    He used interrupts because that is the way to do it. You need to count the number of pulses in the signal for a fixed amount of time and determine if the switch has been touched or not. This app note might help you to understand the basics of CSM

    http://ww1.microchip.com/downloads/e...tes/01101a.pdf

    Robert
    "No one is completely worthless. They can always serve as a bad example."

    Anonymous

  24. #24
    Join Date
    Nov 2003
    Location
    Greece
    Posts
    3,807


    Did you find this post helpful? Yes | No

    Default

    Don't you have to do better things?

    Seriously now, I mean it, while the timers do their jobs, that is to count, you can do many other tasks in your program.

    That is why the so hated interrupts are needed.

    As for your errors, do post your code. Do you need help or guesses?

    Ioannis

  25. #25
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default

    I experimented with capacitive touch on a 16f690, my related thread about it here (you might glean some stuff from it)...

    http://www.picbasic.co.uk/forum/showthread.php?t=12196

    My (short!) youtube video of the end result here (using a guitar's scratchplate screw's 'head', as a 'toggle switch')...



    Re the process itself...it might initially seem a lot to swallow (especially if it's your first sortie using interrupts - which are pretty much essential for capacitive touch), but like everything else, if you break it down into smaller 'building blocks' and approach each block one at a time, then it becomes much more digestible.

    You obviously need to get the relaxation oscillator working first - an oscilloscope is *extremely* useful to make sure this is working (& getting it working proved to be the most troublesome part for me....there's a whole heap of registers that need to be set 'oh so right', once I got it running, I was off to the races).

    re those wsave errors you're seeing when compiling - you need to comment out some lines in the DTS_INTS-14.BAS (search on the error wsave VAR BYTE $20 SYSTEM on this forum to find out what needs doing!)
    Last edited by HankMcSpank; - 31st August 2010 at 10:16.

  26. #26
    Join Date
    Nov 2003
    Location
    Greece
    Posts
    3,807


    Did you find this post helpful? Yes | No

    Default Re: 16F726 Capacitive sensing module

    Finally I got my first touch demo working with 16F1827 chip. The CSM module is easy to use and makes program small enough.

    But, I have one problem with the stability of the output that shows whether one is touching, close to touch or not touching at all.

    Although I have included Darrel's Average routine there is a grey region that makes deciding if one is touching not very clear.

    The following test code has a LED indicator to show when touch pad is really touched or not. If finger is very close, value is playing up or down the threshold and makes the LED indicator blink.

    Code:
    OPTION_REG = %10000110    'Tmr0 from 256 presc and Int Clock
      
     T1CON = %11000001 '%00110000    ' TMR1 1:8 prescale, timer1 off
    
    led         var portb.4       
    value       var word
    AvgCount CON 32  ' = Number of samples to average
    FAspread CON 10000 ' = Fast Average threshold +/-
    ADavg  VAR WORD
    flag        var bit
    'Interrupt Engine Setup
    ':::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    ASM
    INT_LIST  macro    ; IntSource,     Label,      Type,       ResetFlag?
      INT_Handler   TMR0_INT,       _Timer_0,     PBP,    yes
    
     endm
     INT_CREATE               ; Creates the interrupt processor
        INT_ENABLE   TMR0_INT
    ENDASM
    ':::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::       
    
    goto main
    
    Timer_0:
        t1con.0=0
        vALUE.lowbyte=tmr1l:VALUE.highbyte=tmr1h
        flag=1
        tmr1l=0:tmr1h=0
        t1con.0=1
    @ INT_RETURN    
    
    main:
    clear
    pause 1000
    
    start:
    if flag=1 then
        flag=0
        gosub Average
    endif
    
    hserout [27,"[H",27,"[10;0H","Value is: ",#vALUE," "]
    
    if VALUE<319 then
        high led
    else
        low led
    endif
    goto start
    
    Average:
        IF Value = ADavg Then NoChange
        IF ABS (Value - ADavg) > FAspread OR Value < AvgCount Then FastAvg
        IF ABS (Value - ADavg) < AvgCount Then RealClose
        ADavg = ADavg - (ADavg/AvgCount)
        ADavg = ADavg + (Value/AvgCount)
        GoTo AVGok
      FastAvg:
        ADavg = Value
        GoTo AVGok
      RealClose:
        ADavg = ADavg - (ADavg/(AvgCount/4))
        ADavg = ADavg + (Value/(AvgCount/4))
      AVGok:
        Value = ADavg  ' Put Average back into Value
      NoChange:
    Return
    Any ideas welcome.
    Ioannis
    Last edited by Ioannis; - 4th December 2011 at 22:21.

  27. #27
    Join Date
    Nov 2003
    Location
    Wellton, U.S.A.
    Posts
    5,924


    Did you find this post helpful? Yes | No

    Default Re: 16F726 Capacitive sensing module

    Just a wild guess...

    What if bit 6 of the T1GCON register is set to 0?
    Dave
    Always wear safety glasses while programming.

  28. #28
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default Re: 16F726 Capacitive sensing module

    Ioannis,

    Try this modification to the averaging routine for the CSM.
    http://www.picbasic.co.uk/forum/show...598#post107598
    DT

  29. #29
    Join Date
    Nov 2003
    Location
    Greece
    Posts
    3,807


    Did you find this post helpful? Yes | No

    Default Re: 16F726 Capacitive sensing module

    I wanted to correct minor mistakes in the comments of the code I posted but it is not possible. Can any of the moderators or Admins see the whole code? I cannot for sure (in the Edit Post mode).

    Dave, I have not changed the T1GCON register which by default on Power up is reset to zero. I do not use the gate anyway.

    Darrel, I missed that. Will try it an get back.

    Thanks both,
    Ioannis

  30. #30
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default Re: 16F726 Capacitive sensing module

    I use the CSMs with great success without having to average.

    I basically store away the last cap sense output reading (ie TMR1 count), take the present reading (the TMR1 count again) and just have the program calculate an ongoing 'trigger' threshold count (the threshold being the last TMR1 reading reading minus a certain percentage)

    And then just code it along the lines of if the present reading just takenis less than the threshold (ie the last reading minus a preset percentage), then the sensor has been touched....set a flag variable.

    There should be a huge amount of difference between the non touched count & the touched count ...I set my threshold at something like 30% and it trigger everytime.

    One thing i've found helps greatly with CSM ...is to adjust the CSM oscillator settings & also the sample period so that you get a 'normal' reading in the 10,000->15,000 count ballpark.
    Last edited by HankMcSpank; - 5th December 2011 at 21:37.

  31. #31
    Join Date
    Nov 2003
    Location
    Greece
    Posts
    3,807


    Did you find this post helpful? Yes | No

    Default Re: 16F726 Capacitive sensing module

    Thanks Hank. Well, 30% seems too much to me. I have managed up to 16%...

    Thanks Darrel too. Yes your suggestions did made alot of difference.

    Ioannis

  32. #32
    Join Date
    Nov 2003
    Location
    Greece
    Posts
    3,807


    Did you find this post helpful? Yes | No

    Default Re: 16F726 Capacitive sensing module

    After some testing, it seems that with the modification Darrel suggested, it needs to touch very quickly to get a 'pressed=1' flag.

    If you approach relatively slow the touch pad it won't get triggered. I may have to play with the constants in the CSM and average too.

    But it made a very reliable system now.

    Thanks for the tips.

    PIC16f1827 with the internal CSM module makes it very easy to make a touch keyboard. Only a couple of registers to setup and you are ready.

    Ioannis

  33. #33
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default Re: 16F726 Capacitive sensing module

    Yes the deviation from the 'normal' (no finger nearby) CSM output count, is related to how long the sample period is vs how long you actually touch the sensor for.....also the physical composition of the sensor itself, and how moist your finger is!

    So a quick touch might only see a 5% deviation from the normal count, whereas a long sensor press, will see the CSM output count plummet.
    Last edited by HankMcSpank; - 6th December 2011 at 16:18.

  34. #34
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default Re: 16F726 Capacitive sensing module

    Quote Originally Posted by Ioannis View Post
    If you approach relatively slow the touch pad it won't get triggered.
    I think increasing the number of samples in the average will adjust that behavior.
    DT

  35. #35
    Join Date
    Nov 2003
    Location
    Greece
    Posts
    3,807


    Did you find this post helpful? Yes | No

    Default Re: 16F726 Capacitive sensing module

    OK, seems to work good now with these settings:

    PIC chip : 16F1827
    System clock : 32MHz
    Timer0 Int's : From system clock every 8ms
    Timer1 input : From CSM module
    CSM setup : CPSCON0 = %10001100
    CPSCON1 = %00000010
    T1CON setup : %11000001
    OPTION_REG : %10000111 Timer0 with /256 prescaller
    AvgCount CON 16 ' = Number of samples to average (max 32)
    FAspread CON 25

    Now you may wonder why the average constants are low valued. Because the system clock is high enough, clocking everything too fast. But with these settings looks OK for the touch pad I am testing.

    Ioannis

  36. #36
    Join Date
    Feb 2010
    Posts
    30


    Did you find this post helpful? Yes | No

    Default Re: 16F726 Capacitive sensing module

    Ioannis , geia !

    Is it possible to post the modified optimized code for the 16F1827?

    Thank you.
    Lakis.

  37. #37
    Join Date
    Nov 2003
    Location
    Greece
    Posts
    3,807


    Did you find this post helpful? Yes | No

    Default Re: 16F726 Capacitive sensing module

    Geia Laki.

    OK, it is over a year now. Hmm, where do I have this file?

    Let me search a bit, OK?

    Ioannis

  38. #38
    Join Date
    Nov 2003
    Location
    Greece
    Posts
    3,807


    Did you find this post helpful? Yes | No

    Default Re: 16F726 Capacitive sensing module

    OK, Here it is.

    It makes use of Darrels Averaging and Interrupt routines.

    Unfortunately I had not add comments and may be hard to follow this test code. Sorry about that.

    Ioannis
    Attached Files Attached Files

  39. #39
    Join Date
    Feb 2010
    Posts
    30


    Did you find this post helpful? Yes | No

    Default Re: 16F726 Capacitive sensing module

    OK !
    It is not so difficult to read.

    Thanks again!
    Lakis from Thessaloniki.

  40. #40
    Join Date
    Oct 2013
    Posts
    41


    Did you find this post helpful? Yes | No

    Default Re: 16F726 Capacitive sensing module

    Hi,
    Is it possible to use A ByteBucher code on PIC16F724.

    How to modified a Darrels Taylor file "DT_INTS-14.bas" with his red text on this thread.
    When I open his file "DT_INTS-14.bas" ver 1.10 I dont see anywhere where I can put this code:

    GetIntInfo macro IflagReg, IflagBit

    Found = NO
    ; nolist
    ifdef TMR1GIF ;----{ TMR1 Gate Interrupt }---------------[PIR1, TMR1GIF]---
    INT_Source PIR1, TMR1GIF, PIE1, TMR1GIE


    and


    ASM
    #define TMR1GATE_INT PIR1,TMR1GIF ;-- Timer1 Gate Interrupt


    Can someone help me to use capacitive sensing on this pic

    Best regards

Similar Threads

  1. Version Control
    By btaylor in forum mel PIC BASIC Pro
    Replies: 33
    Last Post: - 16th October 2011, 17:12
  2. Relaxation oscillators (for capacititive touch sensing)
    By HankMcSpank in forum mel PIC BASIC Pro
    Replies: 24
    Last Post: - 6th December 2009, 22:03
  3. mTouch capacitive sensing
    By jrprogrammer in forum mel PIC BASIC Pro
    Replies: 14
    Last Post: - 1st November 2008, 22:54
  4. Replies: 1
    Last Post: - 27th July 2008, 06:14
  5. Rf module
    By tangray in forum Adverts
    Replies: 0
    Last Post: - 7th August 2006, 07:14

Members who have read this thread : 3

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