Detecting button presses

My post introducing the .NET Micro Framework covered how to use the OutputPort class to interface to a single GPIO output pin as part of an example to blink a LED.

The matching class to interface to a GPIO input pin, is not too surprisingly called the InputPort class. The InputPort class functions very similar to the OutputPort class discussed last time, in fact they share a common base class.

The constructor for the InputPort class has a couple of additional parameters, in addition to the one which specifies which GPIO pin it should be connected to.

The first is a boolean parameter which enables a glitch filter. Mechanical switches can be “noisy”, meaning that a single press by the user could translate into multiple open and close events, which digitial hardware can potentially detect. This problem is commonly refered to as Contact Bounce or Switch Debouncing. At this stage I have not current managed to find out what technique the .NET Micro Framework utilises for glitch filtering, or even if this is device specific (I suspect it is).

The second parameter is of much more interest, since it deals with setting the type of internal pull up resistor present on the GPIO pin. It can have one of following values from the ResistorMode enumeration:

  • ResistorMode.PullUp – A resistor internal to the CPU is connected between the GPIO pin and VCC, i.e. the pin is pulled up to the positive supply rail.
  • ResistorMode.PullDown – A resistor internal to the CPU is connected between the GPIO pin and GND, i.e. the pin is pulled down to ground.
  • ResistorMode.None – no internal resistor is enabled. In this mode if a pin is left unconnected, it could produce spurious readings due to noise induced into the pin.

The pull up and pull down resistor modes can be handy when interfacing to external hardware, in particular push buttons. By relying upon the internal pull up or pull down resistors, you can get by without requiring additional components, as shown in the following schematics.

Schematic showing pull up and pull down resistor configurations for push button interfacing

It is important to note that if a push button is connected with a pull up resistor, it’s logic levels will be inverted. I.e. the GPIO pin will read a logic high (true) logic level when the push button is not pressed, and will read a logic low (false) logic level when the push button is pressed.

Code Sample
Here is a sample program which will write a message to the debug window each time a push button connected to the GPIO_Pin3 pin is pressed.

To reduce the amount of log messages written to the Visual Studio output window, we only sample the push button once every second. This means we do not need to enable the glitch filter because we are sampling it at a slow enough rate that it should not be a significant issue.

using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using System.Threading;
 
namespace InputTestApplication
{
  public class Program
  {
    public static void Main()
    {
      // Monitor the "select" push button
      InputPort button = new InputPort(Cpu.Pin.GPIO_Pin3,
         false, Port.ResistorMode.PullDown);
 
      while (true)
      {
        // Test the state of the button
        if (button.Read())
             Debug.Print("The button is pressed");
 
        // Wait 1 second before sampling the button again
        Thread.Sleep(1000);
      }
    }
  }
}

NOTE: The GPIO pin used for this sample program has been selected for use with the .NET Micro Framework Sample Emulator. If you attempt to run this application on your own .NET Micro Framework module, you may need to adjust the GPIO signal utilised to suit your hardware.

Push Buttons within the Emulator
The “Sample Emulator” released with the .NET Micro Framework SDK has 5 push buttons “wired up” into a D-PAD configuration.

An interesting aspect to the emulated hardware is that the push buttons can be made to act as if there were wired up with pull up or pull down resistors (as outlined above) depending upon the state of the ResistorMode parameter passed into the constructor of the InputPort instance which accesses them. Typical hardware wouldn’t have this flexibility, with the incorrect ResistorMode choice potentially rendering a push button unreadable.

The mapping of emulator buttons to GPIO pins for the Sample Emulator is as follows:

  • Select – GPIO_Pin3
  • Up – GPIO_Pin2
  • Down – GPIO_Pin4
  • Left – GPIO_Pin0
  • Right – GPIO_Pin1

The code sample provided in this blog posting constantly polls the state of the push button. This is not power efficient. It is better to request that the hardware notifies you whenever the GPIO pin changes state. Next time I will discuss how you can use the InterruptPort class to achieve this.

One Response to “Detecting button presses”

  1. Saadia says:

    Hi,
    I like your article. I am working on something similar to what you have mentioned above in your article.
    I am basically using TMS320DM355 TI chip and connected it to a display. Now I want a GPIO button press, to do brigtness changes in the display.Can you outline me on how to go about this?

    Thanks, any help will be appreciated.

Leave a Reply