Digital ports are useful for binary communication in which the port is either high/on (powered at 3.3v) or low/off (grounded at 0v). High represents a digital 1, and low represents 0.

Additionally, Netduino provides built-in support for a host of different types of common digital communication protocols via the digital ports.

The above protocols are sometimes called peripherals. The location of the peripherals is shown on the pin out diagram for the boards. The Netduino 3 and Netduino 3 WiFi pin out is as follows:

Pulling High or Low

Digital ports can be set to stand at a high or low voltage, in what’s knows as pulling them high, or pulling them low. So for instance, a digital port that is pulled high will be powered at 3.3v, until it is modified, whereas a port pulled low will be at 0v.

The following is the signature for one of the InputPort constructors:

public InputPort(Cpu.Pin portId, bool glitchFilter, Port.ResistorMode resistor);

Input Ports

For example, the following code initializes an InputPort (used for reading the port’s value) on GPIO Digital Pin #2 that’s pulled down to 0v, so that by default, it doesn’t have a current running through it:

var inputPort = new InputPort(Cpu.Pin.GPIO_Pin2, false,
Port.ResistorMode.PullDown);

The port’s value can then be accessed via the Read method:

bool state = inputPort.Read();

Events via InterruptPorts

In addition to polling/requesting a port for its value, the .NET MicroFramework can be set to raise an event when a port’s value changes by using an InterruptPort. For example, in response to a button being pressed that connects a circuit and raises the input port’s voltage from low (0v) to high (3.3v).

For example, the Button Interrupt Events Sample illustrates listening for the event raised when the onboard button is pressed, and then lights up the onboard LED:

using System;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware.Netduino;

namespace ButtonInterruptEvents
{
	public class Program
	{
		// An output port allows you to write (send a signal) to a pin
		static OutputPort _led = new OutputPort(Pins.ONBOARD_LED, false);

		// An interrupt port raises events when its value changes. in this case, 
		// we use it to create an event when the button is clicked.
		// We set the Interrupt mode to raise an event on both edges of the signal;
		// both down, and up.
		static InterruptPort _button = new InterruptPort((Cpu.Pin)0x15, false, 
			Port.ResistorMode.Disabled, Port.InterruptMode.InterruptEdgeBoth );
		
		public static void Main()
		{
			// turn the LED off initially
			_led.Write(false);

			// wire up the interrupt to our event handler
			_button.OnInterrupt += handleButtonClick;

			// run forever
			while (true)
			{
				
			}

		}

		static void handleButtonClick (uint port, uint data, DateTime time)
		{
			// will be 1 when pressed (raised high), and 0, when unpressed
			Debug.Print ("Data: " + data.ToString ());
			_led.Write (data == 1);
		}
	}
}

Glitch Filtering

Sometimes, switches and other circuits don’t produce a perfectly clean signal, especially during activation. In this case, multiple events can be raised in quick succession when a single event was expected.

In order to counteract this noise, a technique called Glitch Filtering can be used to only raise one event during any given time span.

To enable glitch filtering, pass true for the glitchFilter parameter when instantiating an InputPort:

static InputPort _button = new InputPort((Cpu.Pin)0x15, true, Port.ResistorMode.Disabled);

And then, set the time span to filter events to, usually 5 milliseconds will do the trick, but depending on the hardware more may be needed:

Cpu.GlitchFilterTime = new TimeSpan(0,0,0,0,5);

The following program comes from the Glitch Filtering Sample and illustrates configuring the glitch filter to 5 milliseconds:

using System;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware.Netduino;

namespace GlitchFilter
{
	public class Program
	{
		// An output port allows you to write (send a signal) to a pin
		static OutputPort _led = new OutputPort(Pins.ONBOARD_LED, false);
		// An input port reads the signal from a pin (Should be Pins.ONBOARD_BTN, but there is a bug)
		static InputPort _button = new InputPort((Cpu.Pin)0x15, true, Port.ResistorMode.Disabled);

		public static void Main()
		{
			// turn the LED off initially
			_led.Write(false);

			// smooth noise out over 5 milliseconds
			Cpu.GlitchFilterTime = new TimeSpan(0,0,0,0,5);


			// run forever
			while (true)
			{
				// set the onboard LED output to be the input of the button
				_led.Write(_button.Read());
			}

		}
	}
}

Output

To write to a port, an OutputPort is instantiated. The code below is from the same Button Interrupt Events Sample:

static OutputPort _led = new OutputPort(Pins.ONBOARD_LED, false);

To send a signal to the port, the Write method is called, passing in false for a low signal (0v), or true for a high (3.3v) signal:

_led.Write(true); 

See Also