Working with GPIO

The reactive PI library contains a set of components that you can use to access the GPIO port on your raspberry PI. This guide describes how to use the GPIO class and its companions to work with the GPIO port.

Getting started

Basic operation of input and output pins on your Raspberry PI can be done by creating a new GPIO input or output pin instance. The following sample demonstrates the use of both:

val input = GPIODevice.input(7)
val output = GPIODevice.output(13)

val x = input.read()
output.write(x)

Opening and closing ports

When not working with actors you are responsible for opening and closing access to GPIO pins yourself. It is important to call close() on the input and output pins it leaves the Raspberry PI in an undefined state. Restarting the device is necessary in this case.

Working with actors

To start using the GPIO port through Akka actors, you either have to create a new input or output actor in your application. The following sample demonstrates both:

import akka.actor.Actor
import reactivepi.GPIO

class GPIOSamples extends Actor {
  val input = GPIO.input(1)
  val output = GPIO.output(2)

  input ! GPIO.Read

  def receive = {
    case GPIO.Data(val) => output ! GPIO.Write(val)
  }
}

object GPIOSamplesApplication extends App {
  implicit val actorSystem = ActorSystem("gpio-controller")
  val actor = actorSystem.actorOf(Props(new GPIOSamples()))
}

This sample reads from the input by sending a GPIO.Read message to the input pin. When the input pin has actually read the value it will send it back to the original actor (GPIOSamples). The actor will then send a new GPIO.Write message to the output pin.

Subscribing to an input port

You can read from an input port explicitly. There's also the option to subscribe to an input. This will enable a more event driven experience. To subscribe to an input pin use the following code:

import akka.actor.Actor
import reactivepi.GPIO

class GPIOSubscription extends Actor {
  val input = GPIO.subscribe(3, self)
  val output = GPIO.output(4)

  def receive = {
    case GPIO.Data(val) => output ! GPIO.Write(val)
  }
}

object GPIOSamplesApplication extends App {
  implicit val actorSystem = ActorSystem("gpio-controller")
  val actor = actorSystem.actorOf(Props(new GPIOSubscription()))
}

Every time the input changes, the input actor will automatically send a GPIO.Data message to the GPIOSubscription actor, which will in turn send a GPIO.Write message to the output.

Opening and closing ports when using actors

When using the actors API you don't need to open or close GPIO ports. When you invoke the GPIO.input, GPIO.output or GPIO.subscribe methods the port you want to access is automatically opened for you. When you stop the actor that you got when you invoked one of the methods on the GPIO component, the port you were using before is automatically closed for you.

Want to know more?

There's some general information on the GPIO driver contained in the Raspbian distribution of Linux on the kernel pages. Check this URL for more info: https://www.kernel.org/doc/Documentation/gpio/sysfs.txt

Comments

comments powered by Disqus