A general-purpose input/output (GPIO) is a generic pin on an integrated circuit whose behavior-whether it is an input or output pin-is controllable by the user at run time.

A standard GPIO can be used for the following purposes:

  • Reading from switches.

  • Reading from sensors such as IR, liquid level.

  • Writing output to LEDs for status, relays, etc.

The ConnectCore 8M Mini has several GPIO interfaces; you can find more information in the ConnectCore 8M Mini Hardware Reference Manual.

Digi adds to Android an API to manage these GPIO interfaces. You can configure them, read and set values, and listen for state changes. In the Digi APIx javadoc you can find a complete list of the available methods in this API.

Unless noted, all GPIO API methods require the com.digi.android.permission.GPIO permission.

If your application does not have the com.digi.android.permission.GPIO permission it will not have access to any GPIO service feature.

First of all, a new GPIOManager object must be instantiated by passing the Android Application Context.

Instantiating the GPIOManager
import android.app.Activity;
import android.os.Bundle;

import com.digi.android.gpio.GPIOManager;

public class GPIOSampleActivity extends Activity {

    GPIOManager gpioManager;

    [...]

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Instantiate the GPIO manager object.
        gpioManager = new GPIOManager(this);

        [...]
    }

    [...]
}

Instantiate a GPIO

The GPIOManager allows you to create a GPIO object for a specific GPIO interface. You can create it with one of the following methods:

Method Description

createGPIO(int, GPIOMode)

Creates and returns a GPIO object with the given kernel number, configuring it with the given mode.

createGPIO(int, int, GPIOMode)

Creates and returns a GPIO object with the given port index and pin index, configuring it with the given mode.

Both methods may fail for the following reasons:

  • If there is an error creating the GPIO, throwing a GPIOException.

  • If kernel number, port index or pin index is less than 0, throwing an IllegalArgumentException.

  • If mode is null, throwing a NullPointerException.

The GPIOMode enumeration contains all the possible modes a GPIO can be configured:

  • INPUT: the GPIO is used as input.

  • OUTPUT_HIGH: the GPIO is used as output and the output level is set high.

  • OUTPUT_LOW: the GPIO is used as output and the output level is set low.

  • INTERRUPT_EDGE_RISING: the GPIO is used as an interrupt on rising edge.

  • INTERRUPT_EDGE_FALLING: the GPIO is used as an interrupt on falling edge.

  • INTERRUPT_EDGE_BOTH: the GPIO is used as an interrupt on both rising and falling edges.

Once you have created the GPIO, you can read or set its mode using the getMode() and setMode(GPIOMode) methods.

Creating a GPIO
import com.digi.android.gpio.GPIO;
import com.digi.android.gpio.GPIOManager;
import com.digi.android.gpio.GPIOMode;

[...]

GPIOManager gpioManager = ...;

// Create a GPIO object for GPIO with kernel number 34 as output low.
GPIO gpio = gpioManager.createGPIO(34, GPIOMode.OUTPUT_LOW);

[...]

Read and set the GPIO value

The GPIO class offers two methods to read and set the GPIO value:

Method Description

getValue()

Retrieves the value of the GPIO. Only has effect if GPIO mode is INPUT, INTERRUPT_EDGE_RISING, INTERRUPT_EDGE_FALLING or INTERRUPT_EDGE_BOTH.

setValue(GPIOValue)

Sets the GPIO value. Only has effect if GPIO mode is OUTPUT_HIGH or OUTPUT_LOW.

The getValue() method may fail if there is an error reading the GPIO value, throwing a GPIOException.

The setValue(GPIOValue) method may fail for the following reasons:

  • If there is an error setting the value, throwing a GPIOException.

  • If the value is null, throwing a NullPointerException.

The GPIOValue enumeration contains the following elements:

  • HIGH: the GPIO value is high.

  • LOW: the GPIO value is low.

Reading and setting the GPIO value
import com.digi.android.gpio.GPIO;
import com.digi.android.gpio.GPIOManager;
import com.digi.android.gpio.GPIOMode;
import com.digi.android.gpio.GPIOValue;

[...]

GPIOManager manager = ...;

GPIO inputGPIO = manager.createGPIO(37, GPIOMode.INPUT);
GPIO outputGPIO = manager.createGPIO(34, GPIOMode.OUTPUT_HIGH);

// Read the value of the GPIO configured as input.
GPIOValue value = inputGPIO.getValue();
System.out.println("GPIO value is: " + value.getDescription());

// Set to LOW the GPIO configured as output.
outputGPIO.setValue(GPIOValue.LOW);

[...]

Detect GPIO interruptions

When a GPIO is configured as INTERRUPT_EDGE_RISING, INTERRUPT_EDGE_FALLING or INTERRUPT_EDGE_BOTH, you can register a listener and be notified when its value changes. To do so, you have to subscribe a IGPIOListener to the GPIO object by using the registerListener(IGPIOListener) method.

Registering the GPIO listener
import com.digi.android.gpio.GPIO;
import com.digi.android.gpio.GPIOManager;
import com.digi.android.gpio.GPIOMode;

[...]

GPIOManager gpioManager = ...;

// Create GPIO object for kernel number 37.
GPIO gpio = gpioManager.createGPIO(37, GPIOMode.INTERRUPT_EDGE_BOTH);

// Create the listener.
MyGPIOListener listener = ...;

// Register the GPIO listener.
gpio.registerListener(listener);

[...]

The registered listener class, MyGPIOListener, must implement the IGPIOListener interface. This interface defines the valueChanged(GPIOValue) method, which is called whenever the value of the GPIO changes.

IGPIOListener implementation example, MyGPIOListener
import com.digi.android.gpio.IGPIOListener;

public class MyGPIOListener implements IGPIOListener {
    @Override
    public void valueChanged(GPIOValue value) {
        // This code will be executed every time the GPIO value changes.
        System.out.println("New GPIO value: " + value);
    }
}

Note that it is possible to have more than one IGPIOListener waiting for updates in the same GPIO. If you no longer wish to receive GPIO value updates in a determined listener, use the unregisterListener(IGPIOListener) method to unsubscribe an already registered listener.

You can also configure the polling rate, that is, the amount of milliseconds between checks for changes in the GPIO value. By default, it is configured to 100 milliseconds, but you can change it by using the setPollingRate(int) method or read it with the getPollingRate() method.

GPIO example

The GPIO Sample Application demonstrates the usage of the GPIO API. In this example, one GPIO is configured as input and another as output. You can press the virtual button to switch on and off the User 0 LED corresponding to the output GPIO.

You can import the example using Digi’s Android Studio plugin. For more information, see Import a Digi sample application. To look at the application source code, go to the GitHub repository.