C program a button to perform a task once when pressed (latch)

Marmstrong picture Marmstrong · Apr 30, 2013 · Viewed 35.9k times · Source

I am relatively new to c and the Raspberry Pi and am trying simple programs. What I would like is when the button is pressed it printfs once and doesn't printf again until the button is pressed again, even if the button is held down (sort of a latch). I thought maybe adding the second while loop in would fix this, but sometimes it still doesn't detect a button press.

#include <bcm2835.h>
#include <stdio.h>
#define PIN RPI_GPIO_P1_11

int main()
{
    if(!bcm2835_init())
        return 1;

    bcm2835_gpio_fsel(PIN, BCM2835_GPIO_FSEL_INPT);

    while(1)
    {
        if(bcm2835_gpio_lev(PIN))
        {
            printf("The button has been pressed\n");
        }

       while(bcm2835_gpio_lev(PIN)){}
    }

    bcm2835_close();
    return 0;
}

Answer

user529758 picture user529758 · Apr 30, 2013

Your logic is correct and this would work if buttons were perfect. But they aren't. You have to debounce the signal of the button. Two methods to achieve that (works best when combined):

I. Add a capacitor between the two pins of the button (or try an even more sophisticated button debouncer circuitry), and/or

II. use software debouncing (pseudo-C):

while (1) {
    while (!button_pressed)
        ;

    printf("Button pressed!\n");


    while (elapsed_time < offset)
        ;
}

etc.

Edit: as @jerry pointed out, the above doesn't work "correctly" when the button is held. Here are a couple of more professional code snippets you can use to meet all the requirements.