.. highlight:: csharp 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 `IPin `_ interface and accessed through the `IGpio `_ interface. :: using MbientLab.MetaWear.Peripheral; IGpio gpio = metawear.GetModule(); 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. :: // output 0V on pin 1 gpio.Pins[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. :: using MbientLab.MetaWear.Peripheral.Gpio; gpio.Pins[2].SetPullMode(PullMode.Up); Analog Data ----------- Analog data comes as either an ADC ratio (`Adc `_) or absolute reference voltage (`AbsoluteReference `_). ADC values are unitless and are interpreted as an unsigned short whereas the reference voltage is a float value in volts (V). :: // Get producer for analog adc data on pin 0 IAnalogDataProducer adc = gpio.Pins[0].Adc; await adc.AddRouteAsync(source => source.Stream(data => Console.WriteLine("adc = " + data.Value())) ); 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. To use these features, set the desired parameters when calling the ``Read`` method. :: IAnalogDataProducer analogVoltage = gpio.Pins[1].AbsoluteReference; await analogVoltage.AddRouteAsync(source => source.Stream()); await gpio.CreateVirtualPin(0x15).AbsoluteReference.AddRouteAsync(source => source.Stream(data => Console.WriteLine("virtual pin voltage = " + data.Value())) ); // before reading analog voltage from pin 1, // pull up pin 1 // pull down pin 2 // wait 10 microseconds then read the voltage analogVoltage.Read(pullup: 0, pulldown: 2, delay: 10); Another useful feature added in the aforementioned firmware release is virtual pins, which are used to distinguish the results of analog reads with different parameters. For example, you can perform analog reads on pin #1 with different pull and delay parameters and have each unique parameter combination be treated as a different pin. Virtual pins are created with the `CreateVirtualPin `_ function. :: // create a virtual pin whose source pin is GPIO pin 1 var vPin = gpio.Pins[1].CreateVirtualPin(0x15); await vPin.AbsoluteReference.AddRouteAsync(source => source.Stream(data => Console.WriteLine("virtual pin 0x15 voltage = " + data.Value())) ); // 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 vPin.AbsoluteReference.Read(pullup: 0, pulldown: 2, delay: 10); // create a second virtual pin with GPIO pin 1 as its source // will feed data do this pin with a different set of read parameters var vPin2 = gpio.Pins[1].CreateVirtualPin(0x24); await vPin2.AbsoluteReference.AddRouteAsync(source => source.Stream(data => Console.WriteLine("virtual pin 0x24 voltage = " + data.Value())) ); // before reading analog voltage from pin 1, // pull up pin 2 // pull down pin 1 // wait 15 microseconds then read the voltage // present the data as coming from pin 0x15 vPin2.AbsoluteReference.Read(pullup: 2, pulldown: 1, delay: 15); 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. :: IForcedDataProducer digital = gpio.Pins[0].Digital; await digital.AddRouteAsync(source => source.Stream(data => Console.WriteLine("digital state = " + data.Value())) ); digital.Read(); 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 `_ property. The data reported is the new digital input state. :: using MbientLab.MetaWear.Peripheral.Gpio; IPin pin = gpio.Pins[1]; // monitor transition from 1 -> 0 pin.SetChangeType(PinChangeType.Falling); await pin.Monitor.AddRouteAsync(source => source.Stream(data => Console.WriteLine("state = " + data.Value())) ); pin.Monitor.Start();