Some problems occured when I used MCU for implementing capacitive sensing

I am using PIC16f722(http://www.kynix.com/Parts/3961321/PIC16F722A-E%2FML.html ) MCU for implementing capacitive sensing but facing issues in implementing it. I have referred the Microchip AN1103 to help me with software part. I have written my own code by considering that Capacitive sensor works by detecting drop in frequency of Capacitive OSC but my code don't work as expected the switches are getting triggered without pressing ! or outputs just flips randomly. I have also tried implementing different touch pad designs with different gaps between them by thinking error was due to crosstalk but it didn't helped. So I believe there is a problem in my code.

Here is my code:

sbit AP0 at RA0_bit; //outputs
sbit AP1 at RA1_bit;
sbit AP2 at RA2_bit;
sbit AP3 at RA4_bit;

volatile bit SWP0,SWP1,SWP2,SWP3;//indicates switch was pressed
unsigned short Timer0_value=0;
unsigned short sensor_No=0;//This indicates the current cap sensor number which is being scanned
float Last_Frequency[4]={0,0,0,0};//this indicates last frequency count
unsigned long trip[4]={500,1090,1090,500};
float current_frequency=0;//this indicates current frequency count
bit first_Read;//this indicates that system has first started so Last_Frequency should hold value of no capacitive load. Nominal frequency.
///this also indicates that all sensor last frequency or nominal frequency is saved in array of Last_Frequency
unsigned short avg_count=0;//this indicates the current avg_count while averaging

void interrupt(){
if(PIR1.TMR1IF==1){
 Timer0_value=TMR0;
 TMR0=0;
 //firstly all sensors nominal frequencies will be stored. This state is indicated by first_Read bit
 if(first_Read==0){//Here Last_Frequency[sensor_No] will hold the nominal frequency(averaged)

  AP0=~AP0;
  AP1=~AP1;
  AP2=~AP2;
  AP3=~AP3;

  if(avg_count<31){//take 30 samples
  if(Last_Frequency[sensor_No]!=0){
  Last_Frequency[sensor_No]=Last_Frequency[sensor_No]+Timer0_value/0.0131072; //0.0131072 is period of Timer1 will interrupt which is used as a fixed timebase.
  }else Last_Frequency[sensor_No]=Timer0_value/0.0131072;
  avg_count++;
  }else {

    Last_frequency[sensor_No]=Last_frequency[sensor_No]/30;
    avg_count=0;
    sensor_No++;
    if(sensor_No>3){
    sensor_No=0;//reset cap sensor count
    first_Read=1;//all nominal frequencies are stored in Last_Frequency array
    AP0=0;
    AP1=0;
    AP2=0;
    AP3=0;
    }
    CPSCON1=sensor_No;
  }

 }else{

 if(avg_count<31){
 if(current_frequency!=0){
 current_frequency=current_frequency+Timer0_value/0.0131072;//get current frequency take 30 samples
  }else current_frequency=Timer0_value/0.0131072;
  avg_count++;

 }else{

 avg_count=0;
 current_frequency=current_frequency/30;//take average

    //Below current frequency is compared with stored nominal frequency of selected sensor
 if(current_frequency<(Last_Frequency[sensor_No]-trip[sensor_No])){//here 1000 is the calibrated value used to tune sensitivity of sensor according to material over sensor
  //button pressed
  switch(sensor_No){
   case 0: SWP0=1;break;
   case 1: SWP1=1;break;
   case 2: SWP2=1;break;
   case 3: SWP3=1;break;
  }
 }else if(current_frequency>(Last_Frequency[sensor_No]-trip[sensor_No]+194)){
  //button not pressed
   switch(sensor_No){
   case 0: SWP0=0;break;
   case 1: SWP1=0;break;
   case 2: SWP2=0;break;
   case 3: SWP3=0;break;
  }
 }

 //change sensor no as current sensor was scanned
 sensor_No++;
 current_frequency=0;//reset
 if(sensor_No>3)sensor_No=0;//reset
 CPSCON1=sensor_No;
}

}
 TMR1L=0;
 TMR1H=0;
 TMR0=0;
 PIR1.TMR1IF=0;
 }else {
 TMR1L=0;
 TMR1H=0;
 TMR0=0;
 PIR1.TMR1IF=0;
 }
 }

 void main() {

 TRISA=0x00;
 ANSELA=0x00;
 SWP0=0;//Switch is not pressed
 SWP1=0;//Switch is not pressed
 SWP2=0;//Switch is not pressed
 SWP3=0;//Switch is not pressed

 first_Read=0;//No first read has done.

 //reset all outputs
 AP0=0;
 AP1=0;
 AP2=0;
 AP3=0;

 //Enable Capacitive sensing module
 CPSCON0.CPSON=1;
 CPSCON0.CPSRNG1=0;
 CPSCON0.CPSRNG0=1;
 CPSCON0.T0XCS=1;
 OPTION_REG.T0CS=1;

 CPSCON1=0x00;//Enable CPS0 channel.at RB0

 TRISB=0x00;
 TRISB.B0=1; //set RB0 as input as it is capacitive input.
 TRISB.B1=1;
 TRISB.B2=1;
 TRISB.B3=1;
 ANSELB=0x00;
 ANSELB.B0=1;
 ANSELB.B1=1;
 ANSELB.B2=1;
 ANSELB.B3=1;


 //Initialize Timer1 for interrupts to scan cap sensors
 TMR1IE_bit=1;
 PEIE_bit=1;
 GIE_bit=1;
 TMR1IF_bit=0;
 // Timer1 Registers: Prescaler=1:1; TMR1 Preset=0; Freq=76.29395Hz; Period=0.0131072 s
 T1CON.T1CKPS1 = 0;  // bits 5-4  Prescaler Rate Select bits
 T1CON.T1CKPS0 = 0;  // bit 4
 T1CON.T1OSCEN = 0;  // bit 3 Timer1 Oscillator Enable Control: bit 1=on
 T1CON.T1SYNC  = 1;  // bit 2 Timer1 External Clock Input Synchronization 
 Control bit:1=Do not synchronize external clock input
 T1CON.TMR1CS0 = 0;  // Timer 1 clock source is FOSC and not FOSC/4
 T1CON.TMR1CS1 = 0;  // Timer 1 clock source is FOSC and not FOSC/4
 T1CON.TMR1ON  = 1;  // bit 0 enables timer
 TMR1H = 0;         // preset for timer1 MSB register
 TMR1L = 0;         // preset for timer1 LSB register
 TMR0=0;

 while(1){

 ///below for each SWPx bit that respective AP(toggle its state)
 if(SWP0){
 AP0=~AP0;
 SWP0=0;//reset this flag
 }

 if(SWP1){
 AP1=~AP1;
 SWP1=0;//reset this flag
 }

 if(SWP2){
 AP2=~AP2;
 SWP2=0;//reset this flag
 }

 if(SWP3){
  AP3=~AP3;
  SWP3=0;//reset this flag
 }

};

}

So where am I making mistake? Thanks for your help!


Sign In or Register to comment.