[ Raspberry Pi C ++ ] Push Buttons (Reading GPIO Input)

This post has been long overdue and will bring the GPIO tutorial to a close. We focus here on how to read input from external devices. This tutorial will keep things as basic as possible by using a simple push button.  

Previous Post: Our First LED


The push button used in this tutorial has four prongs/legs and looks as follows: 

Image of push Button
Example of a Push Button

Setup

Before we begin, there are two other components we require to complete our circuit… 1x 10kOhm resister and 1x 1kOhm resister 

The 1kOhm resister is simply used to dampen the voltage going from the 3.3V pin directly into the GPIO pin when the button is pressed.  

The 10kOhm resister plays a much more important role and is known as a “pull-down” resistor. It sits between an open (un-pressed) button and ground (GND). A pull-down resister is used to prevent erroneous reading from a GPIO pin on an open circuit. I would recommend to learn more about resistors.

A button in this un-pressed state (with a valid pull-down resister) will yield an input reading of 0 (LOW). 

Then when the button is pushed down, the voltage will flow from the 3.3V pin into the INPUT GPIO pin (whilst continuing through the 1kOhm resister) to give us a reading of 1 (HIGH).  

This is how your circuit should look: 

circuit diagram
Complete circuit diagram of push button with valid resistors

Code

The code for this example is very simple (even more so than lighting up our first LED)

#include <stdio.h>
#include <wiringPi.h>

int main(int argc, char** argv)
{
    // Intialize the wiringPi Library
    wiringPiSetup();

	const int INPUT_PIN = 12;
	
    // Read input on this pin
    pinMode(INPUT_PIN, INPUT);

    while(true)
    {
        // As soon as we dedect an input, log and quit.
        if(digitalRead(INPUT_PIN) == HIGH)
		{
			printf("Button is pressed!\n");	
			break;
		}
    }

    // Exit program
    return 0;
}
Reading GPIO Input with C++ and wiringPi

As always, see here on how to compile and run this code.

The code starts by flagging the pin to be used as an input. Later on we detect it’s reading via the digitalRead() function. This will return HIGH / LOW depending on the buttons pressed state.

The program will exit as soon as a HIGH input is received, shortly after printing that the button was pressed. The circuit between the GPIO pin and the 3.3V pin is compete when you press the button thus resulting in a HIGH read.

Earlier on in this post we talked about a pull-down resistor, and without it we may get erroneous reads through the GPIO pin.

I will leave this as a task to the reader, but I would suggest removing the pull-down resistor and tweaking the code to infinitely check the value of the input and see what happens.


Previous Post: Our First LED

[ Raspberry Pi C ++] GPIO Access : Compiling, Linking & Using WiringPi

Previous Post: Using CMake

Next Post: Our First LED


To allow us access to the GPIO pins of the Raspberry Pi in C++ code, we will use a library known as “WiringPi”. What is nice about this library is that the functions we call are similar to those found in the usual Python examples. This should hopefully make it easier for those coming from Python programming on the Raspberry Pi.

As stated in my overview of C++, third party code usually comes in the form of a shared/static library which you link into your projects code. This is the case for WiringPi!

To acquire the use of a third party library, you normally get it in the form of precompiled binaries or downloading and compiling the source code yourself. What “precompiled binaries” mean, is that someone else has compiled the source code on their Pi/machine and distributed the .a/.so (static/shared library) file via a download medium. Precompiled binaries are usually the go-to way of using libraries on Windows machines. In this example however, we will be download the WiringPi source code and compile it ourselves.

Compiling WiringPi

The first thing you want to do is download the WiringPi source code. To retrieve the latest working copy of Wiring Pi, we will use git to clone the repository. If you are unsure if git is installed, you can run the following:

> sudo apt-get install git

Once git is installed, clone the repository by entering the following

> git clone git://git.drogon.net/wiringPi

After a few seconds git will have finished downloading. If you list the contents of the current directory (“ls” command) you will notice a folder named “wiringPi”. Simply change into this directory.

> cd wiringPi

If you list the contents of this directory, there will be a lot of files. The one that we are most interested in is the “build” script. Upon running this script, the compilation of the library will begin and its binaries and header files will be automatically installed into the appropriate /usr/local folders on our system.

> ./build

You should see the words “all done.” at the end of the build process once the binaries are compiled and installed.

Linking WiringPi

When linking a third party library into your C++ project, you usually have to tell the compiler where to find the libraries header and binary files. Thankfully, the build script executed in the compilation process installed these files into our /usr/local/include and /usr/local/lib folders. What is special about these folders is that they are on the system PATH variable, this means that compilers will look for files here by default!

Although we don’t have to tell the compiler where to look, we still have to tell it what to link. Luckily, this is only a one liner with CMake! I have commented each command and highlighted the line which links the wiringPi library. Here is the contents of the complete CMake file (notice I have changed the executable and project name)

# Minimum CMake version required to generate
# our build system
cmake_minimum_required(VERSION 3.0)

# Name of our Project
project(MyProject)

# add_executable creates an executable with
# The given name.
add_executable(MyEXE main.cpp)

# Make sure the executable links to the wiringPi lib
target_link_libraries(MyEXE wiringPi)
CMakeLists.txt

And finally, the code to run to see if the build system will link, compile and run our code:

#include <stdio.h>
#include <wiringPi.h>

int main(int argc, char** argv)
{
    wiringPiSetup();

    printf("wiringPi is working!\n");

    return 0;
}
main.cpp

In the above code, we simply include the wiringPi’s declared functions using the include statement and we are calling the wiringPiSetup function.

To generate the make files, make sure you have a subdirectory called build and make it the working direcotry

> mkdir Build && cd Build

Genreate the makefiles using CMake

> cmake ..

Compile the code

> make

If all goes well, you should be able to execute the program via its executable name and see the line “wiringPi is working!” appear in your terminal.

> ./MyEXE

If you see this, then you are ready to get started with programming in C++ for the Raspberry Pi!

Using WiringPi

Now that we have our program successfully linking and compiling WiringPi, we can now look at preparing the GPIO pins for use in our projects.

If you have come across some of the Python GPIO examples for the Raspberry Pi, the usual procedure is to:

  1. Initialise the GPIO Library
  2. Setup the I/O mode on each GPIO pin you intend to use
  3. Set/Read the pins state dependant on the mode you initiated it as (i.e. input / output)

Luckily, WiringPi is no different! And we’ve already seen from the code above how we initialise the GPIO library.

Just as an example of the functions we will be using in future posts, here is some code (commented on each line) which will set the output & read input from the GPIO pins.

#include <stdio.h>
#include <wiringPi.h>

int main(int argc, char** argv)
{
    // Intialize the wiringPi Library
    wiringPiSetup();

    // Set the I/O state of the given pins
    pinMode(0, OUTPUT);
    pinMode(1, INPUT);

    // Turn pin 0 on then off
    digitalWrite(0, HIGH);
    digitalWrite(0, LOW);

    // Read input from pin 1
    int status = digitalRead(1);
    printf("Pin Input = %d\n", status);

    // Exit program
    return 0;
}
main.cpp

If you copy the above into your main.cpp file from earlier, and recompile the program you should see the line “pin input = 0” when executing. The status will be 0 until there is an input going into the pin… which we will look at when I get to push buttons 🙂

As a quick overall reminder, the full steps to generate your makefiles and compile your code is as follows (don’t execute the contents in brackets):

> cd Build (If not already in Build directory)
> cmake .. (If you have not yet generated makefile / added new files) 
> make     
> ./MyEXE

In the next post I will cover how to setup and make an LED flash using C++. If you want to give this a shot in the meantime though… Use the appropriate GPIO header table for your Pi and setup a GPIO pin in output mode to light up an LED.


Previous Post: Using CMake

Next Post: Our First LED