Hank I'd love to see how you set it up. Thanks
Hank I'd love to see how you set it up. Thanks
Alrighty, a couple of salient points about capacitive touch.
1. You need an oscillator.
2, You need something to count the 'pulses' from that oscillator
3. You need something set as an accurate time 'window' to count the pulses within
4. You need something to notice when the oscillator 'count' has diverged from the 'normal' count.
For step 1, the series of chips I mention (12f1822, 16f1824 etc), have a built in capacitive touch module, which makes it very easy (vs say the 16f690)
To set it up.......simple as eh? (the cps oscillator is now running) whatever CPS pin you choose to use needs to be an input & analogue, so for Ch0 on a 12lf1822 it's RA0....Code:CPSCON0 = %10001100 'set the CPS module highest frequency for vcc mode + timer0clock sourced from CPS module. (BIT 1) CPSCON1 = %00000000 'select CPS Ch0 - which is pin 7 on a 12lf1822 (or whichever pin you care to use)
ok, next step 2 ....you need something to count the pulses (a timer), in the above snippets I set the CPS module oscillator output pulses to feed into Timer0.Code:TRISA.0 = 1 ANSEL.0 = 1
(note: the prescaler setting will depend on your sensor &* enviromentals ...best to dabble & see what oscillator 'count's you're getting between' successive interrupts
next step 3, we need an accurate set time window ...this is where DT's fab interrupt's come in....Code:OPTION_REG = %10000111 'use timer0 as interrupt (timebase) TMR0 Prescaler on (bit3) 256:1 prescale value (bits 2-0) T1CON = %11000001 'enable timer 1 (bit 0) & source the clock from the CPS module (bit 6 & 7 =11
We're almost there- last step! In the interrupt routine, you basically keep a check of the count between 'interrupt's, when the count drops by say 20% (the count goes down when you touch your sensor), then that's a switch press.Code:ASM INT_LIST macro ; IntSource, Label, Type, ResetFlag? INT_Handler TMR0_INT, _Timer0_Int, pbp, yes endm INT_CREATE ; Creates the interrupt processor ENDASM TMR0 = 0 'clear down TIMER0 @ INT_ENABLE TMR0_INT 'enable timer0 interrupts
(note: all the stuff below are my variables...call 'em what you like!)
(sorry about the formating - looks ok before I post it....horrible after I do!Code:Timer0_Int: @ INT_DISABLE TMR0_INT ' stop timer0 interrupts while we're in here CPS0_PRESENTCOUNT = TMR1 ' take a snapshot of Timer0's present count. CPS0_THRESHOLD = CPS0_LASTCOUNT - ((CPS0_LASTCOUNT/100)*2) ' this sets the 'trigger' up for a 20% diversion (finger press) CPS0_LASTCOUNT = CPS0_PRESENTCOUNT ' store away the present timer0count for the next time we come into the interrupt routine if CPS0_PRESENTCOUNT < CPS0_THRESHOLD then 'if the present incoming timer0 count is 20% below the last count, then a finger has been placed on the sensor - go do 'stuff' blah blah TMR0 = 0 ' clear timer0 down @ INT_ENABLE TMR0_INT ' re-enable interrupt @ INT_RETURN
Last edited by HankMcSpank; - 9th September 2011 at 15:34.
I wish the 'edit' period was open for a little longer here (hint!), I've just noticed an error in that last part (cut/pastes are a hack from a much larger program)
One thing to point out, depending on how reactive you want the 'sensor touch' to be trapped, you may need quite a high interrupt rate, which can bring the PIC to it's knees using the interrupt method above - not a problem if your PIC isn't doing much else, but really hampers things if it's a busy little thing!Code:Timer0_Int: @ INT_DISABLE TMR0_INT ' stop timer0 interrupts while we're in here CPS0_PRESENTCOUNT = TMR0 ' take a snapshot of Timer0's present count. CPS0_THRESHOLD = CPS0_LASTCOUNT - ((CPS0_LASTCOUNT/100)*2) ' this sets the 'trigger' up for a 20% diversion (finger press) CPS0_LASTCOUNT = CPS0_PRESENTCOUNT ' store away the present timer0count for the next time we come into the interrupt routine if CPS0_PRESENTCOUNT < CPS0_THRESHOLD then 'if the present incoming timer0 count is 20% below the last count, then a finger is on the sensor,go do 'stuff' 'your stuff goes here' endif TMR0 = 0 ' clear timer0 down @ INT_ENABLE TMR0_INT ' re-enable interrupt @ INT_RETURN
Edit: Damn my speed typing, re this entry...
remove the above entry in my explanation post above - it relates to timer1! (which I was using too, but not needed in my example above, since I was using timer0)Code:T1CON = %11000001 'enable timer 1 (bit 0) & source the clock from the CPS module (bit 6 & 7 =11
Last edited by HankMcSpank; - 9th September 2011 at 15:47.
Returning to the mister_e's idea of the USB 8-pin chip, I wish to see that too!
You can do a lot even with NO extra I/O pins: http://www.thinkgeek.com/interests/retro/c208/
![]()
Last edited by ScaleRobotics; - 9th September 2011 at 17:04. Reason: could not resist linking image
My English doesn't sucks, it's just fugly...
Hank, awesome. you -seriously-made my day. I'm picking up the 12F1822, and 16F1823s this afternooon, and I should be up and running in no time. will I have to modify my DT file like you did a while back? I can't find that post right now.
You can read multiple touch buttons (and perform other functions at the same time) with a PIC16F690/88/887 type device. This example does the keyboard scanning (30+ keys), polyphonic tone generation, PWM, etc. with a single PIC all concurrently.
Why pay for overpriced toys when you can have
professional grade tools for FREE!!!
Ok, my process abpove was right, but the code snippets were riddled with errors (on account I used Timer1 in my code)...I actually spotted one more, so pay no attention to the code snippets above! Here's another attempt below, not saying it's error free (on account again, it's a hack), but use it as a starter, then come back if you've problems...
(this is for a 12f1822, but the concept is the same for its larger brothers...as are most of the registers - this was just a direct copy of my fuse settings....they may need tweaking to suit your own config)
One unknown, is the timer0 prescaler - you may need to tweak this (the OPTION_REG = %10000111 entry) to keep your oscillator under a count of 255 between successive timer0 interrupts (else timer0 will overflow & you'll have one helluva time trying to trap a finger press!). Actually it's better to use timer1 as the timer to count the CPS oscillator output pulses....since it's 16 bits and gives you more room to play with, but I can't be bothered to rejig the above....just consider iot as a framework to start from!Code:@ __CONFIG _CONFIG1, _FCMEN_OFF & _FOSC_INTOSC & _WDTE_SWDTEN & _MCLRE_OFF & _CP_ON & _IESO_OFF & _BOREN_OFF & _PWRTE_OFF @ __CONFIG _CONFIG2, _LVP_OFF ' DEFINE OSC 8 'tell picbasic what speed the oscillator is ' INCLUDE "DT_INTS-14.bas" ' INCLUDE "ReEnterPBP.bas" ' Include if using PBP interrupts ' Osccon = %01110010 'sets the internal oscillator to 8Mhz ' TRISA.0 = 1 . 'make pin 7 (RA1) CPS0 analogue ANSELA.0 = 1 'make pin 7 (RA1) CPS0 as input ' OPTION_REG = %10000111 'use timer0 as interrupt (timebase) TMR0 Prescaler on (bit3) 256:1 prescale value (bits 2-0) ' CPSCON0 = %10001101 'set the CPS module highest frequency availabe (fo vcc mode) + timer0 clock sourced from CPS module. (BIT 1) ' CM1CON0 = 0 ' COMPARATOR OFF CM1CON1 = 0 ' COMPARATOR OFF ' CPS0_PRESENTCOUNT var word CPS0_THRESHOLD var word CPS0_LASTCOUNT var word ' ASM INT_LIST macro ; IntSource, Label, Type, ResetFlag? INT_Handler TMR0_INT, _Timer0_Int, pbp, yes endm INT_CREATE ; Creates the interrupt processor ENDASM ' TMR0 = 0 'clear down TIMER0 @ INT_ENABLE TMR0_INT 'enable timer0 interrupts ' main: pause 100 goto main ' '************************************************************************************************** Timer0_Int: @ INT_DISABLE TMR0_INT ' stop timer0 interrupts while we're in here CPS0_PRESENTCOUNT = TMR0 ' take a snapshot of Timer0's present count. CPS0_THRESHOLD = CPS0_LASTCOUNT - ((CPS0_LASTCOUNT/100)*2) ' this sets the 'trigger' up for a 20% diversion (finger press) CPS0_LASTCOUNT = CPS0_PRESENTCOUNT ' store away the present timer0count for the next time we come into the interrupt routine if CPS0_PRESENTCOUNT < CPS0_THRESHOLD then 'if the present incoming timer0 count is 20% below the last count, then a finger has been placed on the sensor - go do 'stuff' blah blah TMR0 = 0 ' clear timer0 down @ INT_ENABLE TMR0_INT ' re-enable interrupt @ INT_RETURN end
one thing I *strongly* recommend, is getting some debiuug/serout/hserout/pickit2uart tool going down onto your PC screen ...just so you can see/confirm what you CPS oscillator counts are ....or you'll be grabbing int the dark.
Last edited by HankMcSpank; - 9th September 2011 at 17:42. Reason: I
Oh, and btw...I still consider myself a learner, so any hilarious lines or approach in my code - kindly go easy!! (just thought it worth sharing to save some of you all a bit of time)
Bookmarks