4 button touch switch

Thread Starter

PIYUSH SONI

Joined Nov 15, 2013
32
Hi, Guys. I am working on touch button using capsense module of pic mcu- 16f1827 with internal frequency= 8MHz. Actually i have written the code & tested in my pcb using breadboard. I have taken input in port A & output at port B connecting 4 led.Now if am touching I/P button then it's corresponding Led is glowing continously. But i want it to work as switch so that if touch the button again then it's LED must swich off. I am posting my code which i have written in MikroCpro for pic & build it through pickit3.

Please Help me out to SWITCH OFF the led when i touch the button again. Simply i want it to work as a normal switch . Also if u want more info then ask me...

Rich (BB code):
 // function declerations
void init(void);
void flag_set();
//void flag_reset();
switch_off;
void interrupt () ;//ISR(void);
long GetPercent(void);
 // defines
#define _XTAL_FREQ 8MHz
#define PCT_ON 12 // percentge for press

// __CONFIG(FOSC_INTOSC & WDTE_OFF & MCLRE_ON & CP_OFF & PWRTE_OFF);
 // globals
// variables for calculations
 char const1 = 0,const2 =1,const3 = 2,const4 = 3;
unsigned int Average[4] = {0,0,0,0};
unsigned int Raw =0;
 unsigned int index = 0; // index to cycle through switches
unsigned int StartCount = 252;
long Percent;
bit flag0,flag1,flag2,flag3;
 // preset values for MUX Comp channels in registers
//  index       00    01   02 03
char CPSCH[4] = {0x00, 0x01, 0x02, 0x03};
 void main(void)
{
flag0 = 0;
flag1 = 0;
flag2 = 0;
flag3 = 0;

 init();
 flag_set();


   }// end main


 //Main Interrupt Service Routine (ISR)
void interrupt () // ISR(void)
  {
  if(T0IE && T0IF)

  T1CON.TMR1ON = 0; // turn off timer 1, check if turn on resets
  // get raw reading for index
  Raw = TMR1L + (TMR1H << 8);
  // do 252 loops through average calc to set a start average for
  // each button


   if(StartCount > 0)
  {
   StartCount--; // decrement for loop
   // do startup average calcs
   Average[index] = ((Average[index]/16)*15) + (Raw/16);
   // set for next button
   if(index < 3)
    {index++;}
   else
    {index = 0;}
  }else {


   Percent = GetPercent();
   // test raw to average minus trip ammount
   switch_on:
   if(Percent > PCT_ON)
   {



    switch(index)
    {
     case 0:
     {
      LATB.F0 = 1;
      flag0 = 1;
      break;
     }
     case 1:
     {
      LATB.F1 = 1;
      flag1 = 1;
      break;
     }
     case 2:
     {
      LATB.F2 = 1;
      flag2 = 1;
      break;
     }
     case 3:
     {
      LATB.F3 = 1;
      flag3 = 1;
      break;
     }
     default:
      break;
    }

   }


 if(Percent < PCT_ON)
   //Delay_ms(500);
    {
    switch(index)
    {
     case 0:
     {
      LATB.F0 = 0;
      break;
     }
     case 1:
     {
      LATB.F1 = 0;
      break;
     }
     case 2:
     {
      LATB.F2 = 0;
      break;
     }
     case 3:
     {
      LATB.F3 = 0;
      break;
     }
     default:
      break;
    }
    // calc average while not pressed
    Average[index] = ((Average[index]/16)*15) + (Raw/16);
   }

   if(index < 3)
    index++;
   else
    index = 0;
  }

  // set for next button on MUX
  CPSCON1 = CPSCH[index];
  // restart Timers for next calc
  TMR1L = 0; // clear timer 1 low
  TMR1H = 0; // clear timer 1 high
  T1CON.TMR1ON = 1; // turn timer 1 on
  TMR0 = 0; // clear Timer 0
  INTCON.TMR0IF = 0; // reset interupt flag


 } // end TMR0 interupt
    // end ISR
 void init(void)
{
 OPTION_REG = 0b00000101; // WPU disabled, TMR0 Fosc/4, Pre Scale 128
 OSCCON = 0b01111000; // 4mhz
 ANSELA = 0b00011111;
 ANSELB = 0x00;
 TRISB = 0b00000000;
 TRISA = 0b0001111;
 LATA = 0;
 LATB = 0;
 // set up voltage references
 // FVR = 4.096v, DAC = 0.9375v
 FVRCON = 0b10001100; // FVREN enabled, CDAFVR 4.096v, No ADFVR, No Temp sense.
 DACCON1 = 0b00001110; // VOUT = ((VSRC+) - (VSRC-))*(DACR<4:0>/(25)) + VSRC- = (5 - 0) * (16 / 32) - 0; = 1.29v
 DACCON0 = 0b10000000; // DAC on, VDD as + Ref, VSS as - Ref
 // set up cap sense
 CPSCON0 = 0b11001100; // CPS on, CPS High range FVR/DAC, 100ua
 CPSCON1 = CPSCH[index]; // channel to RA0 at start
 // set up timers
 INTCON.TMR0IE = 1;
 T1CON = 0b11000001;
 INTCON.GIE = 1;

}

 // Calculates Percent difference between Raw and Average
long GetPercent(void){
 // do initial calc
 Percent = ((long)Average[index] - (long)Raw);
 // test if above zero, if below = 0
 if(Percent < 0){
       Percent = 0;
 }else{
      Percent = Percent*100;
      Percent = Percent / Average[index];
 }
      return Percent;
}


void flag_set()
{
while(1){
if(flag0)

{
LATB.F0 = 1;

}


if(flag1)


{
LATB.F1=1;

}
if(flag2)
{
LATB.F2 =1;
}

if(flag3)

{
LATB.F3=1;
}
  }
   }
 

shteii01

Joined Feb 19, 2010
4,644
Use a counter variable. Initialize the variable as zero. When you touch first time, you check the variable, see that it is zero, increment it to one and execute instruction to turn led ON. When you touch second time, you check the variable, see that it is one, decrement it to zero and execute instruction to turn led OFF.
 

THE_RB

Joined Feb 11, 2008
5,438
Man, that is some nasty code for 4 buttons lighting 4 LEDs!

If your 4 buttons are on PORTA, and your 4 LEDs are on PORTB, you could replace all your code with this;

Rich (BB code):
TRISB = 0b00000000;
TRISA = 0b0001111;
while(1)
{
  PORTB = PORTA;
}
:)

Sorry that doesn't help you add the on/off switching feature you want to your code, but from my point of view you need to scrap ALL your code and start again anyway. It's a nasty mess.
 

Thread Starter

PIYUSH SONI

Joined Nov 15, 2013
32
:):):Thank you Guys, with your clue & my effort my project is completed.:):)
Still i have to modify my code & adding some extra features to it.
Can you give some ideas to modify it by adding extra features to my touch switch board.
 

THE_RB

Joined Feb 11, 2008
5,438
...
Can you give some ideas to modify it by adding extra features to my touch switch board.
If you feel like a challenge...

You could make it so if you press the button multiple times you can control brightness of the LED;
1 press = dim
2 press = medium
3 press = bright
long press = off
 
Top