Gpio¶
All boards are equipped with general purpose I/O pins which can be used to connect additional sensors to the board. The GPIO pins are represented by the Pin interface and accessed through the Gpio interface.
import com.mbientlab.metawear.module.Gpio;
final Gpio gpio = board.getModule(Gpio.class);
Output Voltage¶
Gpio pins have an output voltage that can be set to ~3V or cleared to ~0V. Depending on how your sensor is connected to the gpio pins, you may need to set (setOutput) or clear (clearOutput) the output voltage with your app to complete the circuit as demonstrated with the optional heart rate sensor.
// output 0V on pin 1
gpio.pin((byte) 1).clearOutput();
Pull Mode¶
To ensure the voltage is within the acceptable ranges for digital states, the MetaWear has resistors that can pull the voltage up or down, set with the setPullMode method.
import com.mbientlab.metawear.module.Gpio.PullMode;
gpio.pin(byte) 2).setPullMode(PullMode.PULL_UP);
Analog Data¶
Analog data comes as either an ADC ratio (analogAdc) or absolute reference voltage (analogAbsRef). ADC values are unitless and are interpreted as a short value whereas the reference voltage is a float value in units of volts (V).
// Get producer for analog adc data
ForcedDataProducer adc = gpio.pin((byte) 0).analogAdc();
adc.addRouteAsync(new RouteBuilder() {
@Override
public void configure(RouteComponent source) {
source.stream(new Subscriber() {
@Override
public void apply(Data data, Object ... env) {
Log.i("MainActivity", "adc = " + data.value(Short.class));
}
});
}
});
Enhanced Analog Reads¶
Starting with firmware v1.2.3, additional features have been added to the analog read to accommodate more complex circuitry. Prior to performing the analog read, the firmware can pull up/down another pin and wait up to 1 millisecond between setting the pull mode and reading analog data. Furthermore, the analog data can be presented as data from another pin.
Call the variant read method
to use the enhanced read and
getVirtualPin to create Pin
objects
for handling data redirection.
ForcedDataProducer analogVoltage = gpio.pin((byte) 1).analogAbsRef();
analogVoltage.addRouteAsync(new RouteBuilder() {
@Override
public void configure(RouteComponent source) {
source.stream(null);
}
}).continueWithTask(new Continuation<Route, Task<Route>>() {
@Override
public Task<Route> then(Task<Route> task) throws Exception {
return gpio.getVirtualPin((byte) 0x15).addRouteAsync(new RouteBuilder() {
@Override
public void configure(RouteComponent source) {
source.stream(new Subscriber() {
@Override
public void apply(Data data, Object ... env) {
Log.i("MainActivity", "virtual pin voltage = " + data.value(Short.class));
}
});
}
});
}
}).continueWith(new Continuation<Route, Object>() {
@Override
public Object then(Task<Route> task) throws Exception {
// before reading analog voltage from pin 1,
// pull up pin 1
// pull down pin 2
// wait 10 microseconds then read the voltage
// present the data as coming from pin 0x15
analogVoltage.read((byte) 0, (byte) 2, (short) 10, (byte) 0x15);
return null;
}
});
Digital Data¶
The GPIO pins can interpret the input data 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. Don’t forget to set the pull mode before reading the digial state.
final ForcedDataProducer digital = gpio.pin((byte) 0).digital();
digital.addRouteAsync(new RouteBuilder() {
@Override
public void configure(RouteComponent source) {
source.stream(new Subscriber() {
@Override
public void apply(Data data, Object ... env) {
Log.i("MainActivity", "digital state = " + data.value(Byte.class));
}
});
}
}).continueWith(new Continuation<Route, Void>() {
@Override
public Void then(Task<Route> task) throws Exception {
digital.read();
return null;
}
});
Pin Monitoring¶
The pin’s digital state can be monitored by the firmware, sending the new state when it changes. There are 3 state transitions that the firmware can look for:
Change |
Description |
---|---|
Any |
Either falling or rising |
Falling |
Transitions from 1 -> 0 |
Rising |
Transitions from 0 -> 1 |
After setting the pin change state (setChangeType), start the async data producer returned from the monitor method.
The data reported is the new digital input state.
import com.mbientlab.metawear.module.Gpio.PinChangeType;
Gpio.Pin pin = gpio.pin((byte) 1);
// monitor transition from 1 -> 0
pin.setChangeType(PinChangeType.FALLING);
pin.monitor().addRouteAsync(new RouteBuilder() {
@Override
public void configure(RouteComponent source) {
source.stream(new Subscriber() {
@Override
public void apply(Data data, Object ... env) {
Log.i("MainActivity", "state = " + data.value(Byte.class));
}
});
}
}).continueWith(new Continuation<Route, Void>() {
@Override
public Void then(Task<Route> task) throws Exception {
pin.monitor().start();
return null;
}
});