Press on press off latch

Thread Starter

David_Baratheon

Joined Feb 10, 2012
285
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
 

djsfantasi

Joined Apr 11, 2010
9,163
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 |
 

t06afre

Joined May 11, 2009
5,934
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
Rich (BB code):
 char dir_var
 if (RB0)
    {
       dir_var=!dir_var//flip the dir_var variable
        while(RB0)// wait and do nothing until the button is released
      }
       //Check the dir_var variable
       //in code to find out which
       // way to rotate
       if(dir_var)
          {
           //rotate left
            }
      if(!dir_var)
          {
           //rotate right
            }
 

t06afre

Joined May 11, 2009
5,934
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.
 

ErnieM

Joined Apr 24, 2011
8,377
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:
Rich (BB code):
    while(1)
    {
        while(button == OFF);
        while(button == ON) Pin = 1 ;
        while(button == OFF);
        while(button == ON) Pin = 0 ;
    }
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.
 

Thread Starter

David_Baratheon

Joined Feb 10, 2012
285
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

Rich (BB code):
/*
* File:   Lab4inC.c
* Author: David Baratheon
*
* Created on 18 June 2013, 20:45
*/


#include <xc.h>
#define _XTAL_FREQ 8000000 //Using 8MHz clock speed

void main(void)
{

//Declaring and Defining Variables

char Blink;
char Counter;
char Switch;

Blink = 0x01;
Counter = 0x00;
Switch = 0x00;

//Configuring the Input and Output Ports


PORTD = Blink;
ANSELH = 0b00000000;
ANSEL = 0b00000000;
TRISD = 0x00;
TRISB = 0b11111111;
TRISA = 0b11111111;

//main program

    while(1)
    {
        //Stimulus Dependant Rotating Bit
        //Bit shifting left
    if(!Switch)
        {

            if(!RB0)
            {
                __delay_ms(250); // request a delay

                if(!RB0)
                {
                Switch = !Switch;
                do{ __delay_ms(25); }
                while(RB0=0);
                }
            }


            if(Counter<7)
            {
                Blink = Blink << 1;    //
                                PORTD=Blink;
                                __delay_ms(250); // request a delay
                Counter++ ;
                //CLRWDT();
            }

            else
            {
                Blink = 0x01;    //
                                PORTD=Blink;
                                __delay_ms(250); // request a delay
                Counter = 0x00;
                //CLRWDT();
            }
        }

//Bit shifting right

    if(Switch)
        {

            if(!RB0)
            {
                __delay_ms(250); // request a delay

                if(!RB0)
                {
                Switch = !Switch;
                do{ __delay_ms(250); }
                while(RB0=0);
                }
            }
            if(Counter>0)
            {
                Blink = Blink >> 1;    //
                                PORTD=Blink;
                                __delay_ms(250); // request a delay
                Counter = Counter - 1 ;
                //CLRWDT();
            }

            else
            {
                Blink = 0x80;    //
                                PORTD=Blink;
                                __delay_ms(250); // request a delay
                Counter = 0x07;
                //CLRWDT();
            }
        }

    }
}
 
Last edited:

Thread Starter

David_Baratheon

Joined Feb 10, 2012
285
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
 
Top