Raspberry Pi GPIO Input Events

Aight, first post! That’s pretty cool.

So today I wanted to write about RasPi rising and falling events. If you don’t know what that means don’t worry — I’ll explain it.


So first I want to describe some terminology I’ll be using for these tutorials. Yes, they’re pretty easy (especially if you’re already experienced with the Raspberry Pi and Python)

GPIO: General Purpose Input/Output

It’s what it’s sounds like. These are the “prongs” on the RasPi that you connect wires to (or a cobbler if you’re lucky enough to have one already). It’s “general purpose” because it‘s controllable by the user at run time. As the name suggests, they allow for both input and output.

Event Handler:

A callback routine that is “fired” (AKA activated or called) when specific input is received by a program (the actual event). This tutorial will include how current is received by the RasPi and is interpreted by Python.


How Amperes are Seen by the Computer

Courtesy of http://tex.stackexchange.com/

So first off, there’s a difference between amps and voltage. I’ll go through those really quickly.

Amperes (Amps):

Measurement of the flow of electricity.

Volts:

Basic measurement of electric force. It’s the amount of force that is required to push one amp through a wire.

So in short:

  • Amps are the electricity coming through a wire
  • Volts are the force of the electricity (it’s the unit that measures current!)

So if you were to look at the above chart, it’s measured in amps. It’s the electricity coming to the RasPi.

So Why is This Important?

It’s how events are fired. Events are one of two things: rising or falling.

Rising events are when the line on the amp graph go upwards to form a square.

Falling is the exact opposite as rising. It’s when the line on the amp graph go downwards to finish the square.

This is best explained by this image:

Same as the first image, but I photo-shopped arrows on to it. Credit to it’s original owners ‘n stuff.

As you can see, the up arrows represent rising current, and the the down arrows represent falling current.

When the arrow goes up, there’s an event to call that. The same applies to the arrow going down.

Remember, when a circuit is connected via a button or a switch, the current falls (this is because it connects to ground). In this sense, you would use these events to detect a button push more efficiently than a while loop.


Setting the Pins

Finally, the good stuff.

Let’s setup the basic imports for our project.

import RPi.GPIO as GPIO
input_pin = 2
GPIO.setmode(GPIO.BCM)
GPIO.setup(input_pin, G.IN, pull_up_down=GPIO.PUD_UP)

So the pin we’re using is pin #2 for GPIO.BCM, AKA pin #3 for GPIO.BOARD.

So you might be wondering “what the heck is that “pull_up_down” argument in the setup method”. Basically, it sets whether the internal pull up or pull down resistor internal to the RasPi is active or not. We need them because when a button is not down, the current is considered “floating” and therefore unpredictable.

“But what’s the difference between a pull up and a pull down resistor?”

What they both do:

They both prevent the button returning it’s state as low or “open-gate”, as we want the button to return either high or low. When the circuit is closed, it returns 0. When the circuit is open, it returns 1.

Pull up resistors:

They’re put in between power (+V) and a signal (the button).

Pull down resistors:

They’re put in between power (+V) and ground (-V).


Finally, the Event Detection

First things first, define a function that will be called when the event is detected. This function is called a“callback”. It needs at least one argument, and the first argument is used by the event detector to call it. The name doesn’t matter.

def my_function_to_be_called(channel):
print("I was called!")

Now, we use the “add_event_detect()” function. I’ll explain the arguments.

It’s in the format of “GPIO.add_event_detect(your_port, falling/rising, callback=callback_function, bouncetime=debounce_wait)”, with the “debounce_wait” being the time in milliseconds where another button press will be ignored. It’s used to prevent bouncing.

For example, if I wanted to detect input on the 2nd pin, see if it’s falling, call a function called “my_function”, then wait 200 milliseconds before another button is worth anything, i’d type:

GPIO.add_event_detect(2, G.FALLING, callback=my_function, bouncetime=200)

Easy enough, right? If you think it’s too hard to memorize right now, don’t worry — It’ll become a habit.

The finished code should look like this:

import RPi.GPIO as GPIO
input_pin = 2
GPIO.setmode(GPIO.BCM)
GPIO.setup(input_pin, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
def my_function(channel):
print("I was called!")
GPIO.add_event_detect(input_pin, GPIO.FALLING, callback=my_function, bouncetime=200)

Congrats! You successfully used your first GPIO input event!