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
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
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!
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)
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
Re: 16F726 Capacitive sensing module
Just a wild guess...
What if bit 6 of the T1GCON register is set to 0?
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
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
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.
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
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
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.
Re: 16F726 Capacitive sensing module
Quote:
Originally Posted by
Ioannis
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.
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
Re: 16F726 Capacitive sensing module
Ioannis , geia !
Is it possible to post the modified optimized code for the 16F1827?
Thank you.
Lakis.
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
1 Attachment(s)
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
Re: 16F726 Capacitive sensing module
OK !
It is not so difficult to read.
Thanks again!
Lakis from Thessaloniki.
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