CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

CVD touch button with pic12F615
Goto page 1, 2, 3  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
viethung_tdh



Joined: 31 May 2014
Posts: 18

View user's profile Send private message

CVD touch button with pic12F615
PostPosted: Sun Jun 01, 2014 1:03 am     Reply with quote

Hi guys.

i have a problems with CVD touch button :
I want use touch buttton to controll PWM signal from pic12f615:
code:
Code:

/*========================================================================
 
         
   Phan cung: Pic 12F615
   
   Thach anh: Internal 4Mhz
   
   Tac gia: Dang Viet Hung
   
   Thoi gian: 5.2014

=========================================================================*/

/****************************Bo tien xu li********************************/
#include <12F615.h>
#device ADC=16

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOMCLR
#FUSES IOSC8
#FUSES NOMCLR                     //Master Clear pin enabled
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOPUT                    //No Power Up Timer
#FUSES RESERVED                 //Used to set the reserved FUSE bits
#use delay(internal=4000000)
//#use fast_io(a)

/*************************************************************************/
/****************************Khai bao bien toan cuc **********************/
int16 average[5];
int16 temp=0,Touch=0;
unsigned char i,dem;
/*************************************************************************/
/**************************** Khai bao ham  ******************************/
/*===========================Ham doc touch button========================*/
void touch_read()
{
   set_adc_channel(sAN3);
   delay_us(10);
   Touch = read_adc();
   delay_us(10);
   if(Touch<temp) dem++;
}
/*=========================Ham duty cycle================================*/
void duty_cycle()
{
      switch(dem)
      {
      case 1:
      {
      setup_ccp1(CCP_PWM);   // che do PWM
      setup_timer_2(T2_DIV_BY_16, 112, 1);
      set_pwm1_duty(0);break;}
      case 2:
      {set_pwm1_duty(0);break;}
      case 3:
      {set_pwm1_duty(56);break;}
      case 4:
      {set_pwm1_duty(101);break;}
      case 5:
      {set_pwm1_duty(56);break;}
     
    }
}

/*************************************************************************/


/***************************** Ham chinh *********************************/
void main()
{
 
   setup_adc_ports(sAN3|VSS_VDD);
   setup_adc(adc_clock_internal);
   set_adc_channel(sAN3);//chon kenh 0 lam analog in
   delay_us(10);
   for(i=0;i<5;i++)       //lay mau 5 lan
   {
      average[i] = read_adc();
      delay_us(8);
      temp = temp + average[i]; //cong don va lay gia tri trung bình
   }
   temp = temp/5;// Lay gia tri trung binh
   while(TRUE)
   {
      touch_read();
      duty_cycle();
      if(dem==6)dem=1;   
   }
}
/*************************************************************************/


it not running!
please help me.

my CCS Version 4.104
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

Re: CVD touch button with pic12F615
PostPosted: Sun Jun 01, 2014 1:50 am     Reply with quote

viethung_tdh wrote:
Hi guys.

i have a problems with CVD touch button :
I want use touch buttton to controll PWM signal from pic12f615:
code:
Code:

......
......
#include <12F615.h>
#device ADC=16
.....
.....
   while(TRUE)
   {
      touch_read();
      duty_cycle();
      if(dem==6)dem=1;   
   }
}
/*************************************************************************/


it not running!
please help me.

my CCS Version 4.104


You need to learn to debug.
Saying "it not running!" is as useful as a chocolate fire guard.

Tell us:-

1) Whether your PIC is running at all.
2) What is working
3) What is not working.
4) What the initial value of 'dem' is
5) What happens to duty if dem happens to be 6.
6) How the system resets if dem > 6.

Start with an LED flasher.
Write test code to check that each function is working as intended.

Mike
viethung_tdh



Joined: 31 May 2014
Posts: 18

View user's profile Send private message

Re: CVD touch button with pic12F615
PostPosted: Sun Jun 01, 2014 2:56 am     Reply with quote

Mike Walne wrote:
viethung_tdh wrote:
Hi guys.

i have a problems with CVD touch button :
I want use touch buttton to controll PWM signal from pic12f615:
code:
Code:

......
......
#include <12F615.h>
#device ADC=16
.....
.....
   while(TRUE)
   {
      touch_read();
      duty_cycle();
      if(dem==6)dem=1;   
   }
}
/*************************************************************************/


it not running!
please help me.

my CCS Version 4.104


You need to learn to debug.
Saying "it not running!" is as useful as a chocolate fire guard.

Tell us:-

1) Whether your PIC is running at all.
2) What is working
3) What is not working.
4) What the initial value of 'dem' is
5) What happens to duty if dem happens to be 6.
6) How the system resets if dem > 6.

Start with an LED flasher.
Write test code to check that each function is working as intended.

Mike

Dear Mike.
My application:
I want use touch buttton to controll PWM signal from pic12f615:

The first touch : Duty cycle =0% (550hz :setup_timer_2(T2_DIV_BY_16, 112, 1); ) and dem =1 .
The second touch : Duty cycle = 50% => dem= 2
3rd touch : Duty cycle = 10% => dem =3
if dem== 6 => dem =2 return duty cycle =50%
.............................

i checked the program with replace the touch button by button and the program running good
you can see:
Code:

#include <12F615.h>
#device ADC=16

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOMCLR
#FUSES IOSC8
#FUSES NOMCLR                     //Master Clear pin enabled
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOPUT                    //No Power Up Timer
#FUSES RESERVED                 //Used to set the reserved FUSE bits
#use delay(internal=4000000)
//#use fast_io(a)
#define Button   PIN_A4   


//fine LED1      PIN_A0
//efine LED2     PIN_A1
//efine LED3     PIN_A2
void main()
{
 unsigned char dem;
//setup_adc(adc_clock_internal);
 //setup_adc_ports(NO_ANALOG|VSS_VDD);
 setup_comparator(NC_NC_NC_NC);
//set_adc_channel(4);
 delay_ms(10);
 
 
set_tris_A(0b00010000);
output_A(0xff);
dem=0;


while(TRUE)
  {
  //adc=read_adc();
  if(!input(Button))// Neu nut bam duoc bam
    {
     dem++;
     switch(dem)
     {
      case 1:
      {
      setup_ccp1(CCP_PWM);   // che do PWM
      setup_timer_2(T2_DIV_BY_16, 112, 1);
      set_pwm1_duty(0);break;}
      case 2:
      {set_pwm1_duty(0);break;}
      case 3:
      {set_pwm1_duty(56);break;}
      case 4:
      {set_pwm1_duty(101);break;}
      case 5:
      {set_pwm1_duty(56);break;}
     
    }
    while(!input(Button));// cho den khi nut bam nha ra moi thuc hien lenh
    delay_ms(20);
    if(dem==6)
    dem=2;
   
  }
  }
  }
Ttelmah



Joined: 11 Mar 2010
Posts: 19529

View user's profile Send private message

PostPosted: Sun Jun 01, 2014 3:34 am     Reply with quote

The code as written, has nothing to do with touch buttons at all!......

You are calling a function 'touch_read', but all it is doing is reading the ADC.

For 'touch', what happens is that the ADC internal capacitor is charged to the supply (using a second ADC input). Then you ground the ADC pin for a moment. Set it back to being an open circuit (input), then connect it to the ADC, and take the reading. The reading then reflects the ratio between the internal capacitance, and the capacitance on the pin.

Look at AN1298.

The neat thing is that using two pins, you can use these alternately to charge and measure, to give two inputs from the two pins, but two ADC inputs minimum are required. You can't do it with one pin....
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Sun Jun 01, 2014 3:38 am     Reply with quote

OK. Your PIC is running.

You do not have any de-bounce.
This bit and your code don't agree, but I will let you sort that out.
Quote:
My application:
I want use touch buttton to controll PWM signal from pic12f615:

The first touch : Duty cycle =0% (550hz :setup_timer_2(T2_DIV_BY_16, 112, 1); ) and dem =1 .
The second touch : Duty cycle = 50% => dem= 2
3rd touch : Duty cycle = 10% => dem =3
if dem== 6 => dem =2 return duty cycle =50%

From your original code:-

1) Which part have you not tested?
2) What do you have to do next?

Mike

EDIT Mr T. has given you a big hint.
viethung_tdh



Joined: 31 May 2014
Posts: 18

View user's profile Send private message

PostPosted: Sun Jun 01, 2014 3:57 am     Reply with quote

Ttelmah wrote:
The code as written, has nothing to do with touch buttons at all!......

You are calling a function 'touch_read', but all it is doing is reading the ADC.

For 'touch', what happens is that the ADC internal capacitor is charged to the supply (using a second ADC input). Then you ground the ADC pin for a moment. Set it back to being an open circuit (input), then connect it to the ADC, and take the reading. The reading then reflects the ratio between the internal capacitance, and the capacitance on the pin.

Look at AN1298.

The neat thing is that using two pins, you can use these alternately to charge and measure, to give two inputs from the two pins, but two ADC inputs minimum are required. You can't do it with one pin....

So i must use 2 channel ADC?
You can code help me!
viethung_tdh



Joined: 31 May 2014
Posts: 18

View user's profile Send private message

PostPosted: Sun Jun 01, 2014 3:57 am     Reply with quote

Mike Walne wrote:
OK. Your PIC is running.

You do not have any de-bounce.
This bit and your code don't agree, but I will let you sort that out.
Quote:
My application:
I want use touch buttton to controll PWM signal from pic12f615:

The first touch : Duty cycle =0% (550hz :setup_timer_2(T2_DIV_BY_16, 112, 1); ) and dem =1 .
The second touch : Duty cycle = 50% => dem= 2
3rd touch : Duty cycle = 10% => dem =3
if dem== 6 => dem =2 return duty cycle =50%

From your original code:-

1) Which part have you not tested?
2) What do you have to do next?

Mike

EDIT Mr T. has given you a big hint.

[img][/img]
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Sun Jun 01, 2014 7:59 am     Reply with quote

Ttelmah has told you what to do.

Read the application note AN1298.
It explains both hardware and software, in detail.

Mike
viethung_tdh



Joined: 31 May 2014
Posts: 18

View user's profile Send private message

PostPosted: Tue Jun 03, 2014 4:58 am     Reply with quote

Hi Mike Walne and Ttelmah
I change code for mtouch use two channel ADC:
Code:

/*========================================================================
   Mo ta:
         
   Phan cung: Pic 12F615
   
   Thach anh: Internal 4Mhz
   
   Tac gia:
   
   Thoi gian: 5.2014

=========================================================================*/

/****************************Bo tien xu li********************************/
#include <12F615.h>
#device ADC=16

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOMCLR
#FUSES IOSC8
#FUSES NOMCLR                     //Master Clear pin enabled
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOPUT                    //No Power Up Timer
#FUSES RESERVED                 //Used to set the reserved FUSE bits
#use delay(internal=4000000)
#use fast_io(a)

/*************************************************************************/
/****************************Khai bao bien toan cuc **********************/
int16 average[5];
int16 temp=0,Touch=0;
unsigned char i,dem;
/*************************************************************************/
/**************************** Khai bao ham  ******************************/
/*===========================Ham doc touch button========================*/
void touch_read()
{
   set_adc_channel(sAN0);
   set_tris_a(0);
   output_bit(PIN_A0,1);
   output_bit(PIN_A3,0);
   set_tris_a(0b00011011);
   set_adc_channel(sAN3);
   delay_us(10);
   Touch = read_adc();
   delay_us(10);
   if(Touch<temp) dem++;
}
/*=========================Ham duty cycle================================*/
void duty_cycle()
{
      switch(dem)
      {
      case 1:
      {
      setup_ccp1(CCP_PWM);   // che do PWM
      setup_timer_2(T2_DIV_BY_16, 112, 1);
      set_pwm1_duty(0);break;}
      case 2:
      {set_pwm1_duty(0);break;}
      case 3:
      {set_pwm1_duty(56);break;}
      case 4:
      {set_pwm1_duty(101);break;}
      case 5:
      {set_pwm1_duty(56);break;}
     
    }
}

/*************************************************************************/


/***************************** Ham chinh *********************************/
void main()
{
 
   setup_adc_ports(sAN3|VSS_VDD);
   setup_adc(adc_clock_internal);
   set_adc_channel(sAN0);
   set_tris_a(0);
   output_bit(PIN_A0,1);
   output_bit(PIN_A3,0);
   set_tris_a(0b00011011);
   set_adc_channel(sAN3);
   for(i=0;i<5;i++)       //lay mau 5 lan
   {
      average[i] = read_adc();
      delay_us(8);
      temp = temp + average[i]; //cong don va lay gia tri trung bình
   }
   temp = temp/5;// Lay gia tri trung binh
   while(TRUE)
   {
      touch_read();
      duty_cycle();
      if(dem==6)dem=1;   
   }
}
/*************************************************************************/


please help me check it!

Thank you very much!
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Tue Jun 03, 2014 7:25 am     Reply with quote

Reduce your code to testing the touch switch only. (Probably no more than 10 lines of code.)

Get to the stage where you know it is working correctly.

I don't have your touch switch, so there is little point in me duplicating your efforts.

Mike
Ttelmah



Joined: 11 Mar 2010
Posts: 19529

View user's profile Send private message

PostPosted: Tue Jun 03, 2014 7:28 am     Reply with quote

Code:

#include <12F615.h>
#device ADC=10

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOMCLR
#FUSES IOSC8
#FUSES NOMCLR                     //Master Clear pin enabled
#FUSES NOPUT                    //No Power Up Timer
#FUSES RESERVED                 //Used to set the reserved FUSE bits
#use delay(internal=4000000)

int16 get_touch()
{
   output_high(PIN_A0);   //set AN0 driven high
   set_adc_channel(sAN0); //connect it to the ADC
   output_low(PIN_A3); //set AN3 to drive low
   output_float(PIN_A3); //set it as an input
   set_adc_channel(sAN3); //now connect this to the ADC
   delay_us(10); //wait for Tacq
   return read_adc();  //and get reading.
}

void touch_read()
{
   touch=get_touch();
   if(Touch<temp) dem++;
}

void main()
{
   int16 temp=0;
   setup_adc_ports(sAN3|sAN0|VSS_VDD);
   //you need to enable both channels
   setup_adc(ADC_CLOCK_DIV_8);
   //Using the internal clock degrades accuracy.
   for(i=0;i<5;i++)       //lay mau 5 lan
   {
      temp+ = get_touch();
      delay_us(8);
   }
   //because you had the ADC set to 16bit, the 16bit sum would overflow
   temp = temp/5;// Lay gia tri trung binh
   while(TRUE)
   {
      delay_us(100);//slow the loop a little
      touch_read();
      duty_cycle();
      if(dem==6)dem=1;   
   }
}


Key big error is running the ADC in 16bit mode (no more accuracy doing this), then summing five readings in an int16. Overflow....

If you look at the code, you can see it follows the steps in the application note exactly.

I'd suggest ignoring your PWM adjustment for a moment, and just sending the ADC readings from the touch calls to a serial port, and then seeing what happens to the readings as capacitance changes. Reading will go up with increased capacitance, so testing if the value is less than the calibration value, may not be correct....
viethung_tdh



Joined: 31 May 2014
Posts: 18

View user's profile Send private message

PostPosted: Wed Jun 04, 2014 12:47 am     Reply with quote

Mike Walne wrote:
Reduce your code to testing the touch switch only. (Probably no more than 10 lines of code.)

Get to the stage where you know it is working correctly.

I don't have your touch switch, so there is little point in me duplicating your efforts.

Mike

Ttelmah wrote:
Code:

#include <12F615.h>
#device ADC=10

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOMCLR
#FUSES IOSC8
#FUSES NOMCLR                     //Master Clear pin enabled
#FUSES NOPUT                    //No Power Up Timer
#FUSES RESERVED                 //Used to set the reserved FUSE bits
#use delay(internal=4000000)

int16 get_touch()
{
   output_high(PIN_A0);   //set AN0 driven high
   set_adc_channel(sAN0); //connect it to the ADC
   output_low(PIN_A3); //set AN3 to drive low
   output_float(PIN_A3); //set it as an input
   set_adc_channel(sAN3); //now connect this to the ADC
   delay_us(10); //wait for Tacq
   return read_adc();  //and get reading.
}

void touch_read()
{
   touch=get_touch();
   if(Touch<temp) dem++;
}

void main()
{
   int16 temp=0;
   setup_adc_ports(sAN3|sAN0|VSS_VDD);
   //you need to enable both channels
   setup_adc(ADC_CLOCK_DIV_8);
   //Using the internal clock degrades accuracy.
   for(i=0;i<5;i++)       //lay mau 5 lan
   {
      temp+ = get_touch();
      delay_us(8);
   }
   //because you had the ADC set to 16bit, the 16bit sum would overflow
   temp = temp/5;// Lay gia tri trung binh
   while(TRUE)
   {
      delay_us(100);//slow the loop a little
      touch_read();
      duty_cycle();
      if(dem==6)dem=1;   
   }
}


Key big error is running the ADC in 16bit mode (no more accuracy doing this), then summing five readings in an int16. Overflow....

If you look at the code, you can see it follows the steps in the application note exactly.

I'd suggest ignoring your PWM adjustment for a moment, and just sending the ADC readings from the touch calls to a serial port, and then seeing what happens to the readings as capacitance changes. Reading will go up with increased capacitance, so testing if the value is less than the calibration value, may not be correct....


I will create a circuit test and show the results to you!
viethung_tdh



Joined: 31 May 2014
Posts: 18

View user's profile Send private message

PostPosted: Sat Jun 07, 2014 12:38 pm     Reply with quote

Hi Ttelmah and Mike Walne
I created a circuit test.You can see the schematic:


and PCB:



I think the touch 1 running not good so i make the touch 2.
Code:
Code:
#include <12F615.h>
#device ADC=10

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOMCLR
#FUSES IOSC8
#FUSES NOMCLR                     //Master Clear pin enabled
#FUSES NOPUT                    //No Power Up Timer
#FUSES RESERVED                 //Used to set the reserved FUSE bits
#use delay(internal=4000000)


/*************************************************************************/
/****************************Khai bao bien toan cuc **********************/

int16 temp=0,Touch=0;
unsigned char i,dem;
/*************************************************************************/
/**************************** Khai bao ham  ******************************/
/*===========================Ham doc touch button========================*/
int16 get_touch()
{
   output_high(PIN_A0);   //set AN0 driven high
   set_adc_channel(sAN0); //connect it to the ADC
   output_low(PIN_A3); //set AN3 to drive low
   output_float(PIN_A3); //set it as an input
   set_adc_channel(sAN3); //now connect this to the ADC
   delay_us(10); //wait for Tacq
   return read_adc();  //and get reading.
}
/*==========================Ham doc gia tri =============================*/
void touch_read()
{
   touch=get_touch();
   
   if(Touch<temp) dem++;
}
/*=========================Ham duty cycle================================*/
void duty_cycle()
{
      switch(dem)
      {
      case 1:
      {
      setup_ccp1(CCP_PWM);   // che do PWM
      setup_timer_2(T2_DIV_BY_16, 112, 1);
      set_pwm1_duty(0);break;}
      case 2:
      {set_pwm1_duty(0);break;}
      case 3:
      {set_pwm1_duty(56);break;}
      case 4:
      {set_pwm1_duty(101);break;}
      case 5:
      {set_pwm1_duty(56);break;}
     
    }
}

/*************************************************************************/


/***************************** Ham chinh *********************************/
void main()
{
   int16 temp=0;
   setup_adc_ports(sAN3|sAN0|VSS_VDD);
   //you need to enable both channels
   setup_adc(ADC_CLOCK_DIV_8);
   //Using the internal clock degrades accuracy.
   for(i=0;i<5;i++)       //lay mau 5 lan
   {
      temp += get_touch();
      delay_us(8);
   }
   //because you had the ADC set to 16bit, the 16bit sum would overflow
   temp = temp/5;// Lay gia tri trung binh
   while(TRUE)
   {
      delay_us(100);//slow the loop a little
      touch_read();
      duty_cycle();
      if(dem==6)dem=1;   
   }
}
/*************************************************************************/


But it not good :
you can see:

if you dont touch:



and press touch 1:

and press touch 2:



So i change the code:
Code:
if(Touch<temp) dem++;
by
Code:
if(Touch>temp) dem++;

and the signal :

+ Dont touch :

+Touch 1 :

+ Touch 2:

Can you help me?
i think the error from code.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sat Jun 07, 2014 3:59 pm     Reply with quote

Quote:
int16 get_touch()
{
output_high(PIN_A0); //set AN0 driven high
set_adc_channel(sAN0); //connect it to the ADC
output_low(PIN_A3); //set AN3 to drive low
output_float(PIN_A3); //set it as an input
set_adc_channel(sAN3); //now connect this to the ADC
delay_us(10); //wait for Tacq
return read_adc(); //and get reading.
}

This is a coding bug. The set_adc_channel() function does not use a sANx
constant as the parameter. The parameter is the ADC channel. The
parameter should be a number such as 0, 1, 2, 3.

Look at the definitions of the sANx constants from the 12F615.h file:
Code:

#define sAN0      1         
#define sAN1      2
#define sAN2      4
#define sAN3      8

Your code above which uses the sANx constants is actually selecting
ADC channels 1 and 8 (which doesn't even exist). This will totally screw
up your program. Fix this by using 0 and 3 as the channel parameters
for set_adc_channel().
Ttelmah



Joined: 11 Mar 2010
Posts: 19529

View user's profile Send private message

PostPosted: Sun Jun 08, 2014 1:07 am     Reply with quote

There is also a big misunderstanding going on.

A _single_ touch pin requires two ADC inputs. The code as written implements one touch pad only.
You can re-use the same two inputs to give a second touch input on the second pin, by reversing the selections done in the code. The application note is the key thing to read here.

The touch pad would normally be done as a pad, with a ground ring around it. The measurement is of the change in capacitance between the pad and the ring.
The circuit misses the protection diodes shown in Mike's circuit. Needed or you can quite quickly kill the chip.
There are problems with the pin numbers. Didn't check these, but on most 8pin PIC's, A3, is input only, so can't be used as the second pin AN3, is on A4.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2, 3  Next
Page 1 of 3

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group