2

I made a board that attached a 1602 LCD and three buttons to the GPIO pins of the Pi. Now I need to write a software to go with it.

The software runs under Raspbian.

The software need to interrupt on the three pins, debounce it, and update the screen accordingly. How to create this event loop without hogging up the processor?

  • You need to specify your environment. Bare metal or under an operating system such as Linux? In either case I expect you'll be using a library to access the gpios. Check the library for callback support. – joan Jan 20 '15 at 21:04
  • You can access your GPIOs pins from sysfs. They kernel make them access through files. You can configure them and read, poll, write on those GPIO. Polling is the key to not hogging the CPU. – Xaqq Jan 20 '15 at 21:06
  • @joan I was hoping to use wiringPi but I need to "park" the main event loop somewhere. I used to have an MCU polling and debouncing the buttons so I can just wait on the SPI bus but now I got rid of the MCU so the Pi need to poll the buttons. – Maxthon Chan Jan 20 '15 at 21:22
  • If you use callbacks (now supported by wiringPi) your main loop can just be while(1) {sleep(1);} if you don't need to do anything else. – joan Jan 20 '15 at 21:40
1

As per the documentation in the kernel source tree, the language agnostic userspace interface in /sys/class/gpio allows for using poll() on open descriptors to these nodes ("language agnostic" here in the sense that you could use an equivalent from any language -- this isn't a C library or anything). This should be fine if you are just dealing with buttons. Beware those nodes are not normal files on disk (see here for some explanation and implications; you can skip down to the paragraph that begins, "Sysfs, a kernelspace subsystem...").

If you haven't used poll() or select() before, these are blocking (or time out-able) calls that return when data is available to read on one of a number of descriptors (and/or a descriptor is ready to receive more data). This is a common method of implementing callbacks/event-driven APIs.

1

You may be interested in the following. http://wiringpi.com/reference/priority-interrupts-and-threads/

I have used int wiringPiISR (int pin, int edgeType, void (*function)(void)) ; in some of my code, although I normally find polling meets most of my needs.

1

I made this a while ago to be an all-around, header-only solution for GPIO on the Pi. No libraries to install or anything like that. I use this in every project that needs GPIO. Even though this is C++ (11), it does have a useful implementation of the polling method. You can't specify a callback function though, the way it works is it simply doesn't return until it detects an interruption (so you might have to run this on multiple threads to handle multiple buttons). It doesn't deal with debouncing though, but that's not that hard to do (just simply check the value again after a couple of milliseconds). Here it is:

https://github.com/adam10603/raspberryPi_GPIO

Here's a quick sketch on how to use it:

auto myButton = GPIO::openGPIO(3, GPIO_INPUT);
while (true) {
    myButton->waitForEdge(GPIO_EDGE_RISING);
    cout << "Button pressed!" << endl;
}

This would print out "Button pressed!" every time you push the button. It's very simple, this is all the code you need for it (other than including the header file of course).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.