4 button touch switch

Discussion in 'Embedded Systems and Microcontrollers' started by PIYUSH SONI, Mar 17, 2014.

  1. PIYUSH SONI

    Thread Starter Member

    Nov 15, 2013
    32
    1
    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...

    Code ( (Unknown Language)):
    1.  
    2.  // function declerations
    3. void init(void);
    4. void flag_set();
    5. //void flag_reset();
    6. switch_off;
    7. void interrupt () ;//ISR(void);
    8. long GetPercent(void);
    9.  // defines
    10. #define _XTAL_FREQ 8MHz
    11. #define PCT_ON 12 // percentge for press
    12.  
    13. // __CONFIG(FOSC_INTOSC & WDTE_OFF & MCLRE_ON & CP_OFF & PWRTE_OFF);
    14.  // globals
    15. // variables for calculations
    16.  char const1 = 0,const2 =1,const3 = 2,const4 = 3;
    17. unsigned int Average[4] = {0,0,0,0};
    18. unsigned int Raw =0;
    19.  unsigned int index = 0; // index to cycle through switches
    20. unsigned int StartCount = 252;
    21. long Percent;
    22. bit flag0,flag1,flag2,flag3;
    23.  // preset values for MUX Comp channels in registers
    24. //  index       00    01   02 03
    25. char CPSCH[4] = {0x00, 0x01, 0x02, 0x03};
    26.  void main(void)
    27. {
    28. flag0 = 0;
    29. flag1 = 0;
    30. flag2 = 0;
    31. flag3 = 0;
    32.  
    33.  init();
    34.  flag_set();
    35.  
    36.  
    37.    }// end main
    38.  
    39.  
    40.  //Main Interrupt Service Routine (ISR)
    41. void interrupt () // ISR(void)
    42.   {
    43.   if(T0IE && T0IF)
    44.  
    45.   T1CON.TMR1ON = 0; // turn off timer 1, check if turn on resets
    46.   // get raw reading for index
    47.   Raw = TMR1L + (TMR1H << 8);
    48.   // do 252 loops through average calc to set a start average for
    49.   // each button
    50.  
    51.  
    52.    if(StartCount > 0)
    53.   {
    54.    StartCount--; // decrement for loop
    55.    // do startup average calcs
    56.    Average[index] = ((Average[index]/16)*15) + (Raw/16);
    57.    // set for next button
    58.    if(index < 3)
    59.     {index++;}
    60.    else
    61.     {index = 0;}
    62.   }else {
    63.  
    64.  
    65.    Percent = GetPercent();
    66.    // test raw to average minus trip ammount
    67.    switch_on:
    68.    if(Percent > PCT_ON)
    69.    {
    70.  
    71.  
    72.  
    73.     switch(index)
    74.     {
    75.      case 0:
    76.      {
    77.       LATB.F0 = 1;
    78.       flag0 = 1;
    79.       break;
    80.      }
    81.      case 1:
    82.      {
    83.       LATB.F1 = 1;
    84.       flag1 = 1;
    85.       break;
    86.      }
    87.      case 2:
    88.      {
    89.       LATB.F2 = 1;
    90.       flag2 = 1;
    91.       break;
    92.      }
    93.      case 3:
    94.      {
    95.       LATB.F3 = 1;
    96.       flag3 = 1;
    97.       break;
    98.      }
    99.      default:
    100.       break;
    101.     }
    102.  
    103.    }
    104.  
    105.  
    106.  if(Percent < PCT_ON)
    107.    //Delay_ms(500);
    108.     {
    109.     switch(index)
    110.     {
    111.      case 0:
    112.      {
    113.       LATB.F0 = 0;
    114.       break;
    115.      }
    116.      case 1:
    117.      {
    118.       LATB.F1 = 0;
    119.       break;
    120.      }
    121.      case 2:
    122.      {
    123.       LATB.F2 = 0;
    124.       break;
    125.      }
    126.      case 3:
    127.      {
    128.       LATB.F3 = 0;
    129.       break;
    130.      }
    131.      default:
    132.       break;
    133.     }
    134.     // calc average while not pressed
    135.     Average[index] = ((Average[index]/16)*15) + (Raw/16);
    136.    }
    137.  
    138.    if(index < 3)
    139.     index++;
    140.    else
    141.     index = 0;
    142.   }
    143.  
    144.   // set for next button on MUX
    145.   CPSCON1 = CPSCH[index];
    146.   // restart Timers for next calc
    147.   TMR1L = 0; // clear timer 1 low
    148.   TMR1H = 0; // clear timer 1 high
    149.   T1CON.TMR1ON = 1; // turn timer 1 on
    150.   TMR0 = 0; // clear Timer 0
    151.   INTCON.TMR0IF = 0; // reset interupt flag
    152.  
    153.  
    154.  } // end TMR0 interupt
    155.     // end ISR
    156.  void init(void)
    157. {
    158.  OPTION_REG = 0b00000101; // WPU disabled, TMR0 Fosc/4, Pre Scale 128
    159.  OSCCON = 0b01111000; // 4mhz
    160.  ANSELA = 0b00011111;
    161.  ANSELB = 0x00;
    162.  TRISB = 0b00000000;
    163.  TRISA = 0b0001111;
    164.  LATA = 0;
    165.  LATB = 0;
    166.  // set up voltage references
    167.  // FVR = 4.096v, DAC = 0.9375v
    168.  FVRCON = 0b10001100; // FVREN enabled, CDAFVR 4.096v, No ADFVR, No Temp sense.
    169.  DACCON1 = 0b00001110; // VOUT = ((VSRC+) - (VSRC-))*(DACR<4:0>/(25)) + VSRC- = (5 - 0) * (16 / 32) - 0; = 1.29v
    170.  DACCON0 = 0b10000000; // DAC on, VDD as + Ref, VSS as - Ref
    171.  // set up cap sense
    172.  CPSCON0 = 0b11001100; // CPS on, CPS High range FVR/DAC, 100ua
    173.  CPSCON1 = CPSCH[index]; // channel to RA0 at start
    174.  // set up timers
    175.  INTCON.TMR0IE = 1;
    176.  T1CON = 0b11000001;
    177.  INTCON.GIE = 1;
    178.  
    179. }
    180.  
    181.  // Calculates Percent difference between Raw and Average
    182. long GetPercent(void){
    183.  // do initial calc
    184.  Percent = ((long)Average[index] - (long)Raw);
    185.  // test if above zero, if below = 0
    186.  if(Percent < 0){
    187.        Percent = 0;
    188.  }else{
    189.       Percent = Percent*100;
    190.       Percent = Percent / Average[index];
    191.  }
    192.       return Percent;
    193. }
    194.  
    195.  
    196. void flag_set()
    197. {
    198. while(1){
    199. if(flag0)
    200.  
    201. {
    202. LATB.F0 = 1;
    203.  
    204. }
    205.  
    206.  
    207. if(flag1)
    208.  
    209.  
    210. {
    211. LATB.F1=1;
    212.  
    213. }
    214. if(flag2)
    215. {
    216. LATB.F2 =1;
    217. }
    218.  
    219. if(flag3)
    220.  
    221. {
    222. LATB.F3=1;
    223. }
    224.   }
    225.    }
    226.  
     
  2. shteii01

    AAC Fanatic!

    Feb 19, 2010
    3,392
    497
    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.
     
  3. THE_RB

    AAC Fanatic!

    Feb 11, 2008
    5,435
    1,305
    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;

    Code ( (Unknown Language)):
    1.  
    2. TRISB = 0b00000000;
    3. TRISA = 0b0001111;
    4. while(1)
    5. {
    6.   PORTB = PORTA;
    7. }
    8.  
    :)

    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.
     
  4. PIYUSH SONI

    Thread Starter Member

    Nov 15, 2013
    32
    1
    Thankx RB for ur reply.
    So r u telling me to remove the switch case from my code?
     
  5. PIYUSH SONI

    Thread Starter Member

    Nov 15, 2013
    32
    1
    :):):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.
     
  6. jennifer01

    New Member

    Mar 18, 2014
    1
    0
    thanks your share
    [​IMG]
     
  7. THE_RB

    AAC Fanatic!

    Feb 11, 2008
    5,435
    1,305
    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
     
  8. PIYUSH SONI

    Thread Starter Member

    Nov 15, 2013
    32
    1
    Yes RB you are right. I will do that using PWM & it's a nice one.
    Thanx for ur suggestion.
     
Loading...