View previous topic :: View next topic |
Author |
Message |
J_GROUP
Joined: 25 Aug 2015 Posts: 18
|
Capacitive touch on 16F722A |
Posted: Sat May 14, 2016 1:57 am |
|
|
Dear All,
I make capacitive touch circuit with 16F722a.
But I have problem. Whenever touch to key, the sounder don't turn off when released.
Below is my code:
Code: |
#include <16f722.h>
#fuses NOWDT,NOPROTECT,MCLR,INTRC_IO,VCAP_A5,BORV25,NOBROWNOUT
#use delay (INTERNAL=4M)
#use TOUCHPAD (Range=H,scantime=32ms,threshold=16,PIN_B0='A',PIN_B1='B',PIN_B2='C',PIN_B3='D',PIN_B4='E',PIN_B5='F')
#define Sounder PIN_A1
#define KEYA 0
#define KEYB 1
#define KEYC 2
#define KEYD 3 //defines for the key positions in the data array
#define KEYE 4
#define KEYF 5 //defines for the key positions in the data array
#define KEYON(keyno) bit_test(TOUCHPADSTATUS,keyno)
#byte CPSCON0 = 0x108
int flg;
void main(void)
{
enable_interrupts(GLOBAL);
delay_ms(300);
//Allow time for the touchpad code to have scanned the pads
TOUCHPAD_STATE(1); //This 'calibrates' the touchpad
//The touchpad needs to be running _before_ you call this
flg=0;
output_low(Sounder);
//now simplified code to just turn each LED on/off for a touchpad
for (;;)
{
delay_ms(200); //allow touch to rescan
flg=0;
if (KEYON(KEYA))
{
output_high(Sounder);
delay_ms(100);
}
if (KEYON(KEYB))
{
output_high(Sounder);
delay_ms(100);
}
if (KEYON(KEYC))
{
output_high(Sounder);
delay_ms(100);
}
if (KEYON(KEYD))
{
output_high(Sounder);
delay_ms(100);
}
if (KEYON(KEYE))
{
output_high(Sounder);
delay_ms(100);
}
if (KEYON(KEYF))
{
output_high(Sounder);
delay_ms(100);
}
output_low(Sounder);
}
} |
|
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9221 Location: Greensville,Ontario
|
|
Posted: Sat May 14, 2016 5:21 am |
|
|
Have to ask ...what is the 'Sounder' and HOW is it connected to the PIC ?
Have you tried an LED in it's place and get the same result?
Jay |
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Sat May 14, 2016 7:44 am |
|
|
look at your 'LST file and see how this compiles
Code: |
#define KEYON(keyno) bit_test(TOUCHPADSTATUS,keyno) |
the answer may lie in that direction |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19498
|
|
Posted: Sat May 14, 2016 8:14 am |
|
|
Add a 'touchpad_getc' to your entries.
The code does not automatically clear the touchpadstatus variable. So when a key is 'seen', it only clears once you 'get' the key.
If fact for what you are doing, you don't need to use touchpadstatus at all:
Code: |
if (touchpad_hit())
{
switch(touchpad_getc()){
case 'A':
//code for key 'A'
break;
case 'B':
//etc. for all the keys
}
}
|
|
|
|
J_GROUP
Joined: 25 Aug 2015 Posts: 18
|
|
Posted: Sat May 14, 2016 11:15 am |
|
|
Dear all,
Thank for reply.
I don't want use function touchpad_hit(). Because I want to detect hold key action. Have you got other solution for me ? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19498
|
|
Posted: Sat May 14, 2016 1:19 pm |
|
|
OK.
I found it does not automatically clear the status of a detected bit, so I'd suggest you clear the bits yourself. They will set again if the key is still detected.
The interrupt code sets the bits if they are above the cal+threshold value. It relies on getc to then handle clearing them. If you don't use getc, you have to do this yourself. |
|
|
J_GROUP
Joined: 25 Aug 2015 Posts: 18
|
|
Posted: Sun May 15, 2016 9:49 am |
|
|
I was add touchpad_getc() for each key then the status of key press has clear.
But I want to key hold function ex: sounder turn on while press and hold the keypad. Have you got any idea for this? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19498
|
|
Posted: Sun May 15, 2016 10:27 am |
|
|
As I said:
"I'd suggest you clear the bits yourself. They will set again if the key is still detected." |
|
|
J_GROUP
Joined: 25 Aug 2015 Posts: 18
|
|
Posted: Mon May 16, 2016 1:19 am |
|
|
Ttelmah wrote: | As I said:
"I'd suggest you clear the bits yourself. They will set again if the key is still detected." |
Can you give me a detail example code?
Thank you |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19498
|
|
Posted: Mon May 16, 2016 2:21 am |
|
|
Code: |
#define KEYON(keyno) bit_test(TOUCHPADSTATUS,keyno)
#define CLEAR_KEY(keyno) bit_clear(TOUCHPADSTATUS,keyno)
//Then for each key:
if (KEYON(KEYA))
{
CLEAR_KEY(KEYA);
output_high(Sounder);
delay_ms(100);
}
|
As written it's going to pulse on/off, since you turn the sounder off, even is a key is still made. So really:
Code: |
#define KEYON(keyno) bit_test(TOUCHPADSTATUS,keyno)
#define CLEAR_KEY(keyno) bit_clear(TOUCHPADSTATUS,keyno)
#define NO_KEY (TOUCHPADSTAUS & 0x3F)==0
int8 keyno;
for (;;)
{
delay_ms(200); //allow touch to rescan
if (NO_KEY)
output_low(Sounder);
for (keyno=0;keyno<6;keyno++)
{
if (KEYON(keyno))
{
CLEAR_KEY(keyno);
output_high(Sounder);
}
}
}
|
This way the only delay is the rescan, and if no keys are on, _then_ the sounder is turned off.
Sounder will stay on for 200mSec, since even if released, the loop takes this long. |
|
|
J_GROUP
Joined: 25 Aug 2015 Posts: 18
|
|
Posted: Mon May 16, 2016 2:33 am |
|
|
I following code as you provided.
But I still cant detect long press (hold key), current code working like using Touchpad_hit() function.
Please see my code
Code: | #include <16f722.h>
#fuses NOWDT,NOPROTECT,MCLR,INTRC_IO,VCAP_A5,BORV25,NOBROWNOUT
#use delay (INTERNAL=4M)
#use TOUCHPAD (Range=H,scantime=32ms,threshold=16,PIN_B0='A',PIN_B1='B',PIN_B2='C',PIN_B3='D',PIN_B4='E',PIN_B5='F')
#define Sounder PIN_A1
#define KEYA 0
#define KEYB 1
#define KEYC 2
#define KEYD 3 //defines for the key positions in the data array
#define KEYE 4
#define KEYF 5 //defines for the key positions in the data array
#define KEYON(keyno) bit_test(TOUCHPADSTATUS,keyno)
#define CLEAR_KEY(keyno) bit_clear(TOUCHPADSTATUS,keyno)
#define NO_KEY (TOUCHPADSTAUS & 0x3F)==0
int flg;
void main(void)
{
enable_interrupts(GLOBAL);
delay_ms(300);
TOUCHPAD_STATE(1); //This 'calibrates' the touchpad
flg=0;
output_low(Sounder);
while(true)
{
delay_ms(40); //allow touch to rescan
flg=0;
if (KEYON(KEYA))
{
output_high(Sounder);
CLEAR_KEY(KEYA);
flg=1;
}
if (KEYON(KEYB))
{
output_high(Sounder);
CLEAR_KEY(KEYB);
flg=1;
}
if (KEYON(KEYC))
{
output_high(Sounder);
CLEAR_KEY(KEYC);
flg=1;
}
if (KEYON(KEYD))
{
output_high(Sounder);
CLEAR_KEY(KEYD);
flg=1;
}
if (KEYON(KEYE))
{
output_high(Sounder);
CLEAR_KEY(KEYE);
flg=1;
}
if (KEYON(KEYF))
{
output_high(Sounder);
CLEAR_KEY(KEYF);
flg=1;
}
if (flg==0)
{
output_low(Sounder);
}
}
} |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19498
|
|
Posted: Mon May 16, 2016 3:39 am |
|
|
OK. In which case you have to go back to the thread you got the references to TOUCHPADSTATUS from, and do the detection yourself. You have to read the level data from the TOUCHDATA array, and test yourself for the value being above the threshold. This was how the poster there had to do it in the end.
The problem is that all the CCS test code is written on the assumption of emulating keypad use, not touch and hold.
Code: |
//After the touchpad is initialised, copy the calibration data
#define KEYS 6
int8 touch_init[KEYS];
for (ctr=0;ctr<KEYS;ctr++)
touch_init[ctr]=TOUCHDATA[ctr];
//Then KEYON becomes
#define KEYON(keyno) TOUCHDATA[keyno]>touch_init[keyno]
|
The compiler automatically offsets the recorded calibration values with the threshold value. |
|
|
J_GROUP
Joined: 25 Aug 2015 Posts: 18
|
|
Posted: Mon May 16, 2016 3:56 am |
|
|
It's not working sir,
Code: | #include <16f722.h>
#fuses NOWDT,NOPROTECT,MCLR,INTRC_IO,VCAP_A5,BORV25,NOBROWNOUT
#use delay (INTERNAL=4M)
#use TOUCHPAD (Range=H,scantime=32ms,threshold=16,PIN_B0='A',PIN_B1='B',PIN_B2='C',PIN_B3='D',PIN_B4='E',PIN_B5='F')
#define Sounder PIN_A1
#define KEYA 0
#define KEYB 1
#define KEYC 2
#define KEYD 3 //defines for the key positions in the data array
#define KEYE 4
#define KEYF 5 //defines for the key positions in the data array
#define KEYON(keyno) TOUCHDATA[keyno]>touch_init[keyno]
#define KEYS 6
int8 touch_init[KEYS];
int8 ctr;
int flg;
void main(void)
{
enable_interrupts(GLOBAL);
delay_ms(300);
TOUCHPAD_STATE(1); //This 'calibrates' the touchpad
flg=0;
output_low(Sounder);
for (ctr=0;ctr<KEYS;ctr++)
{
touch_init[ctr]=TOUCHDATA[ctr];
}
while(true)
{
delay_ms(40); //allow touch to rescan
flg=0;
if (KEYON(KEYA))
{
output_high(Sounder);
flg=1;
}
if (KEYON(KEYB))
{
output_high(Sounder);
flg=1;
}
if (KEYON(KEYC))
{
output_high(Sounder);
flg=1;
}
if (KEYON(KEYD))
{
output_high(Sounder);
flg=1;
}
if (KEYON(KEYE))
{
output_high(Sounder);
flg=1;
}
if (KEYON(KEYF))
{
output_high(Sounder);
flg=1;
}
if (flg==0)
{
output_low(Sounder);
}
}
} |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19498
|
|
Posted: Mon May 16, 2016 4:17 am |
|
|
What compiler version are you on?.
There was a problem a while ago, CCS changed where the data array was int16 or int8 at some point.
Check the threads about using the data array. This was mentioned.
On older compilers the array was int16.
Also, if I remember correctly, you have to call touchpad_state(2) to actually get the data into the array. So you would need to do this before reading the initial values, and then each time round the loop. |
|
|
|