Press on press off latch

Discussion in 'Embedded Systems and Microcontrollers' started by Dawud Beale, Jun 24, 2013.

  1. Dawud Beale

    Thread Starter Member

    Feb 10, 2012
    275
    7
    I am using a push button to control something on a PIC16F887 but as soon as I let go of the button it reverse back. If I have a variable called switch, how to I toggle it between 1 and 0 each time RB0 is triggered? I need some sort of latch in C
     
  2. djsfantasi

    AAC Fanatic!

    Apr 11, 2010
    2,812
    834
    Depends on the type of variable "switch" is defined as. I am not familiar with C conventions, but something like the following will work with logical variables:
    Switch = ! Switch
    Or mathematically, you can use the following equation if you have the absolute value function available :
    Switch = | Switch - 1 |
     
  3. t06afre

    AAC Fanatic!

    May 11, 2009
    5,939
    1,222
    Use som variable that is changed each time the button is pressed. Then let this variable controll the direction. Given that then RB0 button goes high then pressed. I think this pseudo code will do the trick. You have to code it proper by your self
    Code ( (Unknown Language)):
    1.  
    2.  char dir_var
    3.  if (RB0)
    4.     {
    5.        dir_var=!dir_var//flip the dir_var variable
    6.         while(RB0)// wait and do nothing until the button is released
    7.       }
    8.        //Check the dir_var variable
    9.        //in code to find out which
    10.        // way to rotate
    11.        if(dir_var)
    12.           {
    13.            //rotate left
    14.             }
    15.       if(!dir_var)
    16.           {
    17.            //rotate right
    18.             }
    19.  
     
    Dawud Beale likes this.
  4. t06afre

    AAC Fanatic!

    May 11, 2009
    5,939
    1,222
    I also found out that the RB0 pin, is also the interrupt pin on your MCU. And I am quite sure the interrupt pin can be set up to be edge trigged.
     
  5. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,395
    1,607
    An interrupt is probably one of the worst ways to sense a physical switch as it is just TOO FAST. Switches have a bounce,so when you press them they give multiple change signals, which fire multiple interrupts.

    Now I happen to typically use an interrupt to sense my push buttons, but the ISR is called off a timer because I sample the buttons at a slow rate (10-25 ms), and make sure I get 2 readings the same before I declare it as a change.

    To toggle a pin needs code of a form such as this:
    Code ( (Unknown Language)):
    1.     while(1)
    2.     {
    3.         while(button == OFF);
    4.         while(button == ON) Pin = 1 ;
    5.         while(button == OFF);
    6.         while(button == ON) Pin = 0 ;
    7.     }
    Do note the 4 internal while loops trap the program when the button is either not pressed or pressed. That keeps the pin from either continuously changing or releasing with the button.

    Also note *real* code would have other functions, but that's how a button test loop could work.
     
    absf likes this.
  6. Dawud Beale

    Thread Starter Member

    Feb 10, 2012
    275
    7
    Ok I attempted a latch. Its kinda working, but for some reason there is a problem with the do while loop. The LED keeps moving back and forth between two positions whilst the button is pushed down when I thought it would just either free or keep going in one direction

    Code ( (Unknown Language)):
    1. /*
    2.  * File:   Lab4inC.c
    3.  * Author: Dawud Beale
    4.  *
    5.  * Created on 18 June 2013, 20:45
    6.  */
    7.  
    8.  
    9. #include <xc.h>
    10. #define _XTAL_FREQ 8000000 //Using 8MHz clock speed
    11.  
    12. void main(void)
    13. {
    14.  
    15. //Declaring and Defining Variables
    16.  
    17. char Blink;
    18. char Counter;
    19. char Switch;
    20.  
    21. Blink = 0x01;
    22. Counter = 0x00;
    23. Switch = 0x00;
    24.  
    25. //Configuring the Input and Output Ports
    26.  
    27.  
    28. PORTD = Blink;
    29. ANSELH = 0b00000000;
    30. ANSEL = 0b00000000;
    31. TRISD = 0x00;
    32. TRISB = 0b11111111;
    33. TRISA = 0b11111111;
    34.  
    35. //main program
    36.  
    37.     while(1)
    38.     {
    39.         //Stimulus Dependant Rotating Bit
    40.         //Bit shifting left
    41.     if(!Switch)
    42.         {
    43.  
    44.             if(!RB0)
    45.             {
    46.                 __delay_ms(250); // request a delay
    47.  
    48.                 if(!RB0)
    49.                 {
    50.                 Switch = !Switch;
    51.                 do{ __delay_ms(25); }
    52.                 while(RB0=0);
    53.                 }
    54.             }
    55.  
    56.  
    57.             if(Counter<7)
    58.             {
    59.                 Blink = Blink << 1; //
    60.                                 PORTD=Blink;
    61.                                 __delay_ms(250); // request a delay
    62.                 Counter++ ;
    63.                 //CLRWDT();
    64.             }
    65.  
    66.             else
    67.             {
    68.                 Blink = 0x01;   //
    69.                                 PORTD=Blink;
    70.                                 __delay_ms(250); // request a delay
    71.                 Counter = 0x00;
    72.                 //CLRWDT();
    73.             }
    74.         }
    75.  
    76. //Bit shifting right
    77.  
    78.     if(Switch)
    79.         {
    80.  
    81.             if(!RB0)
    82.             {
    83.                 __delay_ms(250); // request a delay
    84.  
    85.                 if(!RB0)
    86.                 {
    87.                 Switch = !Switch;
    88.                 do{ __delay_ms(250); }
    89.                 while(RB0=0);
    90.                 }
    91.             }
    92.             if(Counter>0)
    93.             {
    94.                 Blink = Blink >> 1; //
    95.                                 PORTD=Blink;
    96.                                 __delay_ms(250); // request a delay
    97.                 Counter = Counter - 1 ;
    98.                 //CLRWDT();
    99.             }
    100.  
    101.             else
    102.             {
    103.                 Blink = 0x80;   //
    104.                                 PORTD=Blink;
    105.                                 __delay_ms(250); // request a delay
    106.                 Counter = 0x07;
    107.                 //CLRWDT();
    108.             }
    109.         }
    110.  
    111.     }
    112. }
     
  7. Dawud Beale

    Thread Starter Member

    Feb 10, 2012
    275
    7
    Actually its ok, all I needed to do was have two equals signs.

    Ok so project finished, thank you very much for your help everyone, I learned a lot from it and had fun. I hope I can get involved in some online projects with others to learn more as my knowledge grows.

    Thanks and best wishes everyone
     
    ErnieM likes this.
Loading...