Gpio

The Gpio class interacts with the general purposes I/O pins on the board. You can use these pins to connect external sensors to the board.

As this module does not have a built in sampling function for reading analog and digital data, you will need to use the Timer module to schedule these tasks.

Analog Data

Reading analog data is done with the readAnalogIn method. Data comes in two forms, an absolute reference voltage and an ADC value. The absolute reference voltage is reported in milli volts (mV) and the ADC value, being a ratiometric value, has no units. When constructing the data route, you need to select the pin and analog read mode the route is processing

import com.mbientlab.metawear.module.Gpio;
import com.mbientlab.metawear.module.Gpio.AnalogReadMode;

final byte GPIO_PIN= 0;

// Route data from adc reads on pin 0
final Gpio gpioModule= mwBoard.getModule(Gpio.class);
gpioModule.routeData().fromAnalogIn(GPIO_PIN, AnalogReadMode.ADC).stream("gpio_0_adc_stream")
    .commit().onComplete(new CompletionHandler<RouteManager>() {
        @Override
        public void success(RouteManager result) {
            result.subscribe("gpio_0_adc_stream", new RouteManager.MessageHandler() {
                @Override
                public void process(Message msg) {
                    Log.i("MainActivity", String.format("gpio 0 ADC: %d",
                            msg.getData(Short.class)));
                }
            });

            gpioModule.readAnalogIn(GPIO_PIN, AnalogReadMode.ADC);
        }
    });

Enhanced Analog Reads

Starting with firmware v1.2.3, additional features have been added to the analog read. To use these features, call initiateAnalogInRead instead and use the AnalogInParameterBuilder to configure the additional parameters. If none of these parameters are set, the initiateAnalogInRead function will behave identically to the old readAnalog function.

// Equivalent to gpioModule.readAnalogIn((byte) 0, Gpio.AnalogReadMode.ADC);
gpioModule.initiateAnalogInRead((byte) 0, Gpio.AnalogReadMode.ADC).commit();

Pullup and Pulldown Pins

Setting a pullup/pulldown pin will have the board automatically set the pull mode prior to reading the analog data. If unused, the pull modes will not be modified.

// Pull up pin 0 before reading pin 0
gpioModule.initiateAnalogInRead((byte) 0, Gpio.AnalogReadMode.ADC)
    .pullUpPin((byte) 0)
    .commit();

Delay

The delay parameter controls how long the firmware will wait after the pull mode is set before reading the data. The firmware will wait for up to 1 millisecond or it unused, immediately read the analog signal.

// wait 10 microseconds after pulling down pin 1 before reading pin 0
gpioModule.initiateAnalogInRead((byte) 0, Gpio.AnalogReadMode.ADC)
    .pullDownPin((byte) 1)
    .delay((short) 10)
    .commit();

Virtual Pins

Virtual pins are dummy GPIO pins that can be used to redirect the analog output to another pin. For example, you can assign a unique pin for each read configuration in your circuit which will send the data for the configurations to different message handlers. Keep in mind that when using virtual pins, the pin value for the analog input data route and the virtual pin setting must match.

// read data from pin 0, redirect output to pin 21
gpioModule.initiateAnalogInRead((byte) 0, Gpio.AnalogReadMode.ADC)
    .virtualPin((byte) 21)
    .commit();

// Build route for pin 21, not 0
gpioModule..routeData().fromAnalogIn((byte) 21, Gpio.AnalogReadMode.ADC).commit();

Digital Data

Reading digital input data is done with the readDigitalIn method. Data is reported as a 1 or 0. As per the product spec, a high state is between 2.1 and 3.0 volts and a low state is between 0 and 0.9 volts.

import com.mbientlab.metawear.module.Gpio;
import com.mbientlab.metawear.module.Gpio.*;

final byte GPIO_PIN= 1;
final Gpio gpioModule= mwBoard.getModule(Gpio.class);

// Set the pin to pull up the signal
gpioModule.setPinPullMode(GPIO_PIN, PullMode.PULL_UP)
// Route digital data from pin 1
gpioModule.routeData().fromDigitalIn(GPIO_PIN).stream("gpio_0_din_stream").commit()
    .onComplete(new CompletionHandler<RouteManager>() {
        @Override
        public void success(RouteManager result) {
            result.subscribe("gpio_0_din_stream", new RouteManager.MessageHandler() {
                @Override
                public void process(Message msg) {
                    Log.i("MainActivity", String.format(Locale.US, "gpio 1 digital: %d",
                            message.getData(Byte.class)));
                }
            });

            gpioModule.readDigitalIn(GPIO_PIN);
        }
    });

Input Monitoring

A monitor can be attached to a GPIO input, alerting the user when the digital state changes. Users can configure the change type by calling setPinChangeType. Unlike reading GPIO data, pin monitoring has built in sampling, thus does not need to be used in conjunction with the Timer module. Monitoring is started by calling startPinChangeDetection and stopped with a call to stopPinChangeDetection.

The data reported is the new digital input state.

import com.mbientlab.metawear.module.Gpio;
import com.mbientlab.metawear.module.Gpio.*;

final byte GPIO_PIN= (byte) 2;
Gpio gpioModule= mwBoard.getModule(Gpio.class);
// Send alerts when pin 2 transitions from 1 -> 0
gpioModule.setPinChangeType(GPIO_PIN, PinChangeType.FALLIING);
// Route state change alerts from pin 2
gpioModule.routeData().fromGpioPinNotify(GPIO_PIN)
    .stream("gpio_2_notify_stream")
.commit().onComplete(new CompletionHandler<RouteManager>() {
    @Override
    public void success(RouteManager result) {
        result.subscribe("gpio_2_notify_stream", new RouteManager.MessageHandler() {
            @Override
            public void process(Message msg) {
                Log.i("MainActivity", String.format(Locale.US, "gpio 2 din: %d",
                        message.getData(Byte.class)));
            }
        });
        gpioModule.startPinChangeDetection(GPIO_PIN);
    }
});